블로그 목록
Media15분 읽기

x264 실전 옵션 — ref, tune, keyint 완전 가이드

OBS/FFmpeg 설정 화면에서 만나는 x264 옵션을 하나씩 해부. ref=1 vs ref=4, tune=zerolatency가 내부에서 끄는 6가지 옵션, profile=main+bframes=0 조합의 이유, '키프레임 2초'가 업계 표준인 5가지 근거(HLS 세그먼트·채널 조인 대기·PLI 복구·대역폭·업계 관행), 30fps→keyint=60 / 60fps→120 환산까지.

x264H.264reftunezerolatencykeyintGOPOBSFFmpegWebRTC

28편에서는 Profile과 비트레이트, 29편에서는 B-frame 자체를 다뤘습니다. 이 글은 실제 OBS/FFmpeg 설정 화면에서 만나게 되는 x264 옵션들을 하나씩 해부합니다: ref, tune, profile, keyint. 실시간 송출과 VOD가 왜 다른 값을 쓰는지, 그리고 '키프레임 2초'가 왜 업계 표준인지의 근거.


1. ref — reference frames (참조 프레임 수)

개념

P-frame이 "이전 프레임을 참조한다"고 했죠? 이때 몇 개까지 과거 프레임을 참조할지 정하는 옵션입니다. ref=1이면 직전 프레임 하나만, ref=4면 최대 4개까지 후보로 두고 인코더가 가장 압축 효율이 좋은 참조 조합을 골라 씁니다.

ref=1 (실시간용 권장) I P1 P2 P3 각 P는 직전 프레임 1개만 참조 (체인처럼) ref=4 (VOD용 고화질) I P1 P2 P3 P4 P4가 과거 4개(I, P1, P2, P3) 모두 참조 가능 — 압축률 ↑ (최적 참조 선택), 연산량 ↑, 메모리 ↑ 실시간 통신: ref=1 — 디코더 부담 최소, 손실 복구 단순 • 디코더 메모리 사용량 ↓ — 과거 프레임 1개만 보관 • 손실 복구 체인 단순화 — 한 프레임만 복구하면 체인 재개 • 인코더 연산 ↓ — 후보 프레임 하나만 비교 • 압축률은 약간 손해지만 실시간에서는 지연/안정성이 우선

왜 실시간에서 ref=1?

  • 디코더 메모리 사용량 ↓ — 과거 프레임 1개만 보관하면 되므로 저사양 기기에서도 안정적으로 동작합니다.
  • 손실 복구 체인 단순화 — 패킷 하나가 유실됐을 때, ref=1이면 그 프레임 하나만 재요청(PLI)하면 이후 체인이 복구됩니다. ref=4면 4개의 참조가 얽혀 있어 하나 손실이 연쇄 손상으로 번질 가능성이 큽니다.
  • 인코더 연산 ↓ — 후보 참조 프레임이 하나이므로 탐색 연산이 최소입니다.
  • 압축률은 약간 손해지만 실시간에서는 지연/안정성이 우선입니다.

ref 값 선택 가이드

ref 값용도이유
1WebRTC, 실시간 화상회의, 게임 스트리밍디코더 부담 최소, 손실 복구 단순
2~3RTMP 라이브 방송, OBS 스트리밍압축 효율과 지연의 균형점
4~6VOD 인코딩, Blu-ray, 녹화 배포최대 압축 효율 (지연 제약 없음)

2. tune — 용도별 프리셋

튠(tune)은 특정 용도에 맞춰 x264 내부 파라미터 세트를 한 번에 조정하는 프리셋입니다. x264엔 수십 개의 세부 옵션이 있어 수동으로 모두 맞추기가 복잡합니다. tune 하나로 주요 파라미터 묶음을 한 번에 최적화합니다.

용도
film영화용, 고화질 VOD
animation애니메이션 (단색 영역 많음)
grain노이즈 보존 (필름 질감)
stillimage정지 이미지에 가까운 영상
fastdecode디코딩 부담 최소화 (저사양 기기)
zerolatency지연 최소화 (실시간 스트리밍/화상회의)

zerolatency가 내부적으로 하는 일

--bframes 0           (B-frame 비활성)
--force-cfr           (고정 프레임레이트)
--no-mbtree           (매크로블록 트리 비활성 — 미리보기 분석 끔)
--sync-lookahead 0    (look-ahead 비활성)
--sliced-threads      (슬라이스 병렬처리, 프레임 대기 없음)
--rc-lookahead 0      (레이트 컨트롤 look-ahead 제거)

핵심은 **"미래 프레임 미리 보지 말고 현재 프레임만 즉시 처리"**입니다. B-frame도 자동으로 꺼집니다. → 왜 B-frame이 지연의 원인인지는 B-frame 완전정복 참조.

실무 팁: tune=zerolatency 하나만 줘도 bframes=0 효과가 이미 포함됩니다. 명시적으로 둘 다 쓰면 더 확실할 뿐입니다.

tune 적용 FFmpeg 예시

# 실시간 스트리밍 (OBS Custom FFmpeg 설정 참고)
ffmpeg -i input \
  -c:v libx264 \
  -preset veryfast \
  -tune zerolatency \
  -x264-params "ref=1:bframes=0:keyint=60" \
  -b:v 2500k \
  -f flv rtmp://live.example.com/stream

# VOD 고화질 인코딩
ffmpeg -i input \
  -c:v libx264 \
  -preset slow \
  -tune film \
  -x264-params "ref=4:bframes=3:keyint=240" \
  -crf 18 \
  output.mp4

3. profile — 호환성 vs 기능

이전 글에서 다뤘듯이 H.264 프로파일 선택입니다. 자세한 분석은 H.264 Profile·인코더 옵션 참조. 이 글에서는 x264 옵션 맥락에서의 실무 정리만 다룹니다.

프로파일특징Agora/WebRTC
baseline가장 호환성 높음, 기능 제한✅ 안전
mainB-frame, CABAC 허용bframes=0이면 안전
high모든 기능 (4K/Blu-ray용)✅ Agora 수용 (bframes=0 전제 권장)

profile=main + bframes=0 조합은 Main Profile의 CABAC 효율은 쓰되 B-frame만 끄는 구조입니다. WebRTC 호환성과 압축률의 균형점이 여기에 있습니다.

profile 선택 매트릭스

환경별 권장:

브라우저 WebRTC (Chrome ↔ Safari ↔ Firefox):
  → Constrained Baseline 또는 Baseline
  → MTI 표준, 가장 안전

SDK 기반 (Agora, Zoom, 서버-클라이언트 양쪽 통제):
  → Main + bframes=0  (CABAC 이득, B-frame 지연 없음)
  → High + bframes=0  (추가 압축, 8x8 변환)

VOD 녹화·배포:
  → High + bframes=2~3  (최대 압축 효율)

4. 키프레임 간격 — "왜 진짜 2초"인지

가장 자주 질문받는 값입니다. "2초"가 어디서 온 숫자인지 근거를 짚습니다.

개념

키프레임 간격 = GOP 길이 = I-frame 사이 시간. GOP 개념 자체는 프레임의 모든 것 §GOP 참조.

x264 파라미터 이름: keyint (또는 --keyint). 단위는 프레임 수. 60fps에서 keyint=120이면 2초 간격.

1초 간격 (매우 짧음) I 0초 I 1초 I 2초 I 3초 I 4초 5장의 무거운 I-frame → 대역폭 30% 가량 더 소모, 손실 복구는 빠름 2초 간격 (실시간 표준) I 0초 I 2초 I 4초 P P P ... P P P P ... P 3장의 I-frame → HLS/DASH 세그먼트 단위, 채널 조인 대기, 손실 복구의 균형점 10초 간격 (VOD용) I 0초 P P P P P P P P P P P P P P P P P P ... I 10초 I-frame 거의 없음 → 대역폭 최적, 그러나 손실 시 최대 10초 대기 2초가 표준인 이유 — HLS/DASH 청크 단위, 채널 조인 대기 인내선, 손실 복구 속도의 공통 교집합 • HLS 2~6초 세그먼트 모두 호환 (각 세그먼트가 I-frame으로 시작해야 독립 재생 가능) • 새 시청자가 합류할 때 다음 I-frame까지 대기 — 사용자 인내선 ≈ 2초 • 패킷 손실 최악 복구 시나리오: 키프레임 간격이 상한선 → 2초이면 2초 안에 무조건 복구 • YouTube Live / Twitch / Facebook Live / Agora 모두 2초 권장 — 사실상 업계 공통 기준 • 대역폭 오버헤드 적정 — 1초→2초로 늘리면 15~20% 절감, 그 이상은 절감 효과 급감

2초가 표준인 5가지 이유

1. HLS/DASH 세그먼트 단위와 일치

HLS는 보통 2~6초 세그먼트로 영상을 쪼갭니다. 각 세그먼트는 I-frame으로 시작해야 합니다 (독립 재생 가능해야 하니까). 2초 키프레임 간격이면 2/4/6초 세그먼트 모두 호환됩니다.

2. 채널 조인 대기 시간

새 시청자가 합류하면 다음 I-frame까지 대기해야 합니다 — 그 전에는 화면을 그릴 수 없습니다. 사용자가 참을 수 있는 대기 시간이 ~2초입니다. 10초면 "왜 안 뜨지?" 느낌이 강해집니다.

3. 패킷 손실 복구 최악 시나리오

PLI 요청 없이 자연 복구를 기다릴 때 최대 대기 = 키프레임 간격. 2초면 최악에도 2초 안에 복구됩니다.

4. 대역폭 오버헤드 적정

I-frame이 P-frame의 510배. 1초 간격 vs 2초 간격 → 전체 대역폭 1520% 차이. 2초 이상 늘려도 절감 효과가 급격히 감소합니다.

5. 업계 관행

YouTube Live, Twitch, Facebook Live 모두 2초 권장. WebRTC 구현체 기본값. Agora도 이 근처 권장.

프레임 수로 환산

fpskeyint (2초 기준)
3060
60120

OBS에서 "키프레임 간격 2"라고 입력하면 OBS가 현재 fps를 보고 자동 계산합니다. FFmpeg 직접 설정 시엔 -x264-params keyint=60 식으로 프레임 수를 씁니다.

keyint vs min-keyint

x264엔 두 가지 keyint 옵션이 있습니다.

keyint     (또는 --keyint):     최대 키프레임 간격
min-keyint (또는 --min-keyint): 최소 키프레임 간격

기본값:
  keyint=250     (약 8초 @ 30fps)
  min-keyint=25  (scenecut 발동 시 최솟값)

실시간 스트리밍 권장:
  keyint=60      (2초 @ 30fps)
  min-keyint=60  (scenecut 비활성 — 정확히 2초마다 강제 키프레임)

scenecut이 살아있으면 장면 전환 시 추가 I-frame이 삽입됩니다. 라이브에선 이게 예측 불가 오버헤드가 될 수 있어, scenecut=0으로 꺼두는 설정도 자주 씁니다.


5. 한 줄 정리

옵션실시간 값VOD 값이유
ref13~4디코더 메모리, 손실 복구 단순성
tunezerolatencyfilm미래 프레임 look-ahead 제거 vs 최대 압축
profilemain + bframes=0highWebRTC 호환 + 압축 균형 vs 최대 효율
keyint60 (30fps) / 120 (60fps)240+HLS 세그먼트, 채널 조인 대기, 손실 복구 상한

조합 예시 — 실전 설정

# OBS FFmpeg 커스텀 출력 (실시간 스트리밍)
x264opts=ref=1:bframes=0:keyint=60:min-keyint=60:scenecut=0:tune=zerolatency

# FFmpeg CLI (실시간 스트리밍)
ffmpeg -i input \
  -c:v libx264 \
  -profile:v main \
  -preset veryfast \
  -tune zerolatency \
  -x264-params "ref=1:bframes=0:keyint=60:min-keyint=60:scenecut=0" \
  -b:v 2500k \
  -maxrate 2500k \
  -bufsize 5000k \
  -f flv rtmp://live.example.com/stream

# FFmpeg CLI (VOD 고화질)
ffmpeg -i input \
  -c:v libx264 \
  -profile:v high \
  -preset slow \
  -tune film \
  -x264-params "ref=4:bframes=3:keyint=240:b-pyramid=normal" \
  -crf 18 \
  output.mp4

6. 트레이드오프 시각화 — 실시간 vs VOD

실시간과 VOD 설정의 차이를 한 번에 보면 이렇습니다.

실시간 스트리밍 / WebRTC VOD 인코딩 / 녹화 배포 ref ref=1 디코더 메모리 ↓, 복구 단순 ref ref=3~4 압축률 최대화 tune zerolatency look-ahead 제거, bframes=0 tune film / animation 콘텐츠 특성 최적화 profile main + bframes=0 CABAC 유지, B-frame 제거 profile high + bframes=2~3 8x8 변환, B-frame 압축 keyint 60 @ 30fps / 120 @ 60fps 2초 간격, HLS 호환 keyint 240 ~ 300+ I-frame 최소화, 파일 크기 ↓ 우선순위 ① 지연 최소화 ② 패킷 손실 복구 안정성 우선순위 ① 압축률 최대화 ② 같은 화질에 파일/대역폭 최소

관련 글

© 2026 Frank Kim. All rights reserved.