# Pipeline disruption detectors

Capture, encoding, delivery, decoding and playout failures.

Version coverage: /docs/reference/versions/


{{< detector-table >}}
{{< detector-row name="CaptureSourceLostDetector" description="Reports when a capture source ends." trigger="`sourceEnded` capture flag; one-shot capture-source-lost" recovery="one-shot, not a continuously resolved threshold episode" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/CaptureSourceLostDetector.ts#L40" recoveryLabel="Reset and lifecycle behavior" displayName="Capture Source Lost" collects="The capture source's ended state." example="A camera capture source ends during a call." >}}
{{< detector-row name="SilentAudioSourceDetector" description="Detects sustained silence from an active microphone." trigger="live enabled unmuted microphone/device; RMS≤0.0001 for 60000 ms captured audio" recovery="RMS>0.0003 when raised; pause, screen share, lost input, ended source stand down" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/SilentAudioSourceDetector.ts#L106" displayName="Silent Audio Source" collects="Microphone activity, capture state and RMS audio level." example="An enabled, unmuted microphone remains near-silent for one minute." >}}
{{< detector-row name="VideoCaptureBottleneckDetector" description="Detects video capture producing fewer frames than expected." trigger="`1 − producedFps/expectedCaptureFps >0.2` over shared detection slice" recovery="recovery slice within threshold; settings changes, screen share, inactive tab/muted/paused source stand down" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/VideoCaptureBottleneckDetector.ts#L97" displayName="Video Capture Bottleneck" collects="Produced frame rate compared with expected capture frame rate." example="A camera produces substantially fewer frames than its expected capture rate." >}}
{{< detector-row name="EncoderBottleneckDetector" description="Detects encoding that cannot keep up with captured video." trigger="highest layer `1 − encodedFps/producedFps >0.3`" recovery="recovery slice within threshold; source/layer/config-change gates" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/EncoderBottleneckDetector.ts#L113" displayName="Encoder Bottleneck" collects="Captured and encoded frame rates for the highest sending layer." example="Capture continues normally, but the highest layer encodes fewer frames." >}}
{{< detector-row name="RtpSenderStalledDetector" description="Detects encoded video that stops leaving as RTP packets." trigger="frames encode but no RTP packets leave for 4000 ms" recovery="packets resume, stream disappears or guarded state; per-SSRC state" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/RtpSenderStalledDetector.ts#L51" displayName="RTP Sender Stalled" collects="Encoded frames, outgoing RTP packet progress and stall duration." example="Frames are encoded, but outgoing RTP packets stop for four seconds." >}}
{{< detector-row name="DryOutboundTrackDetector" description="Detects an active outbound track that stops sending data." trigger="active layer byte deltas sum to zero for 5000 ms" recovery="data resumes; pause/mute/end/encoder limitation/no active layer stand down" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/DryOutboundTrackDetector.ts#L78" displayName="Dry Outbound Track" collects="Byte deltas across active outbound layers and track lifecycle state." example="An active sending track produces no outgoing bytes for five seconds." >}}
{{< detector-row name="TransportDemuxStalledDetector" description="Detects incoming transport data that does not reach existing RTP streams." trigger="transport receives ≥20000 bps while existing inbound RTP accounts for zero bytes, 4000 ms" recovery="RTP progress, missing transport or failed guards; per-transport state" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/TransportDemuxStalledDetector.ts#L52" displayName="Transport Demux Stalled" collects="Received transport bitrate and byte progress on existing inbound RTP streams." example="Transport data arrives, but none of the existing RTP streams advances." >}}
{{< detector-row name="DryInboundTrackDetector" description="Detects an inbound track that stops receiving data." trigger="incoming byte delta zero for 5000 ms" recovery="bytes resume, local/remote declared pause, ended track" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/DryInboundTrackDetector.ts#L39" displayName="Dry Inbound Track" collects="Incoming byte deltas and local or remote pause declarations." example="An inbound track receives no bytes for five seconds without a declared pause." >}}
{{< detector-row name="FrameAssemblyStalledDetector" description="Detects incoming packets that stop producing complete video frames." trigger="packets arrive, `framesReceived` flat; ≥20 packets and ≥3000 ms" recovery="complete frame arrives or stand-down gates" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/FrameAssemblyStalledDetector.ts#L44" displayName="Frame Assembly Stalled" collects="Incoming packet progress, complete-frame counters and elapsed time." example="Packets keep arriving, but no complete video frame is assembled." >}}
{{< detector-row name="DecoderBottleneckDetector" description="Detects decoding that cannot keep up with incoming frames." trigger="received frame supply≥5 fps, decoding shortfall>0.1 over shared window" recovery="recovery window catches up; dropped-frame and foreground/context gates distinguish causes" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/DecoderBottleneckDetector.ts#L126" displayName="Decoder Bottleneck" collects="Received and decoded frame supply over shared windows, with context gates." example="Complete frames arrive faster than the decoder can process them." >}}
{{< detector-row name="DecoderPerformanceDetector" description="Detects excessive time spent decoding video frames." trigger="decode time >0.8×frame budget, ≥10 received frames, interval loss≤0.02, 2 ticks" recovery="decode keeps up, insufficient frames, loss dominates, ended/background" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/DecoderPerformanceDetector.ts#L73" displayName="Decoder Performance" collects="Decode time, frame budget, received frames and interval packet loss." example="With enough frames and little loss, decoding takes most of the frame budget." >}}
{{< detector-row name="StuckDecoderDetector" description="Detects a decoder that stops producing frames despite incoming media." trigger="no decoded frames with bitrate≥10000, ≥2 PLIs, elapsed≥max(4000 ms,15×RTT)" recovery="decoded frames return or source/context/foreground gates; records assembly evidence" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/StuckDecoderDetector.ts#L66" displayName="Stuck Decoder" collects="Incoming bitrate, decoded-frame progress, PLI count and RTT." example="Media continues arriving and keyframes are requested, but decoding makes no progress." >}}
{{< detector-row name="PlayoutDiscrepancyDetector" description="Detects a gap between received and rendered video frames." trigger="received-vs-rendered frame skew≥0.25 with ≥10 frames in detection window" recovery="skew<0.1 or stand-down; despite prose mentioning decode-to-render, inspect actual operands" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/PlayoutDiscrepancyDetector.ts#L63" displayName="Playout Discrepancy" collects="Received and rendered frame counts over shared windows." example="Received frames accumulate while substantially fewer frames reach display." >}}
{{< detector-row name="VideoRecoveryFailedDetector" description="Detects stalled video that fails to recover after keyframe requests." trigger="stalled picture/keyframe recovery, ≥2 PLIs, ≥5000 ms" recovery="video recovery or guards; repair-loop diagnosis separate from perceptual freeze" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/VideoRecoveryFailedDetector.ts#L44" displayName="Video Recovery Failed" collects="Stalled video, keyframe requests and recovery duration." example="Repeated keyframe requests fail to restore a moving picture." >}}
{{< detector-row name="CpuPerformanceDetector" description="Detects high CPU utilization from software encoding or decoding." trigger="measurable software encode/decode utilization at least 0.5 across client detection window" recovery="recovery below 0.4; background/no CPU-backed work/no measurement stand down" source="https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/CpuPerformanceDetector.ts#L104" displayName="CPU Performance" collects="Measurable software encode/decode utilization across the client window." example="Software media processing keeps measured utilization above the detection threshold." >}}
{{< /detector-table >}}

Sources: named files under [client-monitor-js/src/detectors/Detectors.ts](https://github.com/ObserveRTC/client-monitor-js/blob/0f08bd5d110a4e9d53cf0486962e638c5b393c49/src/detectors/Detectors.ts), plus the full algorithms in the [detector implementation reference](/reference/detector-implementation-reference.md). Shared-window readiness and total-vs-delta choices are material to all capture/encoder/decoder comparisons.

