블로그 목록
Fundamentals30분 읽기

B-frame 이해하기 — 참조 구조, 재정렬, 지연

B-frame이 이전·이후 reference picture를 이용하는 방식과 display order·decode order가 달라지는 이유를 설명합니다. 재정렬 buffer와 timestamp, 압축 효율, latency의 tradeoff를 다루고, 실시간 전송에서 B-frame 사용 여부는 codec profile과 encoder·decoder 협상 결과로 확인합니다.

B-frameI-frameP-frameGOP인코더 버퍼DTSPTSH.264VODWebRTCOpus립싱크기초
목차(30개 항목)
  1. 먼저 — 왜 B-frame이 존재하는가? (목적: 압축률)
    1. 세 가지 프레임 타입 — 상대 용량 비교
    2. 기분을 문자로 보내는 비유
  2. STEP 1 — 카메라가 찍어서 버퍼에 쌓는다
  3. STEP 2 — 인코더가 B-frame 만들 때의 사고 과정
  4. STEP 3 — 인코더 처리 순서 (촬영 순서 ≠ 인코딩 순서)
  5. STEP 4 — 인코딩 지연의 정체
  6. STEP 5 — 디코더를 위한 decoding order 재배열
    1. 디코더 입장에서 한 번 더
  7. 쉬운 비유로 다시 정리
  8. 실제 영상에서의 배치 — GOP 구조
  9. 언제 쓰는가 — 상황별 매핑
  10. 오해 풀기 — "재배열하면 디코더는 문제없는 거 아냐?"
    1. 1. 패킷 손실 → B-frame 참조 불가 (연쇄 손상)
    2. 2. 패킷 지연 (Jitter)
    3. 3. WebRTC가 B-frame을 안 쓰는 "진짜" 이유 — 2가지
    4. 4. 그럼 B-frame이 없어도 끊기는 이유는?
  11. 압축 효율 — 얼마나 차이나나
  12. 최종 요약 — 4가지 역할
    1. 한 줄 결론
  13. Bonus — B-frame은 오디오와 관계가 있나?
    1. 결론: 없음
    2. 왜 오디오엔 B-frame이 없나 — 근본적 차이
    3. 오디오의 압축 방식은 따로
    4. 헷갈리는 지점: "오디오 프레임"이라는 말
    5. 오디오도 약간의 "의존성"은 있음
    6. 간접 연결점 — 립싱크(A/V Sync)
    7. 한 줄 요약
  14. 관련 글
  15. 참고 자료

"B-frame이 미래를 어떻게 알지?", "왜 전송 순서가 표시 순서랑 다르지?", "그럼 재배열하면 되니까 WebRTC에서도 써도 되는 거 아냐?". 이 세 질문은 영상 코덱을 처음 깊이 파고드는 사람이 반드시 부딪히는 지점입니다. 이 글은 B-frame을 5 STEP 비유 + 시각화로 끝까지 풀어보는 심화 가이드입니다.

앞선 글 두 편이 개념 기초(프레임의 모든 것)와 실무 코덱 선택(H.264 Profile·비트레이트)을 다뤘다면, 이 글은 B-frame 하나만 파고듭니다. 모든 설명은 비유 → 그림 → 메커니즘 순서입니다.


먼저 — 왜 B-frame이 존재하는가? (목적: 압축률)

같은 화질로 파일 크기를 줄이는 것이 목표입니다.

I-picture: 외부 reference 없이 intra prediction           → 큰 경우가 많음
P-picture: list 0 reference 기반 prediction + residual     → content에 따라 다름
B-picture: list 0/list 1 prediction + residual             → 작은 경우가 많음

B-slice는 list 0, list 1 또는 양쪽 reference list에서 block prediction을 만들 수 있어 선택지가 늘어납니다. 단순한 시간 중간값을 저장하는 구조는 아닙니다.

세 가지 프레임 타입 — 상대 용량 비교

I Intra-coded 독립 프레임 picture 내부 예측과 residual. 다른 프레임 참조 없음. JPEG와 동일한 bitstream은 아님. 💾 상대 용량 content·QP에 따라 달라짐 키프레임 / 기준점 P Predictive 단방향 참조 이전 I 또는 P와 비교해 prediction + motion + residual. "앞을 보고 예측" 💾 상대 용량 고정 비율 없음 단방향 예측 B Bi-directional 두 reference list 사용 가능 list 0/list 1 prediction 한쪽 또는 양쪽 reference 선택. 효율은 장면과 설정에 따름. 💾 상대 용량 작은 경우가 많음 양방향 예측

기분을 문자로 보내는 비유

친구한테 매일 기분을 숫자로 문자 보낸다고 생각해봅시다. 글자 수가 요금이라 최대한 짧게 보내고 싶습니다.

월요일 기분: 😊 100점
화요일 기분: 😐 150점
수요일 기분: 😄 200점

I-frame 방식 (매번 다 보냄):

월: "오늘 기분 100점"
화: "오늘 기분 150점"   ← 매번 처음부터 다 설명
수: "오늘 기분 200점"

→ 글자 수 많음.

P-frame 방식 (과거만 참조):

월: "오늘 기분 100점"               ← 기준점
화: "어제보다 50점 올랐어"          ← 어제만 참조
수: "어제보다 50점 올랐어"          ← 어제만 참조

→ 달라진 것만 보내니 짧아짐.

B-frame 방식 (과거+미래 참조):

월: "오늘 기분 100점"               ← 기준점
수: "월요일보다 100점 올랐어"       ← 수요일 먼저!
화: "월·수요일을 참고해 차이를 설명" ← 두 reference를 쓰는 비유

이 비유의 핵심은 표시 순서상 뒤의 reference도 encoder가 사용할 수 있다는 점입니다. 실제 codec은 pixel의 산술 중간값이 아니라 block별 motion compensation과 residual을 부호화합니다.


STEP 1 — 카메라가 찍어서 버퍼에 쌓는다

가장 헷갈리는 질문: B-frame은 "미래"를 어떻게 알지?

답: encoder는 표시 순서상 뒤의 reference picture가 capture될 때까지 입력을 buffer할 수 있습니다.

📷 카메라 🗂 인코더 버퍼 (임시 저장소) — 이미 찍힌 프레임들 🌅 t=0 🌄 t=1 🌃 t=2 🌉 t=3 핵심: 뒤쪽 reference가 들어올 때까지 buffer 30fps면 1초에 30장이 버퍼에 쌓입니다. 인코더가 t=1을 처리할 때 t=3은 이미 버퍼 속 현재 데이터일 뿐입니다. 시간 순서는 사용자 입장이지, 인코더에게는 그냥 "버퍼에 쌓인 데이터"일 뿐.

STEP 2 — 인코더가 B-frame 만들 때의 사고 과정

💭 "지금 t=1을 인코딩해야 하는데, B-frame으로 만들 거야" 💭 "이 예에서는 t=0과 t=3을 reference로 선택" "t=3? 아, 버퍼에 이미 있네. 카메라가 진작 찍었으니까" ← 여기가 핵심! 인코더에게 미래는 그냥 "버퍼 속 데이터" ✅ "motion prediction + residual 부호화 → B-picture 완성"

STEP 3 — 인코더 처리 순서 (촬영 순서 ≠ 인코딩 순서)

카메라는 t=0 → t=1 → t=2 → t=3 순서로 찍지만, 인코더는 다른 순서로 처리합니다.

① t=0 → I-frame 키프레임 아무것도 참조 안 함. 화면 전체를 통째로 저장. 📦 용량 가장 큼 — 하지만 완전히 독립적 ② t=3 → P-frame 단방향 참조 이 예에서는 t=0 reference로 prediction하고 residual 저장. 📦 용량 중간 ③ t=1 → B-frame 양방향 참조 ← 핵심! 이 예에서는 t=0과 t=3 reference로 prediction + residual coding. ⏳ t=3이 버퍼에 쌓일 때까지 기다려야 함 = 인코딩 지연 📦 용량 중간 ④ t=2 → B-frame 양방향 참조 이 예에서는 t=0 + t=3 reference 사용. 📦 실제 크기는 content·QP·reference 선택에 따라 달라짐

STEP 4 — 인코딩 지연의 정체

영상통화는 실시간입니다. 카메라가 t=1을 찍는 순간 바로 보내야 자연스럽습니다. 그런데 B-frame을 쓰면:

시각 t=0 t=1 t=2 t=3 카메라 촬영 📷 촬영 📷 촬영 📷 촬영 📷 촬영 t=1 인코딩 — ⏳ 대기 ⏳ 대기 ✅ 인코딩 t=3이 찍힐 때까지 t=1은 인코딩 못 함 → "기다리는 시간" = 인코딩 지연 이게 바로 WebRTC(영상통화)에서 B-frame을 쓰지 않는 이유입니다.

STEP 5 — 디코더를 위한 decoding order 재배열

encoder는 reference picture가 먼저 decode되도록 bitstream을 decoding order로 출력합니다. RTP packet은 이 순서로 보내지만 network reordering은 별도로 발생할 수 있어 sequence number로 복원합니다.

🖥 화면 표시 순서 (시청자가 보는 순서) 표시 ① I t=0 → 표시 ② B t=1 → 표시 ③ B t=2 → 표시 ④ P t=3 📦 실제 전송 순서 (인코더가 재배열) 전송 ① I t=0 → 전송 ② P t=3 → 전송 ③ B t=1 → 전송 ④ B t=2 왜 P(t=3)을 B(t=1)보다 먼저 보내나? 디코더가 B(t=1)을 복원하려면 t=3이 필요하기 때문. → 디코더가 B(t=1)을 받을 때는 이미 I(t=0)과 P(t=3)을 둘 다 가진 상태 → 복원 가능 ✅

디코더 입장에서 한 번 더

❌ 잘못된 순서로 보내면:
받은 순서: I(0) → B(1) → B(2) → P(3)
디코더:    I(0) 디코딩 OK
           B(1) 디코딩 시도... "t=3이 없는데??" 💥 오류!

✅ 올바른 순서로 보내면:
받은 순서: I(0) → P(3) → B(1) → B(2)
디코더:    I(0) 디코딩 OK
           P(3) 디코딩 OK  ← B(1)보다 먼저 준비 완료
           B(1) 디코딩 OK  ← t=0, t=3 둘 다 있으니 계산 가능!
           B(2) 디코딩 OK

결론: 디코더가 미래를 계산하는 게 아니라, 인코더가 미래를 미리 봐서 계산해놓고 순서를 재배열한 것.

이것이 저장 컨테이너에서 DTS(Decoding Timestamp)와 PTS(Presentation Timestamp)가 다른 이유이기도 합니다.


쉬운 비유로 다시 정리

📸 I-Frame 외부 reference 없이 부호화 "오늘 방 상태 전체 사진 찍어둠" intra-coded picture 📝 P-Frame 어제랑 비교해서 바뀐 것만 메모 "책상 위 컵이 왼쪽으로 이동함" 변화만 기록 🔮 B-Frame 어제 + 내일 둘 다 보고 오늘을 역산 "중간쯤 있었겠지" 앞뒤 보간

실제 영상에서의 배치 — GOP 구조

B-picture를 쓰는 encoder는 GOP 안에 I/P/B picture pattern을 구성할 수 있습니다. pattern은 고정적일 수도 adaptive할 수도 있고, open GOP에서는 reference가 GOP 경계를 넘을 수 있습니다.

▶ 일반적인 GOP 패턴: I B B P B B P B B I ... I #1 B #2 B #3 P #4 B #5 B #6 P #7 B #8 B #9 GOP/keyframe 간격은 encoder·streaming target·복구 정책에 따라 설정.

언제 쓰는가 — 상황별 매핑

상황B-frame 사용?이유
영화·드라마 파일 (VOD)✅ 자주 사용reorder latency보다 압축 효율을 우선할 수 있음
업로드형 VOD✅ encoder 설정에 따라 사용playback target과 압축 효율 고려
Blu-ray·OTT 배포✅ profile·format에 따라 사용배포 규격과 decoder 지원 확인
영상통화 (WebRTC)조건부저지연 encoder는 흔히 끄지만 협상·구현에 따름
게임 스트리밍 (저지연)조건부latency budget과 encoder mode로 결정
RTMP 라이브 방송경로에 따라 선택downstream codec/profile·latency 요구와 호환성 확인

오해 풀기 — "재배열하면 디코더는 문제없는 거 아냐?"

재배열은 "순서 문제"를 해결하는 것이고, 끊김은 "패킷 손실·지연 문제"라서 완전히 별개입니다.

1. 패킷 손실 → B-frame 참조 불가 (연쇄 손상)

전송: I → P → B₁ → B₂

근데 P가 네트워크에서 유실됨 💥

디코더: B₁ 받았는데... P가 없네?
        B₁은 P를 참조해야 복원 가능한데
        → B₁ 복원 불가 → B₂도 복원 불가
        → 화면 멈춤 / 깨짐

P-picture가 손실되면 그 picture를 실제로 reference한 B/P picture가 영향을 받을 수 있습니다. 범위는 reference graph와 concealment·recovery에 달려 있습니다.

2. 패킷 지연 (Jitter)

정상:  I 도착 → P 도착 → B₁ 도착 (순서대로 빠르게)
현실:  I 도착 → P가 늦게 도착 (네트워크 혼잡)

디코더: B₁은 이미 받았는데 P가 아직 안 왔어
        재생 시간은 됐는데 복원 못 함
        → 화면 멈춤

3. WebRTC가 B-frame을 안 쓰는 "진짜" 이유 — 2가지

이유설명
인코딩 지연t=3을 기다려야 t=1 인코딩 가능 → 실시간 불가 (STEP 4)
packet loss recoveryreference graph가 복잡하면 영향 추적과 refresh가 어려워질 수 있음

4. 그럼 B-frame이 없어도 끊기는 이유는?

I ← 이게 손실되면 최악
↓ 참조
P → 손실 시 이후 P들도 연쇄 손상
↓ 참조
P ...

decoder refresh picture의 일부가 손실되면 이를 reference하는 후속 picture까지 영향이 전파될 수 있습니다. PLI는 picture loss를 알리고 sender가 새 refresh picture를 만들 수 있게 하지만 즉시 I-picture 전송을 보장하는 재전송 명령은 아닙니다. (#27에서 자세히)


압축 효율 — 얼마나 차이나나

B-picture의 압축 이득에는 보편적인 고정 비율이 없습니다. source clip, encoder/preset, GOP, reference 구조를 고정하고 같은 objective/subjective quality에서 bframes=0과 B-picture 구성을 비교해야 합니다. VOD에서는 추가 reorder latency를 감수할 수 있어 이 tradeoff를 선택하기 쉽지만, live 서비스는 latency와 downstream compatibility를 함께 평가합니다.


최종 요약 — 4가지 역할

🎥 인코더의 역할 버퍼에서 미래 프레임을 꺼내 B-frame 압축 후 순서 재배열해서 전송 📺 디코더의 역할 재배열된 순서로 받아서 참조 프레임 먼저 복원 → B-frame 복원 📦 B-frame 장점 앞뒤 둘 다 참조 → 차이 최소 → 압축률 최고 (VOD에 최적) ⏳ B-frame 단점 미래 프레임 버퍼링 필요 → 실시간 스트리밍 부적합

한 줄 결론

B-picture는 VOD에서는 압축 효율을 높일 수 있고, 저지연 파이프라인에서는 reorder latency와 상호운용 비용을 늘릴 수 있습니다.

두 세계를 이어붙이는 RTMP → WebRTC 같은 파이프라인을 다루신다면 #26에서 실제 PTS rollback 디버그 기록을 보시면 이 글의 모든 개념이 현장에서 어떻게 드러나는지 확인할 수 있습니다.


Bonus — B-frame은 오디오와 관계가 있나?

결론: 없음

I/P/B slice type은 비디오 codec의 개념이며 AAC·MP3·Opus는 같은 분류를 쓰지 않습니다. 다만 오디오 frame이 항상 독립적이라는 뜻은 아닙니다.

왜 오디오엔 B-frame이 없나 — 근본적 차이

데이터 성격이 완전히 달라서입니다.

비디오의 특성

  • 한 프레임 = 수백만 픽셀의 2D 이미지
  • 연속된 프레임끼리 거의 똑같은 경우 많음 (배경 안 바뀌고 얼굴만 조금 움직임)
  • "이전 프레임 기준으로 변화량만" 표현하면 수백 배 압축 가능 → I/P/B 참조 구조가 효율적

오디오의 특성

  • 1 블록 = 20ms짜리 파형 (수백~수천 개 샘플)
  • 시간·주파수 영역의 중복과 masking을 이용해 압축
  • codec에 따라 prediction, overlap, bit reservoir 등 frame 간 상태를 사용
비디오 (I, P, B 프레임) I B B P B 각 프레임이 다른 종류, 서로 참조 프레임 하나 = 2D 이미지 (수백만 픽셀) 같은 화면의 반복 정보 많음 → 참조 압축 유리 프레임 크기: 수십 KB ~ 수백 KB 오디오 (균일한 샘플 블록) 20ms 20ms 20ms 20ms 20ms 20ms I/P/B 분류는 없지만 codec별 frame 의존성은 존재 블록 하나 = 짧은 시간의 소리 파형 블록 크기: 수백 Byte ~ 수 KB prediction·overlap·bit reservoir는 codec마다 다름 B-frame은 비디오만의 개념 — 오디오는 애초에 그런 구조가 없음

오디오의 압축 방식은 따로

오디오 코덱(AAC, Opus, MP3)은 다른 기법으로 압축합니다:

  • 주파수 분석 (FFT/MDCT): 파형을 주파수별로 분해
  • 심리음향 모델: 사람 귀가 못 듣는 주파수 버림
  • 비트 할당: 중요한 주파수에 더 많은 비트

프레임 간 참조와는 완전히 다른 차원의 기술입니다.

헷갈리는 지점: "오디오 프레임"이라는 말

오디오에서도 "프레임"이라는 단어를 씁니다:

코덱프레임 정의
AAC-LC일반적으로 1024 sample, 규격상 960-sample frame도 가능
Opusframe당 2.5 / 5 / 10 / 20 / 40 / 60ms, packet은 최대 120ms 구성 가능
MP3 Layer IIIMPEG-1은 frame당 1152 sample, MPEG-2/2.5는 576 sample

이건 한 번에 압축/디코딩하는 단위라는 뜻이지, I/P/B 같은 참조 관계 타입이 아닙니다. 단어만 같고 의미가 다릅니다.

오디오도 약간의 "의존성"은 있음

오디오 codec에도 frame 간 상태와 의존성이 존재할 수 있습니다:

  • AAC LTP (Long Term Prediction): 이전 주기성 참조
  • Opus SILK 모드: 제한적 예측 코딩
  • MP3 bit reservoir: 이전 frame이 남긴 main-data 공간을 뒤 frame이 사용할 수 있음

이 구조들은 H.264 B-slice와 같은 picture reference type이 아닙니다. codec latency는 frame duration뿐 아니라 algorithmic lookahead, packetization, resampling과 playout buffer를 함께 봅니다.

간접 연결점 — 립싱크(A/V Sync)

비디오와 오디오는 독립 인코딩되지만, 같이 재생돼야 하므로 연결점이 있습니다.

카메라 + 마이크 (원본 소스) 각자 독립적으로 인코딩 진행 비디오 인코더 (H.264, I/P/B 판단) 오디오 인코더 (Opus, 블록 단위) codec별 RTP packetizer — timestamp 부여 audio/video는 보통 별도 SSRC·RTP stream RTCP sender report로 서로 다른 RTP clock을 공통 시각에 연결 디코더 측: 각자 디코딩 후 타임스탬프로 동기화 비디오 프레임과 오디오 블록을 같은 시각에 재생 B-frame이 오디오에 영향을 주는 간접 경로 비디오가 B-frame 때문에 지연 → 오디오는 먼저 도착 → 디코더가 '립싱크'를 위해 오디오 버퍼링 → 전체 재생 지연

비디오에 B-frame이 있으면:

  1. 비디오 디코딩이 미래 프레임 기다려서 지연
  2. 오디오는 먼저 도착
  3. 재생 플레이어가 립싱크 맞추려고 오디오를 인위적으로 지연
  4. 결과적으로 전체 지연 증가

이것은 가능한 A/V sync 영향 중 하나입니다. player는 각 track timestamp와 clock mapping을 기준으로 sync하므로 실제 추가 audio buffering은 구현 정책으로 측정합니다.

한 줄 요약

질문답
오디오에 B-frame 있나?없음. 비디오 전용 개념
오디오 압축 방식은?주파수 분석 + 심리음향 모델 (완전 다른 접근)
관계가 아예 없나?코덱은 무관. 재생 타이밍(립싱크)에서만 간접 영향
실시간 음성 서비스는?Opus는 B-frame 이슈 없음. 비디오 함께 쓸 때만 신경

관련 글: 오디오 파이프라인 해부 · B-frame 이해하기 · RTMP B-frame PTS rollback 트러블슈팅


관련 글

참고 자료

© 2026 Frank Kim. All rights reserved.