fix: rtcp-feedback-negotiation/#90 - #91
Merged
Merged
Conversation
offeredVideoCodecs가 offer SDP에서 코덱을 재구성할 때 RTCPFeedback을 채우지 않아, SetCodecPreferences가 트랜시버 코덱 선호를 덮어쓰면서 answer의 a=rtcp-fb 라인이 전부 사라졌다. NACK · PLI · FIR · transport-cc · goog-remb가 인그레스·이그레스 양방향 모두 미협상 상태가 되어 송출 초반 몇 초간 디코더 레퍼런스가 손실됐다. a=rtcp-fb 라인을 페이로드 타입별로 읽어 RTPCodecCapability.RTCPFeedback에 채운다. 클라이언트가 제안한 피드백만 그대로 되돌려주며, 코덱 선택 순서는 바뀌지 않는다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
실제 ICE·DTLS 핸드셰이크를 마친 뒤 클라이언트가 적용하는 코덱 파라미터를 검증한다. pion은 NACK·PLI·transport-cc 인터셉터 구동 여부를 SDP 텍스트가 아니라 이 협상 파라미터로 결정하므로, 라이브 세션에서 피드백이 실제로 동작하는지는 이 값이 판별한다. 수정 전 코드에서는 receiver·sender 양쪽 모두 빈 리스트를 반환하며 실패한다. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Finefinee
approved these changes
Aug 11, 2026
itzjb
marked this pull request as ready for review
August 11, 2026 10:26
itzjb
approved these changes
Aug 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
변경 내용
송출 시작 직후 몇 초간 클라이언트 미리보기 영상의 정지 영역(벽·천장)만 파괴되고 자가복구되는 증상을 고쳤어요. 디코더 레퍼런스 손실이 원인이에요.
internal/session/video_codec.go의offeredVideoCodecs가 클라이언트 offer를 파싱해RTPCodecCapability를 재구성할 때RTCPFeedback을 채우지 않았어요. 이 값이prepareOutputForOffer의SetCodecPreferences로 비디오 트랜시버에 통째로 덮어써지고, Pion은 answer의a=rtcp-fb라인을 협상된 코덱의RTCPFeedback에서 생성하므로 answer에 피드백 라인이 한 줄도 실리지 않았어요.비디오 m-line은 sendrecv 하나뿐이라 인그레스·이그레스 양방향 모두 NACK · PLI · FIR · transport-cc · goog-remb가 미협상 상태였어요.
이제 offer SDP의
a=rtcp-fb라인을 페이로드 타입별로 읽어RTPCodecCapability.RTCPFeedback에 채워요. 서버가 임의로 피드백을 추가하지 않고 클라이언트가 제안한 것만 그대로 되돌려줘요. 코덱 선택 순서(클라이언트 offer 순서)는 바뀌지 않아요.실측 — answer의
a=rtcp-fb라인 수:nacknack pliccm firgoog-rembtransport-ccanswer는 협상된 코덱 하나(+RTX)만 광고하므로 offer처럼 수십 줄이 되지 않는 것이 정상이에요.
확인 방법
실제 ICE·DTLS 핸드셰이크를 맺고 클라이언트가 협상 후 적용하는 코덱 파라미터를 대조했어요. pion은 NACK·PLI·transport-cc 인터셉터 구동 여부를 SDP 텍스트가 아니라 이 값으로 결정해요.
Receiver().GetParameters()피드백[]ccm fir,goog-remb,nack,nack pli,transport-ccSender().GetParameters()피드백[]수정 전에도 연결 자체는 정상이고 피드백만 비어요 — "연결 실패"가 아니라 "초반 화질 깨짐 후 자가복구"였던 증상과 맞물려요.
TestAnswerRetainsOfferedRTCPFeedback(answer SDP 레벨) — 수정 전 RED → 수정 후 PASSTestConnectedPeerNegotiatesRTCPFeedback(연결 후 런타임 파라미터) — 수정 전 RED → 수정 후 PASS-count=5반복에서도 안정적이며 패키지 실행시간 변화 없음 (0.59s)gofmt -l internal/session빈 출력,go vet ./internal/session통과검증하지 못한 것
cmd/server빌드가 otel로 막혀 있는데, 원인은 저장소가 아니라 로컬 모듈 캐시 손상이에요 (go mod verify가x/sys·x/text·gonum·protobuf등 다수에 "dir has been modified"). 별도로 다뤄야 해요.범위 밖
drainRTCP의 PLI/FIR 분기 처리(2순위) — 현재 egress 인코더는 stdin 기반 별도 ffmpeg 프로세스라 실행 중 온디맨드 IDR을 강제할 채널이 없고, 인코더 재기동이냐 인프로세스 교체냐는 미결 설계 결정이에요. 별도 이슈로 다뤄요.문서
docs/가.gitignore에 등록되어 있어 문서 갱신은 이 PR에 포함되지 않아요. 로컬에서 아래 두 문서를 갱신해 뒀어요.docs/operations/TROUBLESHOOTING.md— "측정 1" 표에 수정 후 값 컬럼 추가, "해결책" 1순위를 완료(fix: WebRTC answer SDP가 offer의 rtcp-fb를 누락해 송출 초반 화면이 깨짐 #90)로 표시docs/operations/streaming-startup-corruption-verification.md— 상단에 "#90에서 수정됨" 한 줄 추가(조사 시점 수치는 그대로)Closes #90
🤖 Generated with Claude Code