글실험 기록

VMAF 95점인데 별이 사라졌다: 소개 영상을 AV1 대신 H.264로 압축한 이유

PromptFilm 소개 페이지의 36.9MB 영상을 줄이면서 AV1과 H.264를 비교했습니다. 화질 점수는 AV1이 더 높았지만, 희미한 별 439개 중 284개가 사라졌습니다.

검은 우주 배경에 흩어진 희미한 은하들

PromptFilm 소개 페이지 맨 위에는 35초짜리 우주 영상이 자동으로 재생됩니다. 1080×1080, 60fps에 소리는 없고, 지구에서 출발해 관측 가능한 우주까지 멀어지는 장면입니다. 이 파일 하나가 36.9MB였습니다. 처음 올릴 때 화질을 최대한 지키려고 H.264 CRF 16이라는 아주 높은 설정으로 인코딩해 두었기 때문입니다.

페이지를 한 번 열 때마다 36.9MB가 나간다는 건 방문자에게도, 호스팅 전송량에도 부담입니다. 그래서 10월 16일에 영상을 다시 압축하기로 했습니다. 목표는 단순했습니다. 눈으로 보기에 원본과 차이가 없으면서 최대한 작게.

비교 방법

35초 전체로 매번 실험하면 시간이 오래 걸려서, 영상 앞 10초를 잘라 기준으로 삼았습니다. 이 10초 원본이 10.5MB입니다. 여기에 두 코덱을 여러 설정으로 적용했습니다.

  • H.264: 지금 거의 모든 기기와 브라우저에서 재생되는 코덱입니다. x264 인코더, preset slow.
  • AV1: 같은 화질이면 파일이 훨씬 작다고 알려진 최신 코덱입니다. SVT-AV1 인코더, preset 5.

두 코덱 모두 CRF(숫자가 클수록 더 많이 압축)를 바꿔 가며 만들고, 원본과 얼마나 비슷한지 VMAF로 쟀습니다. VMAF는 넷플릭스가 만든 화질 지표로, 100에 가까울수록 원본과 비슷하게 보인다는 뜻입니다. 보통 93~95점이면 사람 눈으로 차이를 느끼기 어렵다고 봅니다.

실험에 쓴 명령(요약)
# H.264
ffmpeg -i ref10.mp4 -c:v libx264 -preset slow -crf 22 -pix_fmt yuv420p -movflags +faststart -an h264_crf22.mp4
# AV1
ffmpeg -i ref10.mp4 -c:v libsvtav1 -preset 5 -crf 36 -an av1_crf36.mp4
# VMAF (2프레임마다 측정)
ffmpeg -i av1_crf36.mp4 -i ref10.mp4 -lavfi libvmaf=n_subsample=2 -f null -

점수만 보면 AV1이 이겼다

설정10초 크기VMAF
원본 (H.264 CRF 16)10.5MB기준
H.264 CRF 223.6MB94.6
H.264 CRF 242.8MB93.3
H.264 CRF 271.9MB90.5
AV1 CRF 362.1MB95.3
AV1 CRF 322.9MB96.1
AV1 CRF 284.1MB96.8
AV1 CRF 245.6MB97.2

AV1 CRF 36은 H.264 CRF 22보다 파일이 40% 작은데 점수는 오히려 높았습니다. 35초 전체로 다시 만들어 봐도 AV1 CRF 36은 7.8MB에 VMAF 95.0, H.264 CRF 22는 16.1MB에 94.7이었습니다. 숫자만 보면 고민할 이유가 없었습니다.

그런데 화면을 보니

결과 파일을 하나씩 열어 보다가 7초쯤에서 멈췄습니다. 우리은하 주변의 이웃 은하군이 나오는 장면입니다. 원본에는 검은 화면 위에 작은 점 수백 개가 흩어져 있는데, AV1 버전에서는 그 점들이 눈에 띄게 줄어 있었습니다.

같은 장면을 네 가지 설정으로 확대한 비교. AV1 CRF 36에서 희미한 점이 크게 줄었다
7초 지점의 같은 영역을 2배로 확대하고, 네 장 모두 같은 비율로 밝게 보정했습니다. 왼쪽 아래 AV1 CRF 36에서 희미한 점이 많이 사라졌습니다.

느낌으로 끝내지 않으려고 직접 셌습니다. 원본 프레임에서 주변보다 확실히 밝은 점(주변 밝기의 두 배 이상인 한두 픽셀짜리 점)을 모두 찾으니 439개였습니다. 그다음 각 인코딩 결과에서 같은 위치의 밝기를 읽어, 원본 밝기의 절반 아래로 떨어진 점이 몇 개인지 셌습니다.

설정10초 크기VMAF절반 이하로 흐려진 점 (439개 중)
H.264 CRF 223.6MB94.610
H.264 CRF 242.8MB93.327
H.264 CRF 271.9MB90.5156
AV1 CRF 362.1MB95.3284
AV1 CRF 322.9MB96.1255
AV1 CRF 284.1MB96.8194
AV1 CRF 245.6MB97.2126

점수는 왜 이걸 못 잡았나

VMAF는 화면 전체를 보고 사람이 느낄 화질을 추정하는 지표입니다. 한두 픽셀짜리 점 수백 개는 1080×1080 화면에서 차지하는 면적이 아주 작습니다. 은하의 밝은 중심, 글자, 큰 천체가 그대로라면 점수는 높게 나옵니다.

인코더 입장에서 이런 점은 잡음과 구분하기 어렵습니다. 어두운 배경에 고르게 흩어진 작은 점은 지워도 수치상 손해가 적으니, 압축률을 높이는 쪽으로 판단한 것으로 보입니다. 그런데 이 영상에서는 그 점들이 바로 보여주려는 내용입니다. “이웃 은하군” 장면에서 은하가 사라지면 장면의 의미가 없어집니다.

AV1을 살리는 방법도 있었다

SVT-AV1에는 variance boost라는 옵션이 있습니다. 밝기 변화가 적은 평평한 영역에 비트를 더 배정해, 어두운 배경의 미세한 디테일을 덜 지우게 하는 기능입니다. CRF 30에 이 옵션을 강도 3으로 켜고 다시 만들어 봤습니다.

설정10초 크기VMAF흐려진 점
H.264 CRF 223.6MB94.610
AV1 CRF 30 + variance boost6.2MB97.211

별은 돌아왔습니다. 대신 파일이 6.2MB로, H.264 CRF 22보다 1.7배 컸습니다. 이 영상에서는 별을 지키는 순간 AV1의 크기 이점이 사라진 셈입니다. 게다가 AV1을 쓰려면 AV1을 재생하지 못하는 브라우저와 기기를 위해 H.264 파일을 하나 더 만들어 두어야 합니다. 관리할 파일만 늘어납니다.

결정: H.264 CRF 22

최종으로 H.264 CRF 22, preset slow, faststart를 골랐습니다.

  • 35초 전체가 36.9MB에서 16.1MB로, 56% 줄었습니다. 전체 길이 기준 VMAF는 94.7입니다.
  • 희미한 점은 439개 중 10개만 흐려졌습니다. 확대하지 않으면 원본과 구분하기 어렵습니다.
  • faststart로 파일 정보를 앞에 두어, 다 받기 전에 재생을 시작합니다.

CRF 24도 후보였습니다. 35초 전체가 12.2MB로 더 작고, 흐려진 점도 27개로 나쁘지 않았습니다. 다만 VMAF가 93.0으로 내려가고 점 손실이 세 배 가까이 늘어서, 처음 보이는 영상인 만큼 여유를 두고 CRF 22를 택했습니다.

남겨 두고 싶은 것

이번 실험에서 배운 건 하나입니다. 화질 점수는 평균이다. 평균은 영상에서 정말 중요한 부분이 무엇인지 모릅니다. 별이 핵심인 우주 영상이라면 별을, 글자가 핵심인 화면 녹화라면 글자를 직접 재야 합니다.

방법이 거창할 필요는 없었습니다. 원본에서 지켜야 할 대상을 찾고, 압축한 결과에서 같은 위치를 읽어 비교하는 수십 줄짜리 스크립트로 충분했습니다. 점수가 좋은데도 뭔가 이상하다는 느낌이 들면, 그 느낌을 숫자로 바꿔 보는 데 30분이면 됩니다.

실험에 쓴 영상은 PromptFilm으로 만든 Cosmic Size Ladder입니다. 영상이 무엇을 보여주는지는 영상 해설 페이지에 정리해 두었습니다.

이 글에서 다룬 도구

PromptFilm

말로 설명하면 3D 영상으로

자세히 보기

루샨 · lucianLabs 운영자

AI 에이전트와 일하며 필요한 도구를 직접 만들고, 그 과정에서 얻은 숫자와 시행착오를 기록합니다. 글에 틀린 내용이 있으면 알려주세요.