Skip to content

Commit ffb9989

Browse files
authored
WebRTCGetStartedVP8Net: add per-second source + RTCP packet-count diagnostics (#1581)
Adds two unconditional packet counters to the example so we can distinguish sender-side audio failure from receiver-side drop the next time audio cuts out mid-session. Background ---------- Audio loss has been observed in this example after some seconds of streaming. chrome://webrtc-internals confirms packetsLost = 0 on both streams and iceState = connected at failure time, with video continuing to flow normally on the same transport while audio's bytesReceived/s drops to 0. From the receiver's vantage point we can't tell whether: (a) The .NET sender stopped emitting audio packets (encoder/timer stuck, or pc.SendAudio failing silently); or (b) Packets are leaving the sender but Chrome is dropping them pre-stats — suspected SRTP / DTLS auth issue, which doesn't manifest as packetsLost or bytesReceived because failed-auth packets are discarded before being counted. The previous music-source-EOF hypothesis is ruled out: the embedded Macroform_-_Simplicity.raw is 200.6 s of music and the observed audio cut-off is at ~166 s with 35+ s of audio remaining in the file. Diagnostics added ----------------- 1. "src" counter on the source-side encoded-sample events: OnVideoSourceEncodedSample += { send + Interlocked.Increment } OnAudioSourceEncodedSample += { send + Interlocked.Increment } Logged once per second of source rate (every 15 video frames / every 50 audio packets). If this counter freezes at the moment audio dies, the source itself stopped producing. 2. "rtcp" counter from outgoing RTCP Sender Reports, hooked via pc.OnSendReport. SIPSorcery emits SRs every ~5 s by default and PacketCount is the cumulative count of RTP packets the local send path has actually emitted on each stream. If "src" keeps incrementing past audio-loss but "rtcp" PacketCount on the audio SSRC stalls (or grows much slower than "src"), packets are being silently dropped between the source-side event and the wire — for example by SRTP encryption returning an error that pc.SendAudio swallows. If "src" stalls, the source itself is the issue. Comparing the audio rtcp PacketCount with Chrome's inbound-rtp packetsReceived for the same SSRC then tells us whether the remaining packets are leaving .NET but failing in transit / at Chrome (PacketCount > packetsReceived) or whether SIPSorcery itself stopped sending (PacketCount = packetsReceived, both stop together). No bitstream or timing changes; pure observability addition. The example's existing Q=96/15fps configuration is unchanged. Author attribution: Claude Opus 4.7 (model: claude-opus-4-7), commissioned by Aaron Clauson — per the convention from #1562.
1 parent 2317140 commit ffb9989

1 file changed

Lines changed: 52 additions & 2 deletions

File tree

  • examples/WebRTCExamples/WebRTCGetStartedVP8Net

examples/WebRTCExamples/WebRTCGetStartedVP8Net/Program.cs

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,58 @@ private static Task<RTCPeerConnection> CreatePeerConnection()
129129
MediaStreamTrack audioTrack = new MediaStreamTrack(audioSource.GetAudioSourceFormats(), MediaStreamStatusEnum.SendRecv);
130130
pc.addTrack(audioTrack);
131131

132-
testPatternSource.OnVideoSourceEncodedSample += pc.SendVideo;
133-
audioSource.OnAudioSourceEncodedSample += pc.SendAudio;
132+
// ---- Diagnostic packet counters ----
133+
//
134+
// Two counters logged once per second on each stream:
135+
//
136+
// * "src": packets handed off by the source to pc.Send*.
137+
// Increments iff the source is still producing
138+
// encoded samples — answers "did our test
139+
// source / encoder stop?".
140+
//
141+
// * "rtcp": cumulative PacketCount field of our outgoing
142+
// RTCP Sender Reports, fired by SIPSorcery's
143+
// RTPSession.OnSendReport. SIPSorcery emits an
144+
// SR roughly every 5 s and sets PacketCount to
145+
// the total number of RTP packets that have
146+
// actually left this peer. If this counter
147+
// keeps growing while Chrome's webrtc-internals
148+
// packetsReceived stalls, packets are leaving
149+
// the .NET app but Chrome is dropping them
150+
// (suspected SRTP / DTLS issue). If "rtcp"
151+
// stalls when "src" stalls, the issue is at or
152+
// above the SIPSorcery send path.
153+
int audioSrcCount = 0, videoSrcCount = 0;
154+
155+
testPatternSource.OnVideoSourceEncodedSample += (rtpTs, frame) =>
156+
{
157+
pc.SendVideo(rtpTs, frame);
158+
int n = System.Threading.Interlocked.Increment(ref videoSrcCount);
159+
if (n % 15 == 0) { logger.LogInformation("video src: {Count} frames (~{Sec:F0}s at 15 fps)", n, n / 15.0); }
160+
};
161+
162+
audioSource.OnAudioSourceEncodedSample += (rtpTs, sample) =>
163+
{
164+
pc.SendAudio(rtpTs, sample);
165+
int n = System.Threading.Interlocked.Increment(ref audioSrcCount);
166+
if (n % 50 == 0) { logger.LogInformation("audio src: {Count} packets (~{Sec:F0}s at 50 pps)", n, n / 50.0); }
167+
};
168+
169+
// Hook outgoing RTCP Sender Reports. PacketCount is the
170+
// cumulative count of RTP packets the local SIPSorcery
171+
// send path has emitted on each stream. Compare against
172+
// Chrome's inbound-rtp packetsReceived to see whether
173+
// packets are getting lost between the .NET app and
174+
// Chrome. SIPSorcery emits SRs every ~5 s by default.
175+
pc.OnSendReport += (mediaType, compound) =>
176+
{
177+
var sr = compound?.SenderReport;
178+
if (sr != null)
179+
{
180+
logger.LogInformation("rtcp SR {Media}: SSRC={SSRC,10} PacketCount={Pkts} OctetCount={Octets}",
181+
mediaType, sr.SSRC, sr.PacketCount, sr.OctetCount);
182+
}
183+
};
134184

135185
pc.OnVideoFormatsNegotiated += (formats) => testPatternSource.SetVideoSourceFormat(formats.First());
136186
pc.OnAudioFormatsNegotiated += (formats) => audioSource.SetAudioSourceFormat(formats.First());

0 commit comments

Comments
 (0)