Skip to content
이 문서의 중국어 번역본이 있습니다 기계번역 / 机翻중국어판 보기 →

화면 암전 구간 이후에 버퍼링이 발생하는 이유 ​

VBR 인코딩의 비트레이트 붕괴 구간이 플레이어의 ABR 판단을 속이면, 정작 버퍼링은 화면이 다시 밝아진 뒤에 발생합니다.

먼저 관측된 현상 ​

실제 운영 중이던 라이브 채널에서 있었던 일입니다. 4시간짜리 이벤트였고, CDN 엣지 기준 최고 대역폭은 약 824.47 Mbps였습니다. 인코더, 패키저, CDN, 네트워크 어느 쪽에도 리소스 특이사항이 없었습니다. 그런데 운영 중 모니터링 지표에서 버퍼링 그래프만 순간적으로 급증하는 구간이 관측됐습니다.

체크리스트를 순서대로 훑었는데 전부 깨끗했습니다.

확인 대상결과
CDN 엣지 5xx, 타임아웃 비율변화 없음
오리진 CPU, 메모리, 대역폭여유 충분
오리진 응답 시간 분포 (p50 / p99)평시와 동일
세그먼트 생성 간격, 매니페스트 갱신 지연정상
네트워크 구간 패킷 손실유의미한 값 없음
인코더 입력 프레임 드롭없음

주의: 이런 조합이 나오면 전달 경로에는 문제가 없다는 뜻입니다. 그러면 남은 곳은 두 군데뿐입니다. 콘텐츠 자체, 그리고 플레이어의 판단 로직입니다.

타임라인을 겹쳐 보니 ​

패키저 출력 인코딩 품질을 시간축으로 뽑아서 원본 영상과 나란히 놓아 봤습니다.

1080p rendition 출력 비트레이트가 원본 영상 암전 구간에서 붕괴했다가 회복되고, 버퍼링 스파이크는 그 직후에 나타나는 시간차 그래프

핵심은 두 가지입니다.

  1. VBR 출력 비트레이트가 급격히 낮아졌다가 다시 급격히 올라갔습니다.
  2. 비트레이트가 낮았던 약 7초 구간이 원본 영상이 약 8초간 암전됐던 구간과 정확히 겹칩니다.

그리고 버퍼링 스파이크는 비트레이트가 떨어질 때가 아니라, 다시 올라간 직후에 나타났습니다. 이 시간차가 이 현상의 정체를 알려줍니다.

VBR의 정상 동작이 함정이 되는 지점 ​

VBR은 화면 복잡도에 따라 비트를 다르게 씁니다. 움직임이 많고 디테일이 많으면 비트를 많이 쓰고, 화면이 정적이거나 어두우면 적게 씁니다. 암전 구간은 인코더 입장에서 압축하기 가장 쉬운 화면입니다. residual이 거의 없기 때문입니다. 그래서 비트레이트가 바닥을 칩니다.

이건 버그가 아니라 VBR이 잘 동작한 증거입니다. 문제는 이 현상이 ABR ladder 전체에 동시에 일어난다는 점입니다.

rendition목표 비트레이트움직임 구간 실측암전 구간 실측(추정)
1080p8 Mbps약 8 Mbps1 Mbps 이하
720p4 Mbps약 4 Mbps1 Mbps 이하
480p2 Mbps약 2 Mbps1 Mbps 이하
360p1 Mbps약 1 Mbps1 Mbps 이하

참고: 암전 구간에서는 모든 화질 레벨의 실제 비트레이트가 서로 붙어버립니다. 1080p와 360p가 둘 다 1 Mbps 아래라면, 그 순간의 ladder는 계단이 아니라 평지입니다.

플레이어 측 동작 ​

ABR 로직은 대체로 이렇게 동작합니다.

추정 대역폭 = 방금 받은 세그먼트 크기(bit) / 다운로드에 걸린 시간(s)

if (추정 대역폭 > 상위 rendition 선언 비트레이트 x safety factor) {
    상위 rendition으로 전환
}

여기서 분자인 세그먼트 크기가 콘텐츠 복잡도에 따라 변한다는 사실이 빠져 있습니다. 대역폭 1 Mbps인 사용자를 놓고 계산해 보겠습니다.

[움직임 구간, 360p 시청 중]
  세그먼트: 6초 x 1 Mbps = 약 0.75 MB
  다운로드 시간: 0.75 MB / (1 Mbps) = 약 6초
  추정 대역폭 = 1 Mbps          -> 360p 유지, 정확한 판단

[암전 구간, 360p 시청 중]
  세그먼트: 6초 x 0.3 Mbps = 약 0.22 MB   (VBR이 비트를 덜 씀)
  다운로드 시간: 0.22 MB / (1 Mbps) = 약 1.8초
  추정 대역폭 = 6초 분량을 1.8초에 받았으니 약 3.3 Mbps로 계산됨
                                -> "네트워크가 좋아졌다" 판단
                                -> 720p 또는 1080p로 상향

[암전 종료, 1080p 시청 중]
  세그먼트: 6초 x 8 Mbps = 약 6 MB
  다운로드 시간: 6 MB / (1 Mbps) = 약 48초
  6초 분량을 48초에 받는 중 => 버퍼 고갈 => 버퍼링 발생

참고: 사용자의 실제 대역폭은 1 Mbps에서 1 바이트도 변하지 않았습니다. 그런데 플레이어는 대역폭이 3배 넓어졌다고 판단했습니다. 원인은 네트워크가 아니라 분자가 흔들렸다는 사실을 모르는 추정식입니다.

그리고 상향 전환 결정과 그 대가를 치르는 시점 사이에 시차가 있기 때문에, 버퍼링은 항상 화면이 다시 밝아진 뒤에 나타납니다. 지표만 보고 원인 시각을 찾으면 엉뚱한 구간을 파게 되는 이유입니다.

그래서 인코딩 쪽에서 무엇을 바꾸는가 ​

권장하는 방향은 CBR 계열로의 전환입니다. 선택지를 비교하면 다음과 같습니다.

방식비트 배분ABR 정확도저장/전송 효율라이브 적합도
VBR복잡도에 따라 자유롭게 변동낮음 (분자가 흔들림)가장 좋음낮음
capped VBR변동하되 상한 고정중간 (하한은 여전히 붕괴)좋음중간
CBR구간 평균을 목표값에 고정, 부족하면 padding높음낮음 (쉬운 화면에서 비트 낭비)높음

정적 화면에서 낭비되는 비트가 아까워 보이지만, 라이브 ABR에서는 선언한 비트레이트가 실제와 일치한다는 보장이 대역폭 절약보다 값이 큽니다. ladder 각 단계의 실측 비트레이트가 서로 겹치지 않는 것, 그게 ABR이 성립하는 전제 조건입니다.

주의: capped VBR로만 바꾸면 절반만 해결됩니다. 문제를 만드는 쪽은 상한이 아니라 하한 붕괴입니다. 최소 비트레이트 하한(min bitrate)이나 padding이 없으면 암전 구간에서 여전히 ladder가 평지가 됩니다.

플레이어 쪽에서 완화할 수 있는 것 ​

인코딩을 바꿀 수 없는 상황도 있으니 완화 장치도 정리해 둡니다.

  • 추정 대역폭을 단일 세그먼트가 아니라 여러 세그먼트의 이동 평균 또는 조화 평균으로 계산합니다. 7초짜리 이상치가 판단을 뒤집지 못하게 만드는 게 목적입니다.
  • 상향 전환에 버퍼 수준 조건을 추가합니다. 추정 대역폭이 충분해도 버퍼가 목표치 아래면 올리지 않습니다.
  • 상향 전환에 쿨다운을 둡니다. 하향은 즉시, 상향은 보수적으로 가는 비대칭 정책이 라이브에서는 거의 항상 맞습니다.
  • 세그먼트 크기 대신 매니페스트가 선언한 BANDWIDTH 값을 상향 판단 기준의 하한으로 함께 씁니다. 실측만 믿으면 이번 케이스에 그대로 걸립니다.

같은 시간대에 함께 울렸던 알람들 ​

참고로 이 구간에는 다른 알람도 두 종류 같이 떴는데, 둘 다 정상 동작이었습니다. 진단 순서를 흐리는 노이즈였기 때문에 같이 적어둡니다.

  • 세그먼트 404 급증: DASH MPD의 SegmentTemplate은 $Time$ 값이 SegmentTimeline의 t 필드와 연결된 구조입니다. 플레이어가 타임스탬프를 계산해서 요청하는 과정에서 아직 생성되지 않은 타임스탬프를 선요청할 수 있고, 그때 404가 납니다. 오리진이 실제 생성한 세그먼트 요청은 전부 200으로 로깅되고 있었습니다. DASH 라이브에서 소량의 404는 정상 범주입니다.
  • 403 급증: 분당 약 150회 규모였고, 전부 IP allowlist에 없는 출처의 요청이었습니다. 정책이 의도대로 동작한 결과입니다.

참고: 지표 3개가 동시에 튀면 하나의 원인이 있을 것 같지만, 실제로는 무관한 정상 동작 2개와 진짜 이슈 1개인 경우가 훨씬 많습니다. 각 알람의 정상 범주 baseline을 미리 정의해 두는 게 사고 대응 시간을 줄이는 가장 싼 방법입니다.

원리 정리 ​

  • VBR: 화면 복잡도에 따라 비트레이트가 변하는 인코딩입니다. 평균 품질 대비 효율이 가장 좋습니다.
  • CBR: 구간 평균 비트레이트를 목표값에 고정하는 인코딩입니다. 쉬운 화면에서는 비트를 낭비하지만 출력이 예측 가능합니다.
  • ABR: 클라이언트가 관측한 다운로드 성능을 근거로 rendition을 선택하는 방식입니다. 관측값이 세그먼트 크기 / 다운로드 시간이라는 점이 중요합니다.

한 문장으로 압축하면, ABR은 네트워크를 측정하는 게 아니라 콘텐츠 크기 나누기 시간을 측정합니다. 그래서 콘텐츠 크기가 콘텐츠 사정으로 흔들리면 ABR은 네트워크가 흔들렸다고 착각합니다. 라이브에서 CBR을 쓰는 이유는 화질 일관성이 아니라, ABR에게 거짓말을 하지 않기 위해서입니다.

정리 ​

  • 전달 경로(CDN, 오리진, 네트워크)가 전부 정상인데 버퍼링 지표만 튀면, 콘텐츠 특성과 플레이어 판단 로직을 봐야 합니다.
  • 약 8초간의 원본 암전 구간에서 VBR 출력 비트레이트가 붕괴했고(약 7초), ABR ladder의 모든 단계가 사용자 대역폭 1 Mbps 아래로 내려가 계단이 평지가 됐습니다.
  • 플레이어는 짧아진 다운로드 시간을 대역폭 개선으로 오판해 상위 rendition으로 올라갔고, 화면이 다시 밝아져 1080p가 8 Mbps로 복귀한 순간 버퍼가 고갈됐습니다. 그래서 버퍼링은 암전 구간이 아니라 그 직후에 나타납니다.
  • 근본 해결은 CBR 전환입니다. capped VBR만으로는 상한만 잡히고 하한 붕괴가 남습니다.
  • 플레이어 측 완화책은 다중 세그먼트 평균 기반 대역폭 추정, 버퍼 수준 조건 결합, 상향 전환 쿨다운, 매니페스트 선언 비트레이트 참조입니다.

基于 VitePress 构建 · 部署于腾讯云 EdgeOne Pages