DECODE_OVERLOAD 발생 감소 ANALYSIS 개선 방안

마지막 업데이트 2026-07-29

DECODE_OVERLOAD 발생 감소 ANALYSIS 개선 방안: 증상: 배경, 원인: full:video 스텝 게스트 브라우저 실제 부하, 수정·검증: 추가 개선 — MediaCapabilities 기반 정밀 판정 흐름
동작 흐름 요약
  1. 증상: 배경
  2. 원인: full:video 스텝 게스트 브라우저 실제 부하
  3. 수정·검증: 추가 개선 — MediaCapabilities 기반 정밀 판정
문서 읽는 법 · 수사반장식

이 문서는 이렇게 읽으면 됩니다

DECODE_OVERLOAD 발생 감소 — 인코딩 파라미터 및 lowPerf 기준 개선의 핵심을 수사반장식으로 먼저 안내합니다. 기술적 결론과 원문 근거는 아래 본문에 보존되어 있습니다.

핵심 흐름 펼쳐 보기
  1. 결론부터 확인한 뒤 증상과 영향을 읽습니다.
  2. 시간순 수사 흐름에서 가설과 반증을 따라갑니다.
  3. 마지막으로 로그·코드·검증 섹션에서 근거를 확인합니다.
  • 결론 — 처방부터 공개한다
  • 배경
  • full:video 스텝 게스트 브라우저 실제 부하
연관 이슈: VideoEndWatchdog DECODE_OVERLOAD 반복 stall 미발화 관련 파일: apps/web/lib/utils.ts, Lambda 인코딩 함수 작성: 2026-06-17

결론 — 처방부터 공개한다

DECODE_OVERLOAD의 근본 원인은 영상 디코딩 부하이며, 감소 처방은 두 축이다. ① 480p 인코딩 경량화(fps 30→24, maxrate 1200k→800k — Lambda 수정 + 재인코딩 배치)와 ② lowPerf 판정 기준 완화(≤4코어 or ≤8GB — 6코어/8GB 기기도 480p 수신). 1+2 동시 적용이 가장 빠른 개선이고, MediaCapabilities 실측 판정 우선 적용과 VideoEndWatchdog wall clock drift 감지(별도 문서)는 각각 정밀화·안전망으로 뒤따른다.

배경

3개 세션(아동303 25회기, 아동049 24회기, 아동074 2회기)에서 full:video 스텝 영상 재생 중 DECODE_OVERLOAD가 반복 발생하여 자동전환 실패 및 호스트 수동 개입이 7회 이상 확인됨. Watchdog 설계 한계(별도 문서)와 함께, DECODE_OVERLOAD 자체를 줄이는 방향을 분석함.

분석의 출발점

줄이려면 먼저 무엇이 무거운지 알아야 한다. full:video 스텝에서 게스트 브라우저가 실제로 지고 있는 부하부터 목록화했다.

full:video 스텝 게스트 브라우저 실제 부하

확인된 사항: 게스트는 useMediasoupProducer만 사용하며 호스트 스트림을 consume하지 않음. 게스트 화면에는 자신의 웹캠(셀프뷰)이 렌더링됨.
활동 영상 MP4 디코딩 ← 주 부하 H.264 720p/480p 게스트 카메라 H.264 인코딩 ← 중간 mediasoup으로 호스트에 송신 (유지 필요) 게스트 카메라 셀프뷰 렌더링 ← 낮음 srcObject 직접 표시, 추가 디코딩 없음 OpenAI Realtime Opus ← 낮음 응답 차단 상태, 파이프라인 유지 게스트 마이크 인코딩 ← 낮음 음소거 상태

오디오 파이프라인(Opus) pause 효과는 미미함. 근본 원인은 영상 디코딩 부하이므로 서버 인코딩 파라미터와 lowPerf 판정 기준이 핵심 개선 대상.

개선 대상 확정

주 부하가 영상 디코딩으로 좁혀지자 질문은 둘로 나뉘었다 — 누가 무거운 영상을 받고 있는가(lowPerf 판정), 그리고 영상 자체가 왜 이렇게 무거운가(인코딩 파라미터). 3개 세션의 실제 데이터로 첫 번째 질문부터 확인했다.

문제점 1 — lowPerf 기준 미달 기기가 720p 수신 BUG

현재 lowPerf 판정 기준 (apps/web/lib/utils.ts)

// 데스크탑/노트북
return hardwareConcurrency <= 2 || (memoryInfo > 0 && memoryInfo <= 4);
세션디바이스lowPerf 판정제공 해상도DECODE_OVERLOAD
아동303 25회기 6코어 / 8GB ❌ 정상 기기 판정 720p (maxrate 1800k) droppedFrames 31%
아동049 24회기 6코어 / 8GB ❌ 정상 기기 판정 720p (maxrate 1800k) 반복 발생
아동074 2회기 8코어 / 4GB ✅ lowPerf 판정 (≤4GB) 480p (maxrate 1200k) 반복 발생 (여전히)
아동303·아동049 케이스의 근본 원인: 6코어/8GB는 현재 기준을 통과하므로 720p 1800kbps를 수신. WebRTC 인코딩/전송 + AI 오디오 파이프라인과 동시에 720p를 디코딩하면 중간 사양 기기에서도 과부하가 발생할 수 있음.

개선: lowPerf 기준 완화

// apps/web/lib/utils.ts — 데스크탑/노트북 기준 완화
return hardwareConcurrency <= 24 || (memoryInfo > 0 && memoryInfo <= 48);
효과: 6코어/8GB 기기도 480p를 수신하게 됨. 수업 중 동시 미디어 부하를 감안한 보수적 기준.
부작용: 고성능 기기(예: M1 MacBook)도 480p를 받을 수 있음. MediaCapabilities.decodingInfo() 결과를 1차 판단 기준으로 삼는 방안(하단 참고)이 더 정밀함.
남는 의문

그런데 판정 기준 완화만으로는 설명되지 않는 케이스가 있었다 — 아동074는 이미 lowPerf 판정을 받아 480p를 수신하고도 DECODE_OVERLOAD가 반복됐다. 480p 자체가 무겁다는 뜻이다.

문제점 2 — 480p maxrate 1200k가 여전히 무거움 CAUSE

현재 480p 인코딩 파라미터 (Lambda)

# 현재
scale = 'scale=854:480:flags=lanczos,fps=30'
maxrate = '1200k'
bufsize = '2400k'
crf = 22

활동 영상은 캐릭터 애니메이션 스타일 콘텐츠로 실사 영상 대비 정보량이 적음. 1200kbps는 이 콘텐츠 유형에 과도하며, 800kbps 이하로도 충분한 화질 유지 가능. fps=30 → 24 전환 시 초당 디코딩 프레임 20% 감소.

개선: 480p 비트레이트 인하

# 개선안
scale = 'scale=854:480:flags=lanczos,fps=3024'
maxrate = '1200k800k'
bufsize = '2400k1600k'
crf = 22  # 동일 유지
항목변경 전변경 후디코딩 효과
fps3024초당 프레임 20% 감소
maxrate1200kbps800kbps비트 처리량 33% 감소
bufsize2400k1600k버퍼 소비 감소
profile/codecbaseline, cabac=0, ref=1동일유지
효과: 아동074 케이스처럼 480p를 받고도 DECODE_OVERLOAD가 발생하는 경우 감소 기대. 활동 영상 콘텐츠 특성상 24fps/800k에서 체감 화질 저하 없음.
필요 작업: Lambda 코드 수정 후 기존 업로드된 영상 전체 재인코딩 배치 실행 필요. 신규 업로드 영상부터는 자동 적용됨.
더 정밀한 판정으로

두 처방은 모두 스펙 숫자(코어 수·메모리) 기반이라 거칠다. 6코어/8GB이지만 GPU 가속이 없는 기기처럼 스펙만으로 포착되지 않는 사례를 위해, 이미 존재하는 실측 API를 1차 기준으로 끌어올리는 방안을 함께 검토했다.

추가 개선 — MediaCapabilities 기반 정밀 판정

이미 _checkDesktopDecodingCapability() 함수가 존재하며 H.264 720p 30fps 1Mbps 기준으로 smooth && powerEfficient 여부를 확인함. 현재는 보조 수단으로만 사용 중.

// apps/web/lib/utils.ts — _checkDesktopDecodingCapability
const result = await navigator.mediaCapabilities.decodingInfo({
  type: "file",
  video: {
    contentType: "video/mp4; codecs=avc1.42E01E",
    width: 1280, height: 720,
    bitrate: 1_000_000, framerate: 30,
  },
});
// smooth=false OR powerEfficient=false → lowPerf 판정
제안: 하드웨어 스펙 기준(코어 수, 메모리)보다 MediaCapabilities 실측 결과를 우선 적용하면 기기 스펙만으로는 포착 못 하는 사례(6코어/8GB이지만 GPU 가속 미지원 등)를 커버 가능.

단, MediaCapabilities는 비동기 API이므로 앱 초기화 시 한 번 평가 후 캐싱하는 현재 방식 유지.

적용 우선순위

우선순위작업효과구현 비용비고
1 480p fps 30→24, maxrate 1200k→800k 높음 낮음 Lambda 수정 + 재인코딩 배치
2 lowPerf 기준 완화 (≤4코어 or ≤8GB) 높음 낮음 lib/utils.ts 1줄 수정
3 MediaCapabilities 판정 우선 적용 중간 중간 이미 함수 존재, 로직 연결 필요
4 VideoEndWatchdog wall clock drift 감지 중간 낮음 DECODE_OVERLOAD 발생 시 자동전환 보장 (별도 문서)
1+2를 동시에 적용하는 것이 가장 빠른 개선. 1은 서버 작업, 2는 프론트 작업으로 병행 가능. 4는 DECODE_OVERLOAD를 예방하지는 않지만 발생 시 자동전환을 보장하는 안전망이므로 함께 진행 권장.

관련 문서