OBSERVERTC / Reference
Monitor fields and exact calculations
Inspect field calculations and serialization against a pinned implementation.
This generated reference covers Client Monitor 4.9.1, not the latest release. Use it to investigate the documented implementation baseline; check versions and compatibility before applying a formula to another version.
For a guided explanation, start with Metrics and missing values. The raw Markdown inventory remains available for download and agent use.
Generated from the TypeScript AST, not from README lists. Stable 4.9.1 is the main inventory. Schema membership alone is NOT a provenance test: attachments, identity, context, adapter reconstruction and detector outputs are distinct. Each assignment links to its full enclosing implementation; read its guards before using the expression. Assignments are an index, not a promise that every field is refreshed every tick.
ClientMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
samplingSchemaVersion | public static readonly samplingSchemaVersion = schemaVersion; | L63 |
createdAt | public readonly createdAt = Date.now(); | L64 |
mappedPeerConnections | public readonly mappedPeerConnections = new Map<string, PeerConnectionMonitor>(); | L66 |
mappedExtensionStatsMonitors | public readonly mappedExtensionStatsMonitors = new Map<string, ExtensionStatsMonitor>(); | L67 |
detectors | Detectors | L68 |
clientEventPayloadProvider | public readonly clientEventPayloadProvider = new ClientEventPayloadProvider(); | L69 |
extensionStatsProviders | public readonly extensionStatsProviders = new Set<ExtensionStatProvider>(); | L70 |
activeIssues | IssueRegistry | L77 |
slicedWindow | SlicedWindow< | |
| ClientWindowValues, | ||
| Record<keyof ClientWindowConfig[’numberOfSamples’], SliceConfig> | ||
| > | L84 | |
scoreCalculator | ScoreCalculator | L89 |
logger | Logger | L90 |
closed | public closed = false; | L91 |
lastSampledAt | public lastSampledAt = 0; | L92 |
lastCollectingStatsAt | public lastCollectingStatsAt = 0; | L93 |
cpuPerformanceAlertOn | public cpuPerformanceAlertOn = false; | L95 |
cpuUtilization | number | L102 |
activeTab | public activeTab = true; | L110 |
sendingAudioBitrate | public sendingAudioBitrate = -1; | L112 |
sendingVideoBitrate | public sendingVideoBitrate = -1; | L113 |
receivingAudioBitrate | public receivingAudioBitrate = -1; | L114 |
receivingVideoBitrate | public receivingVideoBitrate = -1; | L115 |
totalAvailableIncomingBitrate | public totalAvailableIncomingBitrate = -1; | L116 |
totalAvailableOutgoingBitrate | public totalAvailableOutgoingBitrate = -1; | L117 |
avgRttInSec | public avgRttInSec = -1; | L119 |
score | public score = 5.0; | L120 |
scoreReasons | Record<string, number> | L121 |
durationOfCollectingStatsInMs | public durationOfCollectingStatsInMs = 0; | L136 |
config | AppliedClientMonitorConfig<AppData> | L137 |
attachments | Record<string, unknown> | L144 |
clientId | public get clientId() { return this.config.clientId; } | L498 |
callId | public get callId() { return this.config.callId; } | L503 |
appData | AppData | L508 |
uptimeInMs | public get uptimeInMs() { | L521 |
browser | public get browser() { | L546 |
peerConnections | public get peerConnections() { | L1076 |
codecs | public get codecs() { | L1080 |
inboundRtps | public get inboundRtps() { | L1084 |
outboundRtps | public get outboundRtps() { | L1088 |
remoteInboundRtps | public get remoteInboundRtps() { | L1092 |
remoteOutboundRtps | public get remoteOutboundRtps() { | L1096 |
mediaSources | public get mediaSources() { | L1100 |
mediaPlayouts | public get mediaPlayouts() { | L1104 |
dataChannels | public get dataChannels() { | L1108 |
iceCandidatePairs | public get iceCandidatePairs() { | L1112 |
iceCandidates | public get iceCandidates() { | L1116 |
iceTransports | public get iceTransports() { | L1120 |
certificates | public get certificates() { | L1124 |
tracks | TrackMonitor[] | L1128 |
Assignment and formula index
- logger L152:
this.logger = monitorConfig.logger ?? createLogger() - config L165:
this.config = { ...monitorConfig, collectingPeriodInMs: monitorConfig.collectingPeriodInMs ?? 5000, samplingPeriodInMs: monitorConfig.samplingPeriodInMs ?? 5000, integrateNavigatorMediaDevices: monitorConfig.integrateNavigatorMediaDevices ?? true, watchTabVisibility: monitorConfig.watchTabVisibility ?? true, addClientJointEventOnCreated: monitorConfig.addClientJointEventOnCreated ?? true, addClientLeftEventOnClose: monitorConfig.addClientLeftEventOnClose ?? true, // The slices are counted in values, not milliseconds, so that a slice asked for N // values holds N at any collecting period and is readable at any cadence. What varies // is the stretch those values span: N values span N-1 intervals, so at the default // 5000ms period a slice of 2 covers 5s and one of 4 covers 15s. 'maxAllowedGapInMs' // tolerates a couple of late or missed collections and treats anything longer as a // blackout worth starting again after. outboundTrackWindow: monitorConfig.outboundTrackWindow ?? { numberOfSamples: { detection: 3, recovery: 3, }, maxAllowedGapInMs: collectingPeriodInMs * 4, }, inboundTrackWindow: monitorConfig.inboundTrackWindow ?? { numberOfSamples: { detection: 3, recovery: 3, flowDetection: 4, flowRecovery: 3, }, maxAllowedGapInMs: collectingPeriodInMs * 4, }, peerConnectionWindow: monitorConfig.peerConnectionWindow ?? { numberOfSamples: { detection: 3, recovery: 3, }, maxAllowedGapInMs: collectingPeriodInMs * 4, }, clientWindow: monitorConfig.clientWindow ?? { numberOfSamples: { detection: 3, recovery: 3, }, maxAllowedGapInMs: collectingPeriodInMs * 4, }, // Detector defaults, one entry per detector, grouped as in // 'ClientMonitorConfig' so the two files read side by side. // Connectivity — layer 1: reachability. iceReachabilityDetector: detectorDefault(monitorConfig.iceReachabilityDetector, { thresholdInMs: 6000, }), // Layer 2 — traversal. Telemetry, nothing to tune. iceTraversalDetector: detectorDefault(monitorConfig.iceTraversalDetector, {}), // Layer 3 — path establishment: slow, then demonstrably failed. icePathEstablishmentDetector: detectorDefault(monitorConfig.icePathEstablishmentDetector, { thresholdInMs: 5000, createEvent: true, }), iceEstablishmentFailedDetector: detectorDefault(monitorConfig.iceEstablishmentFailedDetector, { thresholdInMs: 15000, }), // Layer 4 — secure transport. 'failed' is terminal, so no threshold. dtlsHandshakeFailedDetector: detectorDefault(monitorConfig.dtlsHandshakeFailedDetector, {}), dtlsHandshakeStalledDetector: detectorDefault(monitorConfig.dtlsHandshakeStalledDetector, { stalledThresholdInMs: 6000, }), // Layer 5 — path continuity: down, finished, delivering nothing, // or never settling. iceDisconnectedDetector: detectorDefault(monitorConfig.iceDisconnectedDetector, { disconnectedThresholdInMs: 5000, }), iceConnectionFailedDetector: detectorDefault(monitorConfig.iceConnectionFailedDetector, {}), iceTransportStalledDetector: detectorDefault(monitorConfig.iceTransportStalledDetector, { transportStallThresholdInMs: 5000, }), unstableIcePathDetector: detectorDefault(monitorConfig.unstableIcePathDetector, { pathSwitchWindowInMs: 30000, pathSwitchThreshold: 3, }), // Connectivity telemetry. Recommendation thresholds sit wider than // the issue thresholds beside them, on purpose. iceRestartDetector: detectorDefault(monitorConfig.iceRestartDetector, { createEvent: true, }), iceRestartRecommendationDetector: detectorDefault(monitorConfig.iceRestartRecommendationDetector, { createEvent: true, iceRestartRecommendationThresholdInMs: 10000, iceRestartRecommendationCooldownInMs: 15000, restartRecommendationThresholdInMs: 10000, restartRecommendationCooldownInMs: 15000, }), // Transport Quality — the properties of a working path. These // thresholds are starting points, meant to be tuned against a fleet. // Deprecated, on by default so integrations built against the 'congestion' event keep // working. Set to 'null' once nothing depends on it. congestionDetector: detectorDefault(monitorConfig.congestionDetector, { sensitivity: 'medium' as const, }), uplinkCongestionDetector: detectorDefault(monitorConfig.uplinkCongestionDetector, { minSeverity: 0.65, // Four times the connection's own median pacer delay tops the scale. pacerBloatingSaturatesAt: 4, }), downlinkCongestionDetector: detectorDefault(monitorConfig.downlinkCongestionDetector, { minSeverity: 0.65, // Four times the connection's own median jitter buffer delay tops the scale. bufferBloatingSaturatesAt: 4, }), transportDelayDetector: detectorDefault(monitorConfig.transportDelayDetector, { // ~300ms round trip is where turn-taking starts to break down. thresholdInMs: 300, recoveryThresholdInMs: 200, // The sustain lives in 'peerConnectionWindow', not here. }), transportLossDetector: detectorDefault(monitorConfig.transportLossDetector, { threshold: 0.05, recoveryThreshold: 0.01, durationInMs: 6000, }), blockedStunRequestsDetector: detectorDefault(monitorConfig.blockedStunRequestsDetector, { responseReceivedTimeoutInMs: 10000, requestsSentTimeoutInMs: 10000, }), blockedOutboundMediaDetector: detectorDefault(monitorConfig.blockedOutboundMediaDetector, { thresholdInMs: 10000, }), // Defaults to 'null': its premise fails wherever rtcp-mux is in // force, which is every browser. See 'ClientMonitorConfig'. blockedInboundMediaDetector: detectorDefault(monitorConfig.blockedInboundMediaDetector, null), // Pipeline Disruption — the send chain, from the capture device to // the wire. captureSourceLostDetector: detectorDefault(monitorConfig.captureSourceLostDetector, { createEvent: true, }), silentAudioSourceDetector: detectorDefault(monitorConfig.silentAudioSourceDetector, { silenceThresholdInMs: 60000, silenceRmsThreshold: 0.0001, recoveryRmsThreshold: 0.0003, }), videoCaptureBottleneckDetector: detectorDefault(monitorConfig.videoCaptureBottleneckDetector, { produceDegradationThreshold: 0.2, }), encoderBottleneckDetector: detectorDefault(monitorConfig.encoderBottleneckDetector, { encodeDegradationThreshold: 0.3, }), rtpSenderStalledDetector: detectorDefault(monitorConfig.rtpSenderStalledDetector, { thresholdInMs: 4000, }), dryOutboundTrackDetector: detectorDefault(monitorConfig.dryOutboundTrackDetector, { thresholdInMs: 5000, }), // Pipeline Disruption — the receive chain, from the transport to the // renderer. transportDemuxStalledDetector: detectorDefault(monitorConfig.transportDemuxStalledDetector, { thresholdInMs: 4000, minTransportReceiveBitrateBps: 20000, }), dryInboundTrackDetector: detectorDefault(monitorConfig.dryInboundTrackDetector, { thresholdInMs: 5000, }), frameAssemblyStalledDetector: detectorDefault(monitorConfig.frameAssemblyStalledDetector, { thresholdInMs: 3000, minPacketsReceived: 20, }), decoderBottleneckDetector: detectorDefault(monitorConfig.decoderBottleneckDetector, { // 0.1 is the old decodeFpsRatioThreshold of 0.9, read as a shortfall. decodeDegradationThreshold: 0.1, minReceivedFps: 5, }), decoderPerformanceDetector: detectorDefault(monitorConfig.decoderPerformanceDetector, { decodeTimeBudgetRatio: 0.8, minFramesReceived: 10, quietLossThreshold: 0.02, minConsecutiveTicks: 2, }), stuckDecoderDetector: detectorDefault(monitorConfig.stuckDecoderDetector, { thresholdInMs: 4000, rttMultiplier: 15, minBitrate: 10000, minPliCount: 2, }), playoutDiscrepancyDetector: detectorDefault(monitorConfig.playoutDiscrepancyDetector, { lowSkewRatio: 0.1, highSkewRatio: 0.25, minFramesReceived: 10, }), // Pipeline Disruption — the repair loop beside the receive chain, and // the machine behind both chains. videoRecoveryFailedDetector: detectorDefault(monitorConfig.videoRecoveryFailedDetector, { recoveryFailedThresholdInMs: 5000, recoveryFailedMinPliCount: 2, }), cpuPerformanceDetector: detectorDefault(monitorConfig.cpuPerformanceDetector, { utilizationThreshold: 0.5, recoveryThreshold: 0.4, }), // Perceived Quality — how the picture and the sound come across. pixelatedVideoDetector: detectorDefault(monitorConfig.pixelatedVideoDetector, { // Fractions of the codec's own quantizer scale, so one pair covers every codec. // 0.62 is a mean quantizer of 79 on VP8 and 32 on H.264, either of which is // visibly coarse; 0.52 is 66 and 27, which is not. Starting points to calibrate // against a fleet, not findings. threshold: 0.62, recoveryThreshold: 0.52, durationInMs: 8000, }), inboundVideoFlowStateDetector: detectorDefault(monitorConfig.inboundVideoFlowStateDetector, { frozenAfterInMs: 2000, minFreezeCountForChoppy: 2, // The stretch both verdicts are measured over is the track's shared window, not a // duration here: see 'inboundTrackWindow'. }), inventedSpeechDetector: detectorDefault(monitorConfig.inventedSpeechDetector, { // Share of concealed audio tolerated before it counts against the budget. allowedInventedRatio: 0.05, // Invented audio beyond the allowance, in ms, that opens the issue. raiseAfterInventedMs: 400, }), audioPlayoutSynthesisDetector: detectorDefault(monitorConfig.audioPlayoutSynthesisDetector, { // A share of what was played, not a duration per collection. The previous // 'minSynthesizedSamplesDuration: 0' reported on every tick that concealed anything // at all, and its unit was seconds while the config documented milliseconds. synthesizedRatioThreshold: 0.05, createEvent: true, }), // Raise at the acceptability limits, resolve back inside the // detectability ones; audio behind video is forgiven further. avDesyncPlayoutDetector: detectorDefault(monitorConfig.avDesyncPlayoutDetector, { audioAheadRaiseInMs: 90, audioAheadResolveInMs: 45, audioBehindRaiseInMs: 185, audioBehindResolveInMs: 125, sustainForInMs: 3000, }), jitterBufferStressDetector: detectorDefault(monitorConfig.jitterBufferStressDetector, { targetDelayThresholdInMs: 200, timeStretchThreshold: 0.02, minConsecutiveTicks: 2, // Severity scale only, and absolute rather than relative to the thresholds above: // a second of buffering makes conversation impossible, and a seventh of the samples // warped is badly distorted speech. The thresholds land near 0.16 on that scale. unbearableTargetDelayInMs: 1000, unbearableTimeStretchRate: 0.15, }), // Telemetry — facts about the session, not faults. captureTrackMutedDetector: detectorDefault(monitorConfig.captureTrackMutedDetector, { createEvent: true, }), codecChangeDetector: detectorDefault(monitorConfig.codecChangeDetector, { createEvent: true, }), videoResolutionChangeDetector: detectorDefault(monitorConfig.videoResolutionChangeDetector, { createEvent: true, }), simulcastLayerDetector: detectorDefault(monitorConfig.simulcastLayerDetector, { createEvent: true, }), statsGapDetector: detectorDefault(monitorConfig.statsGapDetector, { gapRatioThreshold: 2, minGapInMs: 5000, createEvent: true, }), bufferingEventsForSamples: monitorConfig.bufferingEventsForSamples ?? false, bufferClientSamplesUntilSubscriber: monitorConfig.bufferClientSamplesUntilSubscriber ?? false, sendResolvedIssuesToServer: monitorConfig.sendResolvedIssuesToServer ?? true, sendScoreReasonsToServer: monitorConfig.sendScoreReasonsToServer ?? true, sendIceTransportMetadataOnChangeOnly: monitorConfig.sendIceTransportMetadataOnChangeOnly ?? true, appData: monitorConfig.appData ?? {} as AppData, } - slicedWindow L437:
this.slicedWindow = new SlicedWindow({ maxAllowedGapInMs: this.config.clientWindow.maxAllowedGapInMs, totals: { totalVideoEncodeTimeInMs: null, totalVideoDecodeTimeInMs: null, }, slices: { detection: { numberOfSamples: this.config.clientWindow.numberOfSamples.detection, }, recovery: { numberOfSamples: this.config.clientWindow.numberOfSamples.recovery, offset: this.config.clientWindow.numberOfSamples.detection, }, }, }) - scoreCalculator L455:
this.scoreCalculator = new DefaultScoreCalculator(this) - activeIssues L482:
this.activeIssues = new IssueRegistry({ notify: (issue) => this.addIssue(issue), raise: (input) => this._raiseIssue(input), update: (input) => this._updateIssue(input), resolve: (input) => this._resolveIssue(input), }) - detectors L489:
this.detectors = new Detectors() - config.clientId L500:
this.config.clientId = clientId - config.callId L505:
this.config.callId = callId - config.appData L509:
this.config.appData = appData - closed L580:
this.closed = true - lastCollectingStatsAt L617:
this.lastCollectingStatsAt = Date.now() - sendingAudioBitrate L640:
this.sendingAudioBitrate = this.peerConnections.reduce((acc, peerConnection) => acc + (peerConnection.sendingAudioBitrate ?? 0), 0) - sendingVideoBitrate L641:
this.sendingVideoBitrate = this.peerConnections.reduce((acc, peerConnection) => acc + (peerConnection.sendingVideoBitrate ?? 0), 0) - receivingAudioBitrate L642:
this.receivingAudioBitrate = this.peerConnections.reduce((acc, peerConnection) => acc + (peerConnection.receivingAudioBitrate ?? 0), 0) - receivingVideoBitrate L643:
this.receivingVideoBitrate = this.peerConnections.reduce((acc, peerConnection) => acc + (peerConnection.receivingVideoBitrate ?? 0), 0) - totalAvailableIncomingBitrate L644:
this.totalAvailableIncomingBitrate = this.peerConnections.reduce((acc, peerConnection) => acc + (peerConnection.totalAvailableIncomingBitrate ?? 0), 0) - totalAvailableOutgoingBitrate L645:
this.totalAvailableOutgoingBitrate = this.peerConnections.reduce((acc, peerConnection) => acc + (peerConnection.totalAvailableOutgoingBitrate ?? 0), 0) - avgRttInSec L647:
this.avgRttInSec = 0 < this.peerConnections.length ? this.peerConnections.reduce((acc, peerConnection) => acc + (peerConnection.avgRttInSec ?? 0), 0) / this.peerConnections.length : -1 - durationOfCollectingStatsInMs L650:
this.durationOfCollectingStatsInMs = Date.now() - this.lastCollectingStatsAt - score L729:
this.score = score - scoreReasons L730:
this.scoreReasons = ownReasons - lastSampledAt L764:
this.lastSampledAt = timestamp - config.collectingPeriodInMs L1200:
this.config.collectingPeriodInMs = collectingPeriodInMs - config.samplingPeriodInMs L1214:
this.config.samplingPeriodInMs = samplingPeriodInMs
Exact wire projection
public createSample(): ClientSample | undefined {
if (this.closed) return;
const clientSample: ClientSample = {
clientId: this.clientId,
timestamp: Date.now(),
callId: this.callId,
attachments: this.attachments,
peerConnections: this.peerConnections.map(peerConnection => peerConnection.createSample()),
clientEvents: this._clientEvents,
clientMetaItems: this._clientMetaItems,
clientIssues: this._clientIssues,
extensionStats: this._extensionStats,
score: this.score,
// The client's own reasons only; the aggregate lives on the 'score' event.
scoreReasons: sampledScoreReasons(this.scoreReasons, this.config.sendScoreReasonsToServer),
};
this._clientEvents = [];
this._clientMetaItems = [];
this._clientIssues = [];
this._extensionStats = [];
const timestamp = Date.now();
if (!clientSample) {
return;
}
this.lastSampledAt = timestamp;
if (this._bufferedClientSamples) {
if (this.listenerCount('sample-created') === 0) {
this._bufferedClientSamples.push(clientSample);
} else {
this._flushBufferedClientSamples();
}
}
this.emit('sample-created', {
clientMonitor: this,
sample: clientSample
});
return clientSample;
}CertificateMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
timestamp | number | L7 |
id | string | L8 |
fingerprint | string / undefined | L9 |
fingerprintAlgorithm | string / undefined | L10 |
base64Certificate | string / undefined | L11 |
issuerCertificateId | string / undefined | L12 |
attachments | Record<string, unknown> / undefined | L17 |
appData | Record<string, unknown> / undefined | L22 |
visited | boolean | L35 |
Assignment and formula index
Exact wire projection
public createSample(): CertificateStats {
return {
id: this.id,
timestamp: this.timestamp,
fingerprint: this.fingerprint,
fingerprintAlgorithm: this.fingerprintAlgorithm,
base64Certificate: this.base64Certificate,
issuerCertificateId: this.issuerCertificateId,
attachments: this.attachments,
};
}CodecMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
timestamp | number | L7 |
id | string | L8 |
payloadType | number | L9 |
transportId | string | L10 |
mimeType | string | L11 |
clockRate | number / undefined | L12 |
channels | number / undefined | L13 |
sdpFmtpLine | string / undefined | L14 |
attachments | Record<string, unknown> / undefined | L19 |
appData | Record<string, unknown> / undefined | L24 |
visited | boolean | L37 |
Assignment and formula index
- id L30:
this.id = options.id - timestamp L31:
this.timestamp = options.timestamp - mimeType L32:
this.mimeType = options.mimeType
Exact wire projection
public createSample(): CodecStats {
return {
id: this.id,
timestamp: this.timestamp,
payloadType: this.payloadType,
transportId: this.transportId,
mimeType: this.mimeType,
clockRate: this.clockRate,
channels: this.channels,
sdpFmtpLine: this.sdpFmtpLine,
attachments: this.attachments,
};
}DataChannelMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
timestamp | number | L8 |
id | string | L9 |
label | string / undefined | L10 |
protocol | string / undefined | L11 |
dataChannelIdentifier | number / undefined | L12 |
state | string / undefined | L13 |
messagesSent | number / undefined | L14 |
bytesSent | number / undefined | L15 |
messagesReceived | number / undefined | L16 |
bytesReceived | number / undefined | L17 |
deltaBytesSent | number / undefined | L19 |
deltaBytesReceived | number / undefined | L20 |
sendingBitrate | number / undefined | L22 |
receivingBitrate | number / undefined | L23 |
attachments | Record<string, unknown> / undefined | L25 |
appData | Record<string, unknown> / undefined | L27 |
visited | boolean | L45 |
Assignment and formula index
- id L33:
this.id = options.id - timestamp L34:
this.timestamp = options.timestamp - deltaBytesReceived L63:
this.deltaBytesReceived = positiveDelta(stats.bytesReceived, this.bytesReceived) - deltaBytesSent L64:
this.deltaBytesSent = positiveDelta(stats.bytesSent, this.bytesSent) - sendingBitrate L67:
this.sendingBitrate = Math.max(0, this.deltaBytesSent * 8 / elapsedInSec) - receivingBitrate L71:
this.receivingBitrate = Math.max(0, this.deltaBytesReceived * 8 / elapsedInSec)
Exact wire projection
public createSample(): DataChannelStats {
return {
id: this.id,
timestamp: this.timestamp,
label: this.label,
protocol: this.protocol,
dataChannelIdentifier: this.dataChannelIdentifier,
state: this.state,
messagesSent: this.messagesSent,
bytesSent: this.bytesSent,
messagesReceived: this.messagesReceived,
bytesReceived: this.bytesReceived,
attachments: this.attachments,
};
}ExtensionStatsMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
visited | public visited = true; | L17 |
payload | Record<string, unknown> | L20 |
timestamp | public timestamp = Date.now(); | L23 |
Assignment and formula index
- visited L34:
this.visited = true - payload L35:
this.payload = payload - timestamp L36:
this.timestamp = Date.now()
IceCandidateMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
timestamp | number | L15 |
id | string | L16 |
transportId | string / undefined | L17 |
address | string / undefined | L18 |
port | number / undefined | L19 |
protocol | string / undefined | L20 |
candidateType | string / undefined | L21 |
priority | number / undefined | L22 |
url | string / undefined | L23 |
relayProtocol | string / undefined | L24 |
foundation | string / undefined | L25 |
relatedAddress | string / undefined | L26 |
relatedPort | number / undefined | L27 |
usernameFragment | string / undefined | L28 |
tcpType | string / undefined | L29 |
direction | ’local’ / ‘remote’ | L32 |
attachments | Record<string, unknown> / undefined | L35 |
appData | Record<string, unknown> / undefined | L37 |
visited | boolean | L49 |
isRelay | boolean | L80 |
turnTransport | IceRelayProtocol / undefined | L85 |
turnServer | string / undefined | L100 |
addressFamily | IceAddressFamily / undefined | L108 |
Assignment and formula index
Exact wire projection
public createSample(): IceCandidateStats {
return {
id: this.id,
timestamp: this.timestamp,
transportId: this.transportId,
address: this.address,
port: this.port,
protocol: this.protocol,
candidateType: this.candidateType,
priority: this.priority,
url: this.url,
relayProtocol: this.relayProtocol,
foundation: this.foundation,
relatedAddress: this.relatedAddress,
relatedPort: this.relatedPort,
usernameFragment: this.usernameFragment,
tcpType: this.tcpType,
attachments: this.attachments,
};
}IceCandidatePairMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
id | string | L18 |
timestamp | number | L19 |
transportId | string / undefined | L20 |
localCandidateId | string / undefined | L21 |
remoteCandidateId | string / undefined | L22 |
state | "new" / "in-progress" / "failed" / "waiting" / "succeeded" / undefined | L23 |
nominated | boolean / undefined | L24 |
packetsSent | number / undefined | L25 |
packetsReceived | number / undefined | L26 |
bytesSent | number / undefined | L27 |
bytesReceived | number / undefined | L28 |
lastPacketSentTimestamp | number / undefined | L29 |
lastPacketReceivedTimestamp | number / undefined | L30 |
totalRoundTripTime | number / undefined | L31 |
currentRoundTripTime | number / undefined | L32 |
availableOutgoingBitrate | number / undefined | L33 |
availableIncomingBitrate | number / undefined | L34 |
requestsReceived | number / undefined | L35 |
requestsSent | number / undefined | L36 |
responsesReceived | number / undefined | L37 |
responsesSent | number / undefined | L38 |
consentRequestsSent | number / undefined | L39 |
packetsDiscardedOnSend | number / undefined | L40 |
bytesDiscardedOnSend | number / undefined | L41 |
deltaPacketsSent | number / undefined | L43 |
deltaPacketsReceived | number / undefined | L44 |
deltaBytesSent | number / undefined | L45 |
deltaBytesReceived | number / undefined | L46 |
deltaTotalRoundTripTime | number / undefined | L47 |
deltaRequestsSent | number / undefined | L48 |
deltaConsentRequestsSent | number / undefined | L53 |
deltaResponsesReceived | number / undefined | L54 |
deltaPacketsDiscardedOnSend | number / undefined | L59 |
deltaBytesDiscardedOnSend | number / undefined | L61 |
deltaTime | number / undefined | L64 |
avgRoundTripTimeInSec | number / undefined | L70 |
attachments | Record<string, unknown> / undefined | L73 |
appData | Record<string, unknown> / undefined | L75 |
visited | boolean | L87 |
statsClockTime | public statsClockTime = 0; | L136 |
pathKey | string | L159 |
usingTurn | boolean | L164 |
usingTcp | boolean | L172 |
relayProtocol | IceRelayProtocol / undefined | L177 |
turnUrl | string / undefined | L182 |
turnServer | string / undefined | L187 |
pathKind | IcePathKind | L191 |
tuple | string | L207 |
Assignment and formula index
- id L81:
this.id = options.id - timestamp L82:
this.timestamp = options.timestamp - deltaTime L102:
this.deltaTime = elapsedInMs - statsClockTime L103:
this.statsClockTime += elapsedInMs - deltaPacketsSent L106:
this.deltaPacketsSent = positiveDelta(stats.packetsSent, this.packetsSent) - deltaPacketsReceived L107:
this.deltaPacketsReceived = positiveDelta(stats.packetsReceived, this.packetsReceived) - deltaBytesSent L108:
this.deltaBytesSent = positiveDelta(stats.bytesSent, this.bytesSent) - deltaBytesReceived L109:
this.deltaBytesReceived = positiveDelta(stats.bytesReceived, this.bytesReceived) - deltaTotalRoundTripTime L111:
this.deltaTotalRoundTripTime = positiveDelta(stats.totalRoundTripTime, this.totalRoundTripTime) - deltaResponsesReceived L112:
this.deltaResponsesReceived = positiveDelta(stats.responsesReceived, this.responsesReceived) - deltaRequestsSent L113:
this.deltaRequestsSent = positiveDelta(stats.requestsSent, this.requestsSent) - deltaConsentRequestsSent L114:
this.deltaConsentRequestsSent = positiveDelta(stats.consentRequestsSent, this.consentRequestsSent) - deltaPacketsDiscardedOnSend L115:
this.deltaPacketsDiscardedOnSend = positiveDelta(stats.packetsDiscardedOnSend, this.packetsDiscardedOnSend) - deltaBytesDiscardedOnSend L116:
this.deltaBytesDiscardedOnSend = positiveDelta(stats.bytesDiscardedOnSend, this.bytesDiscardedOnSend) - avgRoundTripTimeInSec L117:
this.avgRoundTripTimeInSec = this.deltaTotalRoundTripTime !== undefined && this.deltaResponsesReceived !== undefined && this.deltaResponsesReceived > 0 ? this.deltaTotalRoundTripTime / this.deltaResponsesReceived : undefined - availableOutgoingBitrate L127:
this.availableOutgoingBitrate = stats.availableOutgoingBitrate - availableIncomingBitrate L128:
this.availableIncomingBitrate = stats.availableIncomingBitrate
Exact wire projection
public createSample(): IceCandidatePairStats {
return {
id: this.id,
timestamp: this.timestamp,
transportId: this.transportId,
localCandidateId: this.localCandidateId,
remoteCandidateId: this.remoteCandidateId,
state: this.state,
nominated: this.nominated,
packetsSent: this.packetsSent,
packetsReceived: this.packetsReceived,
bytesSent: this.bytesSent,
bytesReceived: this.bytesReceived,
lastPacketSentTimestamp: this.lastPacketSentTimestamp,
lastPacketReceivedTimestamp: this.lastPacketReceivedTimestamp,
totalRoundTripTime: this.totalRoundTripTime,
currentRoundTripTime: this.currentRoundTripTime,
availableOutgoingBitrate: this.availableOutgoingBitrate,
availableIncomingBitrate: this.availableIncomingBitrate,
requestsReceived: this.requestsReceived,
requestsSent: this.requestsSent,
responsesReceived: this.responsesReceived,
responsesSent: this.responsesSent,
consentRequestsSent: this.consentRequestsSent,
packetsDiscardedOnSend: this.packetsDiscardedOnSend,
bytesDiscardedOnSend: this.bytesDiscardedOnSend,
attachments: this.attachments,
};
}IceTransportMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
detectors | Detectors | L24 |
issues | IssueRegistry<IceTransportIssues> | L31 |
timestamp | number | L33 |
id | string | L34 |
packetsSent | number / undefined | L35 |
packetsReceived | number / undefined | L36 |
bytesSent | number / undefined | L37 |
bytesReceived | number / undefined | L38 |
iceRole | string / undefined | L39 |
iceLocalUsernameFragment | string / undefined | L40 |
dtlsState | string / undefined | L41 |
iceState | string / undefined | L42 |
selectedCandidatePairId | string / undefined | L43 |
localCertificateId | string / undefined | L44 |
remoteCertificateId | string / undefined | L45 |
tlsVersion | string / undefined | L46 |
dtlsCipher | string / undefined | L47 |
dtlsRole | string / undefined | L48 |
srtpCipher | string / undefined | L49 |
selectedCandidatePairChanges | number / undefined | L50 |
ccfbMessagesSent | number / undefined | L51 |
ccfbMessagesReceived | number / undefined | L52 |
deltaPacketsSent | number / undefined | L54 |
deltaPacketsReceived | number / undefined | L55 |
deltaBytesSent | number / undefined | L56 |
deltaBytesReceived | number / undefined | L57 |
sendingBitrate | number / undefined | L58 |
receivingBitrate | number / undefined | L59 |
deltaSelectedCandidatePairChanges | number / undefined | L64 |
deltaTime | number / undefined | L67 |
everConnected | everConnected = false; | L73 |
blocked | public blocked = false; | L80 |
attachments | Record<string, unknown> / undefined | L83 |
appData | Record<string, unknown> / undefined | L85 |
visited | boolean | L106 |
statsClockTime | public statsClockTime = 0; | L119 |
Assignment and formula index
- id L91:
this.id = options.id - timestamp L92:
this.timestamp = options.timestamp - issues L96:
this.issues = new IssueRegistry<IceTransportIssues>( this._peerConnection.issues.asSink, ) - detectors L99:
this.detectors = new Detectors() - deltaTime L157:
this.deltaTime = elapsedInMs - statsClockTime L158:
this.statsClockTime += elapsedInMs - everConnected L161:
this.everConnected = true - deltaPacketsSent L165:
this.deltaPacketsSent = stats.packetsSent - this.packetsSent - deltaPacketsSent L167:
this.deltaPacketsSent = undefined - deltaPacketsReceived L170:
this.deltaPacketsReceived = stats.packetsReceived - this.packetsReceived - deltaPacketsReceived L172:
this.deltaPacketsReceived = undefined - deltaBytesSent L175:
this.deltaBytesSent = stats.bytesSent - this.bytesSent - sendingBitrate L176:
this.sendingBitrate = (this.deltaBytesSent * 8) / elapsedInSec - deltaBytesSent L178:
this.deltaBytesSent = undefined - sendingBitrate L179:
this.sendingBitrate = undefined - deltaBytesReceived L182:
this.deltaBytesReceived = stats.bytesReceived - this.bytesReceived - receivingBitrate L183:
this.receivingBitrate = (this.deltaBytesReceived * 8) / elapsedInSec - deltaBytesReceived L185:
this.deltaBytesReceived = undefined - receivingBitrate L186:
this.receivingBitrate = undefined - deltaSelectedCandidatePairChanges L191:
this.deltaSelectedCandidatePairChanges = this.selectedCandidatePairId !== undefined ? positiveDelta(stats.selectedCandidatePairChanges, this.selectedCandidatePairChanges) : undefined
Exact wire projection
public createSample(): IceTransportStats {
// Constant after the handshake, so emitted in the first sample and again only on change
// (the ufrag changes exactly at an ICE restart).
const staticMetadata: Pick<IceTransportStats,
'iceRole' | 'iceLocalUsernameFragment' | 'localCertificateId' | 'remoteCertificateId'
| 'tlsVersion' | 'dtlsCipher' | 'dtlsRole' | 'srtpCipher'> = {
iceRole: this.iceRole,
iceLocalUsernameFragment: this.iceLocalUsernameFragment,
localCertificateId: this.localCertificateId,
remoteCertificateId: this.remoteCertificateId,
tlsVersion: this.tlsVersion,
dtlsCipher: this.dtlsCipher,
dtlsRole: this.dtlsRole,
srtpCipher: this.srtpCipher,
};
let sampledStaticMetadata: typeof staticMetadata | undefined = staticMetadata;
if (this._peerConnection.parent.config.sendIceTransportMetadataOnChangeOnly) {
const fingerprint = [
this.iceRole, this.iceLocalUsernameFragment, this.localCertificateId, this.remoteCertificateId,
this.tlsVersion, this.dtlsCipher, this.dtlsRole, this.srtpCipher,
].join('|');
if (this._sampledStaticMetadataFingerprint === fingerprint) {
sampledStaticMetadata = undefined;
} else {
this._sampledStaticMetadataFingerprint = fingerprint;
}
}
return {
id: this.id,
timestamp: this.timestamp,
packetsSent: this.packetsSent,
packetsReceived: this.packetsReceived,
bytesSent: this.bytesSent,
bytesReceived: this.bytesReceived,
dtlsState: this.dtlsState,
iceState: this.iceState,
selectedCandidatePairId: this.selectedCandidatePairId,
selectedCandidatePairChanges: this.selectedCandidatePairChanges,
ccfbMessagesSent: this.ccfbMessagesSent,
ccfbMessagesReceived: this.ccfbMessagesReceived,
attachments: this.attachments,
...(sampledStaticMetadata ?? {}),
};
}InboundRtpMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
addedAt | public addedAt = Date.now(); | L12 |
timestamp | number | L15 |
id | string | L16 |
ssrc | number | L17 |
kind | MediaKind | L18 |
trackIdentifier | string | L19 |
transportId | string / undefined | L20 |
codecId | string / undefined | L21 |
packetsReceived | number / undefined | L22 |
packetsReceivedWithEct1 | number / undefined | L23 |
packetsReceivedWithCe | number / undefined | L24 |
packetsReportedAsLost | number / undefined | L25 |
packetsReportedAsLostButRecovered | number / undefined | L26 |
packetsLost | number / undefined | L27 |
jitter | number / undefined | L28 |
mid | string / undefined | L29 |
remoteId | string / undefined | L30 |
framesDecoded | number / undefined | L31 |
keyFramesDecoded | number / undefined | L32 |
framesRendered | number / undefined | L33 |
framesDropped | number / undefined | L34 |
frameWidth | number / undefined | L35 |
frameHeight | number / undefined | L36 |
framesPerSecond | number / undefined | L37 |
qpSum | number / undefined | L38 |
totalDecodeTime | number / undefined | L39 |
totalInterFrameDelay | number / undefined | L40 |
totalSquaredInterFrameDelay | number / undefined | L41 |
pauseCount | number / undefined | L42 |
totalPausesDuration | number / undefined | L43 |
freezeCount | number / undefined | L44 |
totalFreezesDuration | number / undefined | L45 |
lastPacketReceivedTimestamp | number / undefined | L46 |
headerBytesReceived | number / undefined | L47 |
packetsDiscarded | number / undefined | L48 |
fecBytesReceived | number / undefined | L49 |
fecPacketsReceived | number / undefined | L50 |
fecPacketsDiscarded | number / undefined | L51 |
bytesReceived | number / undefined | L52 |
nackCount | number / undefined | L53 |
firCount | number / undefined | L54 |
pliCount | number / undefined | L55 |
totalProcessingDelay | number / undefined | L56 |
estimatedPlayoutTimestamp | number / undefined | L57 |
jitterBufferDelay | number / undefined | L58 |
jitterBufferTargetDelay | number / undefined | L59 |
jitterBufferEmittedCount | number / undefined | L60 |
jitterBufferMinimumDelay | number / undefined | L61 |
totalSamplesReceived | number / undefined | L62 |
concealedSamples | number / undefined | L63 |
silentConcealedSamples | number / undefined | L64 |
concealmentEvents | number / undefined | L65 |
insertedSamplesForDeceleration | number / undefined | L66 |
removedSamplesForAcceleration | number / undefined | L67 |
audioLevel | number / undefined | L68 |
totalAudioEnergy | number / undefined | L69 |
totalSamplesDuration | number / undefined | L70 |
framesReceived | number / undefined | L71 |
decoderImplementation | string / undefined | L72 |
playoutId | string / undefined | L73 |
powerEfficientDecoder | boolean / undefined | L74 |
framesAssembledFromMultiplePackets | number / undefined | L75 |
totalAssemblyTime | number / undefined | L76 |
retransmittedPacketsReceived | number / undefined | L77 |
retransmittedBytesReceived | number / undefined | L78 |
rtxSsrc | number / undefined | L79 |
fecSsrc | number / undefined | L80 |
totalCorruptionProbability | number / undefined | L81 |
totalSquaredCorruptionProbability | number / undefined | L82 |
corruptionMeasurements | number / undefined | L83 |
bitrate | number | L86 |
avgFramesPerSec | number | L87 |
fpsVolatility | number | L97 |
lastNFramesPerSec | number[] | L98 |
receivingAudioSamples | number | L99 |
totalFractionLost | number | L100 |
bitPerPixel | number | L101 |
packetRate | number / undefined | L102 |
ewmaFps | number | L103 |
deltaPacketsLost | number | L105 |
deltaPacketsReceived | number | L106 |
deltaBytesReceived | number | L107 |
deltaJitterBufferDelay | number | L108 |
deltaCorruptionProbability | number | L109 |
deltaFractionLost | number | L110 |
deltaFramesDecoded | number | L111 |
deltaQpSum | number / undefined | L112 |
avgQpPerFrame | number / undefined | L114 |
normalizedQp | number / undefined | L132 |
deltaFramesReceived | number | L133 |
deltaFramesRendered | number | L134 |
deltaTime | number | L135 |
deltaTotalSamplesReceived | number | L138 |
deltaConcealedSamples | number | L139 |
deltaSilentConcealedSamples | number | L140 |
deltaConcealmentEvents | number | L141 |
deltaInsertedSamplesForDeceleration | number | L142 |
deltaRemovedSamplesForAcceleration | number | L143 |
deltaPacketsDiscarded | number | L144 |
deltaJitterBufferEmittedCount | number | L145 |
deltaJitterBufferTargetDelay | number | L146 |
inventedSpeechRatio | number | L152 |
concealmentEventRate | number | L153 |
timeStretchRate | number | L155 |
avgJitterBufferDelayInMs | number | L156 |
jitterBufferTargetDelayInMs | number | L157 |
discardRate | number | L158 |
deltaFramesDropped | number | L161 |
deltaKeyFramesDecoded | number | L162 |
deltaTotalDecodeTime | number | L163 |
deltaTotalFreezesDuration | number | L164 |
deltaFreezeCount | number | L166 |
frozenTimeRatio | number | L171 |
deltaPauseCount | number | L177 |
deltaTotalPausesDuration | number | L178 |
pausedTimeRatio | number | L180 |
deltaTotalInterFrameDelay | number | L181 |
deltaTotalSquaredInterFrameDelay | number | L182 |
avgInterFrameDelayInMs | number | L184 |
interFrameDelayVariation | number | L191 |
deltaPliCount | number | L192 |
deltaFirCount | number | L193 |
deltaNackCount | number | L194 |
deltaRetransmittedBytesReceived | number | L195 |
deltaRetransmittedPacketsReceived | number | L196 |
retransmissionRatio | number | L198 |
decodeTimePerFrameInMs | number | L199 |
droppedFrameRatio | number | L200 |
renderRatio | number | L201 |
keyFrameRate | number | L202 |
pliRate | number | L203 |
firRate | number | L204 |
nackRate | number | L205 |
attachments | Record<string, unknown> / undefined | L208 |
appData | Record<string, unknown> / undefined | L210 |
visited | boolean | L303 |
statsClockTime | public statsClockTime = 0; | L316 |
Assignment and formula index
- id L216:
this.id = options.id - timestamp L217:
this.timestamp = options.timestamp - ssrc L218:
this.ssrc = options.ssrc - kind L219:
this.kind = options.kind as MediaKind - trackIdentifier L220:
this.trackIdentifier = options.trackIdentifier - timestamp L230:
this.timestamp = stats.timestamp - id L231:
this.id = stats.id - ssrc L232:
this.ssrc = stats.ssrc - kind L233:
this.kind = stats.kind as MediaKind - trackIdentifier L234:
this.trackIdentifier = stats.trackIdentifier - transportId L236:
this.transportId = stats.transportId - codecId L237:
this.codecId = stats.codecId - packetsReceived L238:
this.packetsReceived = stats.packetsReceived - packetsReceivedWithEct1 L239:
this.packetsReceivedWithEct1 = stats.packetsReceivedWithEct1 - packetsReceivedWithCe L240:
this.packetsReceivedWithCe = stats.packetsReceivedWithCe - packetsReportedAsLost L241:
this.packetsReportedAsLost = stats.packetsReportedAsLost - packetsReportedAsLostButRecovered L242:
this.packetsReportedAsLostButRecovered = stats.packetsReportedAsLostButRecovered - packetsLost L243:
this.packetsLost = stats.packetsLost - jitter L244:
this.jitter = stats.jitter - mid L245:
this.mid = stats.mid - remoteId L246:
this.remoteId = stats.remoteId - framesDecoded L247:
this.framesDecoded = stats.framesDecoded - keyFramesDecoded L248:
this.keyFramesDecoded = stats.keyFramesDecoded - framesRendered L249:
this.framesRendered = stats.framesRendered - framesDropped L250:
this.framesDropped = stats.framesDropped - frameWidth L251:
this.frameWidth = stats.frameWidth - frameHeight L252:
this.frameHeight = stats.frameHeight - framesPerSecond L253:
this.framesPerSecond = stats.framesPerSecond - qpSum L254:
this.qpSum = stats.qpSum - totalDecodeTime L255:
this.totalDecodeTime = stats.totalDecodeTime - totalInterFrameDelay L256:
this.totalInterFrameDelay = stats.totalInterFrameDelay - totalSquaredInterFrameDelay L257:
this.totalSquaredInterFrameDelay = stats.totalSquaredInterFrameDelay - pauseCount L258:
this.pauseCount = stats.pauseCount - totalPausesDuration L259:
this.totalPausesDuration = stats.totalPausesDuration - freezeCount L260:
this.freezeCount = stats.freezeCount - totalFreezesDuration L261:
this.totalFreezesDuration = stats.totalFreezesDuration - lastPacketReceivedTimestamp L262:
this.lastPacketReceivedTimestamp = stats.lastPacketReceivedTimestamp - headerBytesReceived L263:
this.headerBytesReceived = stats.headerBytesReceived - packetsDiscarded L264:
this.packetsDiscarded = stats.packetsDiscarded - fecBytesReceived L265:
this.fecBytesReceived = stats.fecBytesReceived - fecPacketsReceived L266:
this.fecPacketsReceived = stats.fecPacketsReceived - fecPacketsDiscarded L267:
this.fecPacketsDiscarded = stats.fecPacketsDiscarded - bytesReceived L268:
this.bytesReceived = stats.bytesReceived - nackCount L269:
this.nackCount = stats.nackCount - firCount L270:
this.firCount = stats.firCount - pliCount L271:
this.pliCount = stats.pliCount - totalProcessingDelay L272:
this.totalProcessingDelay = stats.totalProcessingDelay - estimatedPlayoutTimestamp L273:
this.estimatedPlayoutTimestamp = stats.estimatedPlayoutTimestamp - jitterBufferDelay L274:
this.jitterBufferDelay = stats.jitterBufferDelay - jitterBufferTargetDelay L275:
this.jitterBufferTargetDelay = stats.jitterBufferTargetDelay - jitterBufferEmittedCount L276:
this.jitterBufferEmittedCount = stats.jitterBufferEmittedCount - jitterBufferMinimumDelay L277:
this.jitterBufferMinimumDelay = stats.jitterBufferMinimumDelay - totalSamplesReceived L278:
this.totalSamplesReceived = stats.totalSamplesReceived - concealedSamples L279:
this.concealedSamples = stats.concealedSamples - silentConcealedSamples L280:
this.silentConcealedSamples = stats.silentConcealedSamples - concealmentEvents L281:
this.concealmentEvents = stats.concealmentEvents - insertedSamplesForDeceleration L282:
this.insertedSamplesForDeceleration = stats.insertedSamplesForDeceleration - removedSamplesForAcceleration L283:
this.removedSamplesForAcceleration = stats.removedSamplesForAcceleration - audioLevel L284:
this.audioLevel = stats.audioLevel - totalAudioEnergy L285:
this.totalAudioEnergy = stats.totalAudioEnergy - totalSamplesDuration L286:
this.totalSamplesDuration = stats.totalSamplesDuration - framesReceived L287:
this.framesReceived = stats.framesReceived - decoderImplementation L288:
this.decoderImplementation = stats.decoderImplementation - playoutId L289:
this.playoutId = stats.playoutId - powerEfficientDecoder L290:
this.powerEfficientDecoder = stats.powerEfficientDecoder - framesAssembledFromMultiplePackets L291:
this.framesAssembledFromMultiplePackets = stats.framesAssembledFromMultiplePackets - totalAssemblyTime L292:
this.totalAssemblyTime = stats.totalAssemblyTime - retransmittedPacketsReceived L293:
this.retransmittedPacketsReceived = stats.retransmittedPacketsReceived - retransmittedBytesReceived L294:
this.retransmittedBytesReceived = stats.retransmittedBytesReceived - rtxSsrc L295:
this.rtxSsrc = stats.rtxSsrc - fecSsrc L296:
this.fecSsrc = stats.fecSsrc - totalCorruptionProbability L297:
this.totalCorruptionProbability = stats.totalCorruptionProbability - totalSquaredCorruptionProbability L298:
this.totalSquaredCorruptionProbability = stats.totalSquaredCorruptionProbability - corruptionMeasurements L299:
this.corruptionMeasurements = stats.corruptionMeasurements - attachments L300:
this.attachments = stats.attachments - deltaTotalSamplesReceived L337:
this.deltaTotalSamplesReceived = positiveDelta(stats.totalSamplesReceived, this.totalSamplesReceived) - receivingAudioSamples L339:
this.receivingAudioSamples = this.deltaTotalSamplesReceived - deltaBytesReceived L342:
this.deltaBytesReceived = positiveDelta(stats.bytesReceived, this.bytesReceived) - bitrate L344:
this.bitrate = this.deltaBytesReceived === undefined ? undefined : Math.max(0, this.deltaBytesReceived * 8 / elapsedInSec) - deltaPacketsLost L349:
this.deltaPacketsLost = positiveDelta(stats.packetsLost, this.packetsLost) - deltaPacketsReceived L352:
this.deltaPacketsReceived = positiveDelta(stats.packetsReceived, this.packetsReceived) - packetRate L353:
this.packetRate = this.deltaPacketsReceived === undefined ? undefined : this.deltaPacketsReceived / elapsedInSec - deltaConcealedSamples L359:
this.deltaConcealedSamples = positiveDelta(stats.concealedSamples, this.concealedSamples) - deltaSilentConcealedSamples L360:
this.deltaSilentConcealedSamples = positiveDelta(stats.silentConcealedSamples, this.silentConcealedSamples) - deltaConcealmentEvents L361:
this.deltaConcealmentEvents = positiveDelta(stats.concealmentEvents, this.concealmentEvents) - deltaInsertedSamplesForDeceleration L362:
this.deltaInsertedSamplesForDeceleration = positiveDelta(stats.insertedSamplesForDeceleration, this.insertedSamplesForDeceleration) - deltaRemovedSamplesForAcceleration L363:
this.deltaRemovedSamplesForAcceleration = positiveDelta(stats.removedSamplesForAcceleration, this.removedSamplesForAcceleration) - deltaPacketsDiscarded L364:
this.deltaPacketsDiscarded = positiveDelta(stats.packetsDiscarded, this.packetsDiscarded) - deltaJitterBufferEmittedCount L365:
this.deltaJitterBufferEmittedCount = positiveDelta(stats.jitterBufferEmittedCount, this.jitterBufferEmittedCount) - inventedSpeechRatio L371:
this.inventedSpeechRatio = invented / (this.deltaTotalSamplesReceived as number) - inventedSpeechRatio L373:
this.inventedSpeechRatio = undefined - concealmentEventRate L375:
this.concealmentEventRate = this.deltaConcealmentEvents !== undefined ? this.deltaConcealmentEvents / elapsedInSec : undefined - timeStretchRate L381:
this.timeStretchRate = stretched / (this.deltaTotalSamplesReceived as number) - timeStretchRate L383:
this.timeStretchRate = undefined - discardRate L389:
this.discardRate = 0 < consumed ? this.deltaPacketsDiscarded / consumed : 0 - deltaCorruptionProbability L398:
this.deltaCorruptionProbability = Math.max( 0, deltaCorruption / deltaMeasurements ) - deltaJitterBufferDelay L404:
this.deltaJitterBufferDelay = positiveDelta(stats.jitterBufferDelay, this.jitterBufferDelay) - deltaFramesDecoded L405:
this.deltaFramesDecoded = positiveDelta(stats.framesDecoded, this.framesDecoded) - deltaFramesReceived L406:
this.deltaFramesReceived = positiveDelta(stats.framesReceived, this.framesReceived) - deltaFramesRendered L407:
this.deltaFramesRendered = positiveDelta(stats.framesRendered, this.framesRendered) - deltaFramesDropped L408:
this.deltaFramesDropped = positiveDelta(stats.framesDropped, this.framesDropped) - deltaKeyFramesDecoded L409:
this.deltaKeyFramesDecoded = positiveDelta(stats.keyFramesDecoded, this.keyFramesDecoded) - deltaQpSum L410:
this.deltaQpSum = positiveDelta(stats.qpSum, this.qpSum) - avgQpPerFrame L413:
this.avgQpPerFrame = this.deltaQpSum / this.deltaFramesDecoded - avgQpPerFrame L415:
this.avgQpPerFrame = undefined - normalizedQp L418:
this.normalizedQp = this._deriveNormalizedQp() - deltaTotalDecodeTime L419:
this.deltaTotalDecodeTime = positiveDelta(stats.totalDecodeTime, this.totalDecodeTime) - deltaTotalFreezesDuration L420:
this.deltaTotalFreezesDuration = positiveDelta(stats.totalFreezesDuration, this.totalFreezesDuration) - deltaFreezeCount L421:
this.deltaFreezeCount = positiveDelta(stats.freezeCount, this.freezeCount) - frozenTimeRatio L422:
this.frozenTimeRatio = this.deltaTotalFreezesDuration !== undefined && 0 < elapsedInSec ? this.deltaTotalFreezesDuration / elapsedInSec : undefined - deltaPauseCount L425:
this.deltaPauseCount = positiveDelta(stats.pauseCount, this.pauseCount) - deltaTotalPausesDuration L426:
this.deltaTotalPausesDuration = positiveDelta(stats.totalPausesDuration, this.totalPausesDuration) - pausedTimeRatio L427:
this.pausedTimeRatio = this.deltaTotalPausesDuration !== undefined && 0 < elapsedInSec ? this.deltaTotalPausesDuration / elapsedInSec : undefined - deltaTotalInterFrameDelay L430:
this.deltaTotalInterFrameDelay = positiveDelta(stats.totalInterFrameDelay, this.totalInterFrameDelay) - deltaTotalSquaredInterFrameDelay L431:
this.deltaTotalSquaredInterFrameDelay = positiveDelta(stats.totalSquaredInterFrameDelay, this.totalSquaredInterFrameDelay) - avgInterFrameDelayInMs L446:
this.avgInterFrameDelayInMs = mean * 1000 - interFrameDelayVariation L447:
this.interFrameDelayVariation = 0 < mean ? Math.sqrt(variance) / mean : undefined - avgInterFrameDelayInMs L449:
this.avgInterFrameDelayInMs = undefined - interFrameDelayVariation L450:
this.interFrameDelayVariation = undefined - deltaPliCount L452:
this.deltaPliCount = positiveDelta(stats.pliCount, this.pliCount) - deltaFirCount L453:
this.deltaFirCount = positiveDelta(stats.firCount, this.firCount) - deltaNackCount L454:
this.deltaNackCount = positiveDelta(stats.nackCount, this.nackCount) - deltaRetransmittedBytesReceived L455:
this.deltaRetransmittedBytesReceived = positiveDelta(stats.retransmittedBytesReceived, this.retransmittedBytesReceived) - deltaRetransmittedPacketsReceived L456:
this.deltaRetransmittedPacketsReceived = positiveDelta(stats.retransmittedPacketsReceived, this.retransmittedPacketsReceived) - retransmissionRatio L458:
this.retransmissionRatio = this.deltaRetransmittedBytesReceived !== undefined && 0 < (this.deltaBytesReceived ?? 0) ? Math.min(1, this.deltaRetransmittedBytesReceived / (this.deltaBytesReceived as number)) : undefined - avgJitterBufferDelayInMs L462:
this.avgJitterBufferDelayInMs = 0 < (this.deltaJitterBufferEmittedCount ?? 0) && this.deltaJitterBufferDelay !== undefined ? (this.deltaJitterBufferDelay / (this.deltaJitterBufferEmittedCount as number)) * 1000 : undefined - deltaJitterBufferTargetDelay L465:
this.deltaJitterBufferTargetDelay = positiveDelta(stats.jitterBufferTargetDelay, this.jitterBufferTargetDelay) - jitterBufferTargetDelayInMs L466:
this.jitterBufferTargetDelayInMs = 0 < (this.deltaJitterBufferEmittedCount ?? 0) && this.deltaJitterBufferTargetDelay !== undefined ? (this.deltaJitterBufferTargetDelay / (this.deltaJitterBufferEmittedCount as number)) * 1000 : undefined - decodeTimePerFrameInMs L471:
this.decodeTimePerFrameInMs = 0 < (this.deltaFramesDecoded ?? 0) && this.deltaTotalDecodeTime !== undefined ? (this.deltaTotalDecodeTime / (this.deltaFramesDecoded as number)) * 1000 : undefined - droppedFrameRatio L473:
this.droppedFrameRatio = 0 < (this.deltaFramesReceived ?? 0) && this.deltaFramesDropped !== undefined ? this.deltaFramesDropped / (this.deltaFramesReceived as number) : undefined - renderRatio L475:
this.renderRatio = 0 < (this.deltaFramesDecoded ?? 0) && this.deltaFramesRendered !== undefined ? this.deltaFramesRendered / (this.deltaFramesDecoded as number) : undefined - keyFrameRate L477:
this.keyFrameRate = this.deltaKeyFramesDecoded !== undefined ? this.deltaKeyFramesDecoded / elapsedInSec : undefined - pliRate L478:
this.pliRate = this.deltaPliCount !== undefined ? this.deltaPliCount / elapsedInSec : undefined - firRate L479:
this.firRate = this.deltaFirCount !== undefined ? this.deltaFirCount / elapsedInSec : undefined - nackRate L480:
this.nackRate = this.deltaNackCount !== undefined ? this.deltaNackCount / elapsedInSec : undefined - deltaTime L481:
this.deltaTime = elapsedInMs - statsClockTime L482:
this.statsClockTime += elapsedInMs - avgFramesPerSec L496:
this.avgFramesPerSec = avgFramesPerSec - fpsVolatility L497:
this.fpsVolatility = avgDiff / avgFramesPerSec - bitPerPixel L500:
this.bitPerPixel = this.bitrate / (this.frameWidth * this.frameHeight * this.framesPerSecond) - totalFractionLost L505:
this.totalFractionLost = 0 < this.packetsReceived && 0 < this.packetsLost ? (this.packetsLost) / (this.packetsLost + this.packetsReceived) : 0.0 - deltaFractionLost L509:
this.deltaFractionLost = 0 < this.deltaPacketsReceived && 0 < this.deltaPacketsLost ? (this.deltaPacketsLost) / (this.deltaPacketsLost + this.deltaPacketsReceived) : 0.0 - ewmaFps L513:
this.ewmaFps = this.ewmaFps ? 0.9 * this.ewmaFps + 0.1 * this.framesPerSecond : this.framesPerSecond
Exact wire projection
public createSample(): InboundRtpStats {
return {
timestamp: this.timestamp,
id: this.id,
ssrc: this.ssrc,
kind: this.kind,
trackIdentifier: this.trackIdentifier,
transportId: this.transportId,
codecId: this.codecId,
packetsReceived: this.packetsReceived,
packetsReceivedWithEct1: this.packetsReceivedWithEct1,
packetsReceivedWithCe: this.packetsReceivedWithCe,
packetsReportedAsLost: this.packetsReportedAsLost,
packetsReportedAsLostButRecovered: this.packetsReportedAsLostButRecovered,
packetsLost: this.packetsLost,
jitter: this.jitter,
mid: this.mid,
remoteId: this.remoteId,
framesDecoded: this.framesDecoded,
keyFramesDecoded: this.keyFramesDecoded,
framesRendered: this.framesRendered,
framesDropped: this.framesDropped,
frameWidth: this.frameWidth,
frameHeight: this.frameHeight,
framesPerSecond: this.framesPerSecond,
qpSum: this.qpSum,
totalDecodeTime: this.totalDecodeTime,
totalInterFrameDelay: this.totalInterFrameDelay,
totalSquaredInterFrameDelay: this.totalSquaredInterFrameDelay,
pauseCount: this.pauseCount,
totalPausesDuration: this.totalPausesDuration,
freezeCount: this.freezeCount,
totalFreezesDuration: this.totalFreezesDuration,
lastPacketReceivedTimestamp: this.lastPacketReceivedTimestamp,
headerBytesReceived: this.headerBytesReceived,
packetsDiscarded: this.packetsDiscarded,
fecBytesReceived: this.fecBytesReceived,
fecPacketsReceived: this.fecPacketsReceived,
fecPacketsDiscarded: this.fecPacketsDiscarded,
bytesReceived: this.bytesReceived,
nackCount: this.nackCount,
firCount: this.firCount,
pliCount: this.pliCount,
totalProcessingDelay: this.totalProcessingDelay,
estimatedPlayoutTimestamp: this.estimatedPlayoutTimestamp,
jitterBufferDelay: this.jitterBufferDelay,
jitterBufferTargetDelay: this.jitterBufferTargetDelay,
jitterBufferEmittedCount: this.jitterBufferEmittedCount,
jitterBufferMinimumDelay: this.jitterBufferMinimumDelay,
totalSamplesReceived: this.totalSamplesReceived,
concealedSamples: this.concealedSamples,
silentConcealedSamples: this.silentConcealedSamples,
concealmentEvents: this.concealmentEvents,
insertedSamplesForDeceleration: this.insertedSamplesForDeceleration,
removedSamplesForAcceleration: this.removedSamplesForAcceleration,
audioLevel: this.audioLevel,
totalAudioEnergy: this.totalAudioEnergy,
totalSamplesDuration: this.totalSamplesDuration,
framesReceived: this.framesReceived,
decoderImplementation: this.decoderImplementation,
playoutId: this.playoutId,
powerEfficientDecoder: this.powerEfficientDecoder,
framesAssembledFromMultiplePackets: this.framesAssembledFromMultiplePackets,
totalAssemblyTime: this.totalAssemblyTime,
retransmittedPacketsReceived: this.retransmittedPacketsReceived,
retransmittedBytesReceived: this.retransmittedBytesReceived,
rtxSsrc: this.rtxSsrc,
fecSsrc: this.fecSsrc,
totalCorruptionProbability: this.totalCorruptionProbability,
totalSquaredCorruptionProbability: this.totalSquaredCorruptionProbability,
corruptionMeasurements: this.corruptionMeasurements,
attachments: this.attachments,
}
}InboundTrackMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
CLEAN_QP_RATIO | public static CLEAN_QP_RATIO = 0.5; | L189 |
COARSE_QP_RATIO | public static COARSE_QP_RATIO = 0.8; | L190 |
direction | public readonly direction = ‘inbound’; | L192 |
detectors | Detectors | L193 |
issues | IssueRegistry<InboundTrackIssues> | L199 |
slicedWindow | SlicedWindow< | |
| InboundTrackWindowValues, | ||
| // A slice for every stretch the config sizes, so the names are declared once. Only the | ||
| // names matter here: how many samples each covers, and where it sits, are runtime. | ||
| Record<keyof InboundTrackWindowConfig[’numberOfSamples’], SliceConfig> | ||
| > | L210 | |
dtxMode | public dtxMode = false; | L218 |
paused | boolean | L229 |
remoteOutboundTrackPaused | boolean | L237 |
contentType | TrackContentType / undefined | L244 |
linkedVideoTrackId | string / undefined | L247 |
motionType | VideoMotionType / undefined | L250 |
presentedResolution | { width: number, height: number } / undefined | L253 |
videoTag | HTMLVideoElement / undefined | L256 |
linkedVideoPlayoutDiffInMs | number | L266 |
displayMagnification | number | L272 |
frameFlowState | InboundVideoFlowState | L283 |
degradedFrameSupply | boolean | L300 |
decodingDegradation | number | L308 |
quantizationDegradation | number | L345 |
synthesizedAudioRatio | number | L348 |
jitterBufferStressSeverity | number | L351 |
videoPlayoutSkew | number | L367 |
decodeBudgetUtilization | number | L370 |
inventedSpeechSeverity | number | L373 |
overloadedDecoder | boolean | L376 |
dry | boolean | L379 |
stalledFrameAssembly | boolean | L382 |
playoutDiscrepancy | boolean | L385 |
stuckedDecoder | boolean | L388 |
failedVideoRecovery | boolean | L391 |
calculatedScore | CalculatedScore | L393 |
score | public get score() { | L398 |
scoreReasons | public get scoreReasons() { | L402 |
attachments | Record<string, unknown> / undefined | L407 |
appData | Record<string, unknown> / undefined | L409 |
isScreenShare | public get isScreenShare() { | L531 |
readyState | MediaStreamTrack[‘readyState’] | L560 |
kind | public get kind() { | L568 |
bitrate | public get bitrate() { | L572 |
jitter | public get jitter() { | L576 |
fractionLost | public get fractionLost() { | L580 |
Assignment and formula index
- attachments L416:
this.attachments = attachments - issues L420:
this.issues = new IssueRegistry<InboundTrackIssues>( this.getPeerConnection().parent.activeIssues.asSink, ) - slicedWindow L427:
this.slicedWindow = new SlicedWindow({ maxAllowedGapInMs: windowConfig.maxAllowedGapInMs, totals: INBOUND_TRACK_WINDOW_VALUES, // Each recovery slice sits at its own detection slice's size, so it covers the stretch // that ends where that detection stretch begins. The two pairs are independent: a // detector reads one pair or the other, never one half of each. slices: { detection: { numberOfSamples: windowConfig.numberOfSamples.detection, }, recovery: { numberOfSamples: windowConfig.numberOfSamples.recovery, offset: windowConfig.numberOfSamples.detection, }, flowDetection: { numberOfSamples: windowConfig.numberOfSamples.flowDetection, }, flowRecovery: { numberOfSamples: windowConfig.numberOfSamples.flowRecovery, offset: windowConfig.numberOfSamples.flowDetection, }, }, }) - detectors L450:
this.detectors = new Detectors() - quantizationDegradation L613:
this.quantizationDegradation = normalizedQp === undefined || coarse <= clean ? undefined : clamp((normalizedQp - clean) / (coarse - clean), 0, 1) - displayMagnification L656:
this.displayMagnification = presented && 0 < presented.width && 0 < presented.height && decodedWidth && decodedHeight ? Math.sqrt((presented.width * presented.height) / (decodedWidth * decodedHeight)) : undefined - linkedVideoPlayoutDiffInMs L665:
this.linkedVideoPlayoutDiffInMs = undefined - linkedVideoPlayoutDiffInMs L675:
this.linkedVideoPlayoutDiffInMs = audioPlayout - videoPlayout
Exact wire projection
public createSample(): InboundTrackSample {
return {
id: this.track.id,
kind: this.track.kind,
timestamp: Date.now(),
attachments: this.attachments,
score: this.score,
scoreReasons: sampledScoreReasons(
this.calculatedScore.reasons,
this.getPeerConnection()?.parent.config.sendScoreReasonsToServer,
),
};
}MediaPlayoutMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
detectors | public readonly detectors = new Detectors(); | L14 |
timestamp | number | L16 |
id | string | L17 |
kind | MediaKind | L18 |
synthesizedSamplesDuration | number / undefined | L19 |
synthesizedSamplesEvents | number / undefined | L20 |
totalSamplesDuration | number / undefined | L21 |
totalPlayoutDelay | number / undefined | L22 |
totalSamplesCount | number / undefined | L23 |
deltaSynthesizedSamplesDuration | public deltaSynthesizedSamplesDuration = 0; | L25 |
deltaSamplesDuration | public deltaSamplesDuration = 0; | L26 |
deltaSynthesizedSamplesEvents | number / undefined | L27 |
deltaTotalPlayoutDelay | number / undefined | L28 |
deltaSamplesCount | number / undefined | L29 |
deltaTime | number / undefined | L32 |
playoutDelayPerSampleInMs | number / undefined | L36 |
synthesizedSamplesRatio | number / undefined | L39 |
attachments | Record<string, unknown> / undefined | L41 |
appData | Record<string, unknown> / undefined | L43 |
visited | boolean | L57 |
statsClockTime | public statsClockTime = 0; | L66 |
Assignment and formula index
- id L49:
this.id = options.id - timestamp L50:
this.timestamp = options.timestamp - kind L51:
this.kind = options.kind as MediaKind - deltaTime L79:
this.deltaTime = elapsedInMs - statsClockTime L80:
this.statsClockTime += elapsedInMs - deltaSynthesizedSamplesDuration L81:
this.deltaSynthesizedSamplesDuration = positiveDelta(stats.synthesizedSamplesDuration, this.synthesizedSamplesDuration) ?? 0 - deltaSamplesDuration L82:
this.deltaSamplesDuration = positiveDelta(stats.totalSamplesDuration, this.totalSamplesDuration) ?? 0 - deltaSynthesizedSamplesEvents L83:
this.deltaSynthesizedSamplesEvents = positiveDelta(stats.synthesizedSamplesEvents, this.synthesizedSamplesEvents) - deltaTotalPlayoutDelay L84:
this.deltaTotalPlayoutDelay = positiveDelta(stats.totalPlayoutDelay, this.totalPlayoutDelay) - deltaSamplesCount L85:
this.deltaSamplesCount = positiveDelta(stats.totalSamplesCount, this.totalSamplesCount) - playoutDelayPerSampleInMs L89:
this.playoutDelayPerSampleInMs = (this.deltaTotalPlayoutDelay * 1000) / this.deltaSamplesCount - playoutDelayPerSampleInMs L91:
this.playoutDelayPerSampleInMs = undefined - synthesizedSamplesRatio L94:
this.synthesizedSamplesRatio = this.deltaSamplesDuration > 0 ? Math.min(1, this.deltaSynthesizedSamplesDuration / this.deltaSamplesDuration) : 0
Exact wire projection
public createSample(): MediaPlayoutStats {
return {
id: this.id,
timestamp: this.timestamp,
kind: this.kind,
synthesizedSamplesDuration: this.synthesizedSamplesDuration,
synthesizedSamplesEvents: this.synthesizedSamplesEvents,
totalSamplesDuration: this.totalSamplesDuration,
totalPlayoutDelay: this.totalPlayoutDelay,
totalSamplesCount: this.totalSamplesCount,
attachments: this.attachments,
};
}MediaSourceMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
timestamp | number | L9 |
id | string | L10 |
kind | MediaKind | L11 |
audioLevel | number / undefined | L12 |
trackIdentifier | string | L13 |
totalAudioEnergy | number / undefined | L14 |
totalSamplesDuration | number / undefined | L15 |
echoReturnLoss | number / undefined | L16 |
echoReturnLossEnhancement | number / undefined | L17 |
width | number / undefined | L18 |
height | number / undefined | L19 |
frames | number / undefined | L20 |
framesPerSecond | number / undefined | L21 |
deltaFrames | number / undefined | L24 |
deltaTotalAudioEnergy | number / undefined | L25 |
deltaSamplesDuration | number / undefined | L26 |
deltaTime | number / undefined | L29 |
producedFps | number / undefined | L33 |
rmsAudioLevel | number / undefined | L39 |
attachments | Record<string, unknown> / undefined | L42 |
appData | Record<string, unknown> / undefined | L44 |
visited | boolean | L58 |
statsClockTime | public statsClockTime = 0; | L67 |
Assignment and formula index
- id L50:
this.id = options.id - timestamp L51:
this.timestamp = options.timestamp - kind L52:
this.kind = options.kind as MediaKind - deltaTime L89:
this.deltaTime = elapsedInMs - statsClockTime L90:
this.statsClockTime += elapsedInMs - deltaFrames L93:
this.deltaFrames = positiveDelta(stats.frames, this.frames) - deltaTotalAudioEnergy L94:
this.deltaTotalAudioEnergy = positiveDelta(stats.totalAudioEnergy, this.totalAudioEnergy) - deltaSamplesDuration L95:
this.deltaSamplesDuration = positiveDelta(stats.totalSamplesDuration, this.totalSamplesDuration) - producedFps L103:
this.producedFps = framesDelta !== undefined && 0 <= framesDelta ? framesDelta / elapsedInSec : undefined - rmsAudioLevel L107:
this.rmsAudioLevel = this.deltaTotalAudioEnergy !== undefined && this.deltaSamplesDuration !== undefined && this.deltaSamplesDuration > 0 ? Math.sqrt(this.deltaTotalAudioEnergy / this.deltaSamplesDuration) : undefined
Exact wire projection
public createSample(): MediaSourceStats {
return {
id: this.id,
timestamp: this.timestamp,
kind: this.kind,
audioLevel: this.audioLevel,
trackIdentifier: this.trackIdentifier,
totalAudioEnergy: this.totalAudioEnergy,
totalSamplesDuration: this.totalSamplesDuration,
echoReturnLoss: this.echoReturnLoss,
echoReturnLossEnhancement: this.echoReturnLossEnhancement,
width: this.width,
height: this.height,
frames: this.frames,
framesPerSecond: this.framesPerSecond,
attachments: this.attachments,
};
}OutboundRtpMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
timestamp | number | L9 |
id | string | L10 |
ssrc | number | L11 |
kind | MediaKind | L12 |
qualityLimitationDurations | QualityLimitationDurations | L13 |
transportId | string / undefined | L14 |
codecId | string / undefined | L15 |
packetsSent | number / undefined | L16 |
bytesSent | number / undefined | L17 |
mid | string / undefined | L18 |
mediaSourceId | string / undefined | L19 |
remoteId | string / undefined | L20 |
rid | string / undefined | L21 |
encodingIndex | number / undefined | L22 |
headerBytesSent | number / undefined | L23 |
retransmittedPacketsSent | number / undefined | L24 |
retransmittedBytesSent | number / undefined | L25 |
rtxSsrc | number / undefined | L26 |
targetBitrate | number / undefined | L27 |
totalEncodedBytesTarget | number / undefined | L28 |
frameWidth | number / undefined | L29 |
frameHeight | number / undefined | L30 |
framesPerSecond | number / undefined | L31 |
framesSent | number / undefined | L32 |
hugeFramesSent | number / undefined | L33 |
framesEncoded | number / undefined | L34 |
keyFramesEncoded | number / undefined | L35 |
qpSum | number / undefined | L36 |
psnrSum | PsnrSum / undefined | L37 |
psnrMeasurements | number / undefined | L38 |
totalEncodeTime | number / undefined | L39 |
totalPacketSendDelay | number / undefined | L40 |
qualityLimitationReason | string / undefined | L41 |
qualityLimitationResolutionChanges | number / undefined | L42 |
nackCount | number / undefined | L43 |
firCount | number / undefined | L44 |
pliCount | number / undefined | L45 |
encoderImplementation | string / undefined | L46 |
powerEfficientEncoder | boolean / undefined | L47 |
active | boolean / undefined | L48 |
scalabilityMode | string / undefined | L49 |
packetsSentWithEct1 | number / undefined | L50 |
bitrate | number / undefined | L53 |
payloadBitrate | number / undefined | L54 |
packetRate | number / undefined | L55 |
bitPerPixel | number / undefined | L56 |
deltaPacketsSent | number / undefined | L58 |
deltaBytesSent | number / undefined | L59 |
deltaHeaderBytesSent | number / undefined | L60 |
deltaRetransmittedPacketsSent | number / undefined | L61 |
deltaRetransmittedBytesSent | number / undefined | L62 |
deltaFramesSent | number / undefined | L63 |
deltaFramesEncoded | number / undefined | L64 |
deltaKeyFramesEncoded | number / undefined | L65 |
deltaHugeFramesSent | number / undefined | L66 |
deltaEncodeTime | number / undefined | L67 |
deltaPacketSendDelay | number / undefined | L68 |
deltaQpSum | number / undefined | L69 |
deltaNackCount | number / undefined | L70 |
deltaFirCount | number / undefined | L71 |
deltaPliCount | number / undefined | L72 |
deltaTime | number / undefined | L75 |
avgEncodeTimePerFrameInMs | number / undefined | L78 |
retransmissionRatio | number / undefined | L81 |
retransmittedPacketRatio | number / undefined | L84 |
avgQpPerFrame | number / undefined | L87 |
avgPacketSendDelayInMs | number / undefined | L90 |
keyFrameRate | number / undefined | L93 |
nackRate | number / undefined | L96 |
pliRate | number / undefined | L97 |
firRate | number / undefined | L98 |
qualityLimitationDurationShares | { | |
| none: number; | ||
| cpu: number; | ||
| bandwidth: number; | ||
| other: number; | ||
| } / undefined | L101 | |
attachments | Record<string, unknown> / undefined | L109 |
appData | Record<string, unknown> / undefined | L111 |
visited | boolean | L125 |
trackIdentifier | public get trackIdentifier() { | L133 |
statsClockTime | public statsClockTime = 0; | L142 |
Assignment and formula index
- id L117:
this.id = options.id - timestamp L118:
this.timestamp = options.timestamp - ssrc L119:
this.ssrc = options.ssrc - kind L120:
this.kind = options.kind as MediaKind - deltaTime L181:
this.deltaTime = elapsedInMs - statsClockTime L182:
this.statsClockTime += elapsedInMs - deltaPacketsSent L185:
this.deltaPacketsSent = positiveDelta(stats.packetsSent, this.packetsSent) - packetRate L187:
this.packetRate = this.deltaPacketsSent / elapsedInSec - deltaBytesSent L190:
this.deltaBytesSent = positiveDelta(stats.bytesSent, this.bytesSent) - deltaHeaderBytesSent L191:
this.deltaHeaderBytesSent = positiveDelta(stats.headerBytesSent, this.headerBytesSent) - deltaRetransmittedBytesSent L192:
this.deltaRetransmittedBytesSent = positiveDelta(stats.retransmittedBytesSent, this.retransmittedBytesSent) - deltaRetransmittedPacketsSent L193:
this.deltaRetransmittedPacketsSent = positiveDelta(stats.retransmittedPacketsSent, this.retransmittedPacketsSent) - bitrate L196:
this.bitrate = Math.max(0, this.deltaBytesSent * 8 / elapsedInSec) - payloadBitrate L201:
this.payloadBitrate = Math.max(0, payloadBytesSent * 8 / elapsedInSec) - retransmissionRatio L204:
this.retransmissionRatio = this.deltaBytesSent > 0 && this.deltaRetransmittedBytesSent !== undefined ? Math.min(1, this.deltaRetransmittedBytesSent / this.deltaBytesSent) : 0 - retransmittedPacketRatio L210:
this.retransmittedPacketRatio = this.deltaPacketsSent > 0 ? Math.min(1, this.deltaRetransmittedPacketsSent / this.deltaPacketsSent) : 0 - deltaFramesSent L215:
this.deltaFramesSent = positiveDelta(stats.framesSent, this.framesSent) - deltaFramesEncoded L216:
this.deltaFramesEncoded = positiveDelta(stats.framesEncoded, this.framesEncoded) - deltaKeyFramesEncoded L217:
this.deltaKeyFramesEncoded = positiveDelta(stats.keyFramesEncoded, this.keyFramesEncoded) - deltaHugeFramesSent L218:
this.deltaHugeFramesSent = positiveDelta(stats.hugeFramesSent, this.hugeFramesSent) - deltaEncodeTime L219:
this.deltaEncodeTime = positiveDelta(stats.totalEncodeTime, this.totalEncodeTime) - deltaPacketSendDelay L220:
this.deltaPacketSendDelay = positiveDelta(stats.totalPacketSendDelay, this.totalPacketSendDelay) - deltaQpSum L221:
this.deltaQpSum = positiveDelta(stats.qpSum, this.qpSum) - deltaNackCount L222:
this.deltaNackCount = positiveDelta(stats.nackCount, this.nackCount) - deltaFirCount L223:
this.deltaFirCount = positiveDelta(stats.firCount, this.firCount) - deltaPliCount L224:
this.deltaPliCount = positiveDelta(stats.pliCount, this.pliCount) - avgEncodeTimePerFrameInMs L229:
this.avgEncodeTimePerFrameInMs = (this.deltaEncodeTime * 1000) / this.deltaFramesEncoded - avgQpPerFrame L232:
this.avgQpPerFrame = this.deltaQpSum / this.deltaFramesEncoded - avgPacketSendDelayInMs L238:
this.avgPacketSendDelayInMs = (this.deltaPacketSendDelay * 1000) / this.deltaPacketsSent - keyFrameRate L242:
this.keyFrameRate = this.deltaKeyFramesEncoded / elapsedInSec - nackRate L245:
this.nackRate = this.deltaNackCount / elapsedInSec - pliRate L248:
this.pliRate = this.deltaPliCount / elapsedInSec - firRate L251:
this.firRate = this.deltaFirCount / elapsedInSec - qualityLimitationDurationShares L254:
this.qualityLimitationDurationShares = this._calculateQualityLimitationShares( this.qualityLimitationDurations, stats.qualityLimitationDurations, ) - bitPerPixel L262:
this.bitPerPixel = this.bitrate / (this.frameHeight * this.frameWidth * this.framesPerSecond)
Exact wire projection
public createSample(): OutboundRtpStats {
return {
timestamp: this.timestamp,
id: this.id,
ssrc: this.ssrc,
kind: this.kind,
qualityLimitationDurations: this.qualityLimitationDurations,
transportId: this.transportId,
codecId: this.codecId,
packetsSent: this.packetsSent,
bytesSent: this.bytesSent,
mid: this.mid,
mediaSourceId: this.mediaSourceId,
remoteId: this.remoteId,
rid: this.rid,
encodingIndex: this.encodingIndex,
headerBytesSent: this.headerBytesSent,
retransmittedPacketsSent: this.retransmittedPacketsSent,
retransmittedBytesSent: this.retransmittedBytesSent,
rtxSsrc: this.rtxSsrc,
targetBitrate: this.targetBitrate,
totalEncodedBytesTarget: this.totalEncodedBytesTarget,
frameWidth: this.frameWidth,
frameHeight: this.frameHeight,
framesPerSecond: this.framesPerSecond,
framesSent: this.framesSent,
hugeFramesSent: this.hugeFramesSent,
framesEncoded: this.framesEncoded,
keyFramesEncoded: this.keyFramesEncoded,
qpSum: this.qpSum,
psnrSum: this.psnrSum,
psnrMeasurements: this.psnrMeasurements,
totalEncodeTime: this.totalEncodeTime,
totalPacketSendDelay: this.totalPacketSendDelay,
qualityLimitationReason: this.qualityLimitationReason,
qualityLimitationResolutionChanges: this.qualityLimitationResolutionChanges,
nackCount: this.nackCount,
firCount: this.firCount,
pliCount: this.pliCount,
encoderImplementation: this.encoderImplementation,
powerEfficientEncoder: this.powerEfficientEncoder,
active: this.active,
scalabilityMode: this.scalabilityMode,
packetsSentWithEct1: this.packetsSentWithEct1,
attachments: this.attachments,
};
}OutboundTrackMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
direction | public readonly direction = ‘outbound’; | L91 |
detectors | Detectors | L92 |
issues | IssueRegistry<OutboundTrackIssues> | L93 |
slicedWindow | SlicedWindow< | |
| OutboundTrackWindowValues, | ||
| // A slice for every stretch the config sizes, so the names are declared once. Only the | ||
| // names matter here: how many samples each covers, and where it sits, are runtime. | ||
| Record<keyof OutboundTrackWindowConfig[’numberOfSamples’], SliceConfig> | ||
| > | L102 | |
bitrate | number | L119 |
jitter | number | L120 |
fractionLost | number | L121 |
sendingPacketRate | number | L122 |
remoteReceivedPacketRate | number | L123 |
sourceEnded | public sourceEnded = false; | L130 |
mappedOutboundRtps | public readonly mappedOutboundRtps = new Map<number, OutboundRtpMonitor>(); | L131 |
paused | boolean | L145 |
settings | MediaTrackSettings | L164 |
videoCaptureSettingsChanged | boolean | L167 |
degradedVideoCapture | boolean | L173 |
videoCaptureDegradation | number | L181 |
degradedEncodingPerformance | boolean | L184 |
videoEncodingDegradation | number | L187 |
dry | boolean | L190 |
silentAudioSource | boolean | L193 |
lostCaptureSource | boolean | L199 |
contentType | TrackContentType / undefined | L209 |
calculatedScore | CalculatedScore | L213 |
score | public get score() { | L218 |
scoreReasons | public get scoreReasons() { | L222 |
attachments | Record<string, unknown> / undefined | L227 |
appData | Record<string, unknown> / undefined | L229 |
kind | public get kind() { | L316 |
isScreenShare | public get isScreenShare() { | L321 |
readyState | MediaStreamTrack[‘readyState’] | L325 |
highestLayer | OutboundRtpMonitor | L343 |
Assignment and formula index
- attachments L236:
this.attachments = attachments - detectors L237:
this.detectors = new Detectors() - issues L238:
this.issues = new IssueRegistry<OutboundTrackIssues>( this.getPeerConnection().parent.activeIssues.asSink ) - slicedWindow L288:
this.slicedWindow = new SlicedWindow({ maxAllowedGapInMs: windowConfig.maxAllowedGapInMs, totals: { highestLayerTotalEncodedFrames: null, mediaSourceTotalProducedFrames: null, }, slices: { detection: { numberOfSamples: windowConfig.numberOfSamples.detection, }, recovery: { numberOfSamples: windowConfig.numberOfSamples.recovery, offset: windowConfig.numberOfSamples.detection, } } }) - bitrate L348:
this.bitrate = 0 - jitter L349:
this.jitter = 0 - fractionLost L350:
this.fractionLost = 0 - sendingPacketRate L351:
this.sendingPacketRate = 0 - remoteReceivedPacketRate L352:
this.remoteReceivedPacketRate = 0 - highestLayer L353:
this.highestLayer = undefined - bitrate L356:
this.bitrate += outboundRtp.bitrate ?? 0 - jitter L357:
this.jitter += outboundRtp.getRemoteInboundRtp()?.jitter ?? 0 - fractionLost L358:
this.fractionLost += outboundRtp.getRemoteInboundRtp()?.deltaFractionLost ?? 0 - sendingPacketRate L359:
this.sendingPacketRate += outboundRtp.packetRate ?? 0 - remoteReceivedPacketRate L360:
this.remoteReceivedPacketRate += outboundRtp.getRemoteInboundRtp()?.packetRate ?? 0 - highestLayer L364:
this.highestLayer = outboundRtp - highestLayer L367:
this.highestLayer = outboundRtp - settings L402:
this.settings = settings ? { ...settings } : undefined - settings L405:
this.settings = undefined - videoCaptureSettingsChanged L408:
this.videoCaptureSettingsChanged = previous === undefined ? undefined : previous.frameRate !== this.settings?.frameRate || previous.width !== this.settings?.width || previous.height !== this.settings?.height
Exact wire projection
public createSample(): OutboundTrackSample {
return {
id: this.track.id,
kind: this.kind,
timestamp: Date.now(),
attachments: this.attachments,
score: this.score,
scoreReasons: sampledScoreReasons(
this.calculatedScore.reasons,
this.getPeerConnection()?.parent.config.sendScoreReasonsToServer,
),
};
}PeerConnectionMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
statsAdapters | StatsAdapters | L171 |
detectors | Detectors | L173 |
issues | IssueRegistry<PeerConnectionIssues> | L180 |
mappedCodecMonitors | public readonly mappedCodecMonitors = new Map<string, CodecMonitor>(); | L181 |
mappedInboundRtpMonitors | public readonly mappedInboundRtpMonitors = new Map<number, InboundRtpMonitor>(); | L182 |
mappedRemoteOutboundRtpMonitors | public readonly mappedRemoteOutboundRtpMonitors = new Map<number, RemoteOutboundRtpMonitor>(); | L183 |
mappedOutboundRtpMonitors | public readonly mappedOutboundRtpMonitors = new Map<number, OutboundRtpMonitor>(); | L184 |
mappedDataChannelMonitors | public readonly mappedDataChannelMonitors = new Map<string, DataChannelMonitor>(); | L185 |
mappedRemoteInboundRtpMonitors | public readonly mappedRemoteInboundRtpMonitors = new Map<number, RemoteInboundRtpMonitor>(); | L186 |
mappedMediaSourceMonitors | public readonly mappedMediaSourceMonitors = new Map<string, MediaSourceMonitor>(); | L187 |
mappedMediaPlayoutMonitors | public readonly mappedMediaPlayoutMonitors = new Map<string, MediaPlayoutMonitor>(); | L188 |
mappedPeerConnectionTransportMonitors | public readonly mappedPeerConnectionTransportMonitors = new Map<string, PeerConnectionTransportMonitor>(); | L189 |
mappedIceTransportMonitors | public readonly mappedIceTransportMonitors = new Map<string, IceTransportMonitor>(); | L190 |
mappedIceCandidateMonitors | public readonly mappedIceCandidateMonitors = new Map<string, IceCandidateMonitor>(); | L191 |
mappedIceCandidatePairMonitors | public readonly mappedIceCandidatePairMonitors = new Map<string, IceCandidatePairMonitor>(); | L192 |
mappedCertificateMonitors | public readonly mappedCertificateMonitors = new Map<string, CertificateMonitor>(); | L193 |
mappedSelectedIcePaths | public readonly mappedSelectedIcePaths = new Map<string, SelectedIcePath>(); | L195 |
mappedInboundTracks | public readonly mappedInboundTracks = new Map<string, InboundTrackMonitor>(); | L202 |
mappedOutboundTracks | public readonly mappedOutboundTracks = new Map<string, OutboundTrackMonitor>(); | L203 |
closed | public closed = false; | L209 |
sendingAudioBitrate | public sendingAudioBitrate = 0; | L212 |
sendingVideoBitrate | public sendingVideoBitrate = 0; | L213 |
receivingAudioBitrate | public receivingAudioBitrate = 0; | L214 |
receivingVideoBitrate | public receivingVideoBitrate = 0; | L215 |
dataChannelSendingBitrate | public dataChannelSendingBitrate = 0; | L216 |
dataChannelReceivingBitrate | public dataChannelReceivingBitrate = 0; | L217 |
outboundFractionLost | public outboundFractionLost = 0.0; | L219 |
inboundFractionalLost | public inboundFractionalLost = 0.0; | L220 |
avgInboundFractionLost | number | L228 |
avgOutboundFractionLost | number | L231 |
avgInboundJitterInMs | number | L234 |
transportStability | number | L251 |
deltaTime | number / undefined | L258 |
statsClockTime | public statsClockTime = 0; | L265 |
slicedWindow | SlicedWindow< | |
| PeerConnectionWindowValues, | ||
| // A slice for every stretch the config sizes, so the names are declared once. Only the | ||
| // names matter here: how many samples each covers, and where it sits, are runtime. | ||
| Record<keyof PeerConnectionWindowConfig[’numberOfSamples’], SliceConfig> | ||
| > | L286 | |
totalInboundPacketsLost | number | L296 |
totalInboundPacketsReceived | number | L297 |
totalOutboundPacketsSent | number | L298 |
totalOutboundPacketsReceived | number | L299 |
totalOutboundPacketsLost | number | L300 |
totalDataChannelBytesSent | number | L301 |
totalDataChannelBytesReceived | number | L302 |
totalSentAudioBytes | number | L303 |
totalSentVideoBytes | number | L304 |
totalReceivedAudioBytes | number | L305 |
totalReceivedVideoBytes | number | L306 |
totalVideoEncodeTimeInMs | number | L307 |
totalVideoDecodeTimeInMs | number | L308 |
totalAvailableIncomingBitrate | number | L309 |
totalAvailableOutgoingBitrate | number | L310 |
totalPacketSendDelayInSec | number | L311 |
deltaInboundPacketsLost | number | L314 |
deltaInboundPacketsReceived | number | L315 |
deltaOutboundPacketsSent | number | L316 |
deltaOutboundPacketsReceived | number | L317 |
deltaOutboundPacketsLost | number | L318 |
deltaAudioBytesSent | number | L319 |
deltaVideoBytesSent | number | L320 |
deltaAudioBytesReceived | number | L321 |
deltaVideoBytesReceived | number | L322 |
deltaDataChannelBytesReceived | number | L323 |
deltaDataChannelBytesSent | number | L324 |
deltaPacketSendDelayInSec | number | L325 |
deltaVideoPacketsSent | number | L327 |
deltaVideoEncodeTimeInMs | number | L334 |
deltaVideoDecodeTimeInMs | number | L335 |
avgPacketSendDelayInMs | number | L342 |
deltaInboundVideoJitterBufferDelayInSec | number | L345 |
deltaInboundVideoJitterBufferEmittedCount | number | L346 |
avgInboundVideoJitterBufferDelayInMs | number | L356 |
uplinkCongested | public uplinkCongested = false; | L363 |
uplinkVideoCongestionSeverity | number | L364 |
downlinkCongested | public downlinkCongested = false; | L365 |
downlinkVideoCongestionSeverity | number | L366 |
cpulimited | public cpulimited = false; | L368 |
stalledRtpSender | boolean | L382 |
stalledTransportDemux | boolean | L385 |
hasInboundMedia | public hasInboundMedia = false; | L387 |
hasOutboundMedia | public hasOutboundMedia = false; | L388 |
hasInboundVideo | public hasInboundVideo = false; | L395 |
qualityLimitationReason | PeerConnectionQualityLimitationReason | L402 |
iceRttInSec | number | L408 |
ewmaIceRttInSec | number | L409 |
rtcpRttInSec | number | L412 |
ewmaRtcpRttInSec | number | L413 |
connectingStartedAt | number | L414 |
connectedAt | number | L415 |
iceState | W3C.RtcIceTransportState | L417 |
iceGatheringState | string | L420 |
usingTURN | boolean | L422 |
usingTCP | boolean | L423 |
calculatedStabilityScore | CalculatedScore | L424 |
appData | Record<string, unknown> / undefined | L430 |
avgRttInSec | number / undefined | L541 |
ewmaRttInSec | number / undefined | L546 |
score | public get score() { | L550 |
scoreReasons | public get scoreReasons() { | L554 |
congested | public congested = false; | L565 |
receivingBitrate | public get receivingBitrate() { | L567 |
sendingBitrate | public get sendingBitrate() { | L571 |
tracks | public get tracks() { | L575 |
codecs | public get codecs() { | L985 |
inboundRtps | public get inboundRtps() { | L989 |
remoteOutboundRtps | public get remoteOutboundRtps() { | L1042 |
outboundRtps | public get outboundRtps() { | L1046 |
remoteInboundRtps | public get remoteInboundRtps() { | L1050 |
mediaSources | public get mediaSources() { | L1054 |
mediaPlayouts | public get mediaPlayouts() { | L1058 |
dataChannels | public get dataChannels() { | L1062 |
peerConnectionTransports | public get peerConnectionTransports() { | L1066 |
iceTransports | public get iceTransports() { | L1070 |
iceCandidates | public get iceCandidates() { | L1074 |
localIceCandidates | public get localIceCandidates() { | L1079 |
iceCandidatePairs | public get iceCandidatePairs() { | L1083 |
certificates | public get certificates() { | L1087 |
selectedIcePaths | public get selectedIcePaths() { | L1091 |
selectedIcePath | SelectedIcePath / undefined | L1099 |
blockedTransport | boolean | L1110 |
selectedIceCandidatePairs | public get selectedIceCandidatePairs() { | L1118 |
connectionState | public get connectionState() { | L1164 |
Assignment and formula index
- statsAdapters L440:
this.statsAdapters = new StatsAdapters(logger) - issues L441:
this.issues = new IssueRegistry<PeerConnectionIssues>(parent.activeIssues.asSink) - slicedWindow L446:
this.slicedWindow = new SlicedWindow({ maxAllowedGapInMs: windowConfig.maxAllowedGapInMs, totals: PEER_CONNECTION_WINDOW_VALUES, slices: { detection: { numberOfSamples: windowConfig.numberOfSamples.detection, }, recovery: { numberOfSamples: windowConfig.numberOfSamples.recovery, offset: windowConfig.numberOfSamples.detection, }, }, }) - detectors L459:
this.detectors = new Detectors() - deltaTime L632:
this.deltaTime = timeDelta !== undefined && 0 < timeDelta ? timeDelta : undefined - statsClockTime L633:
this.statsClockTime += this.deltaTime ?? 0 - deltaVideoBytesSent L642:
this.deltaVideoBytesSent = undefined - deltaAudioBytesSent L643:
this.deltaAudioBytesSent = undefined - deltaVideoBytesReceived L644:
this.deltaVideoBytesReceived = undefined - deltaAudioBytesReceived L645:
this.deltaAudioBytesReceived = undefined - deltaDataChannelBytesReceived L646:
this.deltaDataChannelBytesReceived = undefined - deltaDataChannelBytesSent L647:
this.deltaDataChannelBytesSent = undefined - deltaOutboundPacketsLost L648:
this.deltaOutboundPacketsLost = undefined - deltaOutboundPacketsReceived L649:
this.deltaOutboundPacketsReceived = undefined - deltaOutboundPacketsSent L650:
this.deltaOutboundPacketsSent = undefined - deltaInboundPacketsLost L651:
this.deltaInboundPacketsLost = undefined - deltaInboundPacketsReceived L652:
this.deltaInboundPacketsReceived = undefined - deltaPacketSendDelayInSec L653:
this.deltaPacketSendDelayInSec = undefined - deltaInboundVideoJitterBufferDelayInSec L654:
this.deltaInboundVideoJitterBufferDelayInSec = undefined - deltaInboundVideoJitterBufferEmittedCount L655:
this.deltaInboundVideoJitterBufferEmittedCount = undefined - avgInboundVideoJitterBufferDelayInMs L656:
this.avgInboundVideoJitterBufferDelayInMs = undefined - deltaVideoPacketsSent L657:
this.deltaVideoPacketsSent = undefined - deltaVideoEncodeTimeInMs L658:
this.deltaVideoEncodeTimeInMs = undefined - deltaVideoDecodeTimeInMs L659:
this.deltaVideoDecodeTimeInMs = undefined - avgPacketSendDelayInMs L660:
this.avgPacketSendDelayInMs = undefined - sendingAudioBitrate L662:
this.sendingAudioBitrate = 0 - sendingVideoBitrate L663:
this.sendingVideoBitrate = 0 - receivingAudioBitrate L664:
this.receivingAudioBitrate = 0 - receivingVideoBitrate L665:
this.receivingVideoBitrate = 0 - dataChannelSendingBitrate L666:
this.dataChannelSendingBitrate = 0 - dataChannelReceivingBitrate L667:
this.dataChannelReceivingBitrate = 0 - outboundFractionLost L668:
this.outboundFractionLost = 0 - inboundFractionalLost L669:
this.inboundFractionalLost = 0 - totalAvailableIncomingBitrate L670:
this.totalAvailableIncomingBitrate = undefined - totalAvailableOutgoingBitrate L671:
this.totalAvailableOutgoingBitrate = undefined - qualityLimitationReason L672:
this.qualityLimitationReason = undefined - hasInboundMedia L673:
this.hasInboundMedia = false - hasOutboundMedia L674:
this.hasOutboundMedia = false - hasInboundVideo L675:
this.hasInboundVideo = false - receivingAudioBitrate L689:
this.receivingAudioBitrate += monitor?.bitrate ?? 0 - deltaAudioBytesReceived L690:
this.deltaAudioBytesReceived = accumulatedValue(this.deltaAudioBytesReceived, monitor?.deltaBytesReceived) - hasInboundMedia L691:
this.hasInboundMedia = true - receivingVideoBitrate L694:
this.receivingVideoBitrate += monitor?.bitrate ?? 0 - deltaVideoBytesReceived L695:
this.deltaVideoBytesReceived = accumulatedValue(this.deltaVideoBytesReceived, monitor?.deltaBytesReceived) - hasInboundMedia L696:
this.hasInboundMedia = true - hasInboundVideo L697:
this.hasInboundVideo = true - deltaVideoDecodeTimeInMs L700:
this.deltaVideoDecodeTimeInMs = accumulatedValue( this.deltaVideoDecodeTimeInMs, monitor.deltaTotalDecodeTime === undefined ? undefined : monitor.deltaTotalDecodeTime * 1000, ) - deltaInboundVideoJitterBufferDelayInSec L712:
this.deltaInboundVideoJitterBufferDelayInSec = accumulatedValue( this.deltaInboundVideoJitterBufferDelayInSec, monitor?.deltaJitterBufferDelay, ) - deltaInboundVideoJitterBufferEmittedCount L716:
this.deltaInboundVideoJitterBufferEmittedCount = accumulatedValue( this.deltaInboundVideoJitterBufferEmittedCount, monitor?.deltaJitterBufferEmittedCount, ) - inboundFractionalLost L725:
this.inboundFractionalLost += monitor?.deltaFractionLost ?? 0.0 - deltaInboundPacketsLost L726:
this.deltaInboundPacketsLost = accumulatedValue(this.deltaInboundPacketsLost, monitor?.deltaPacketsLost) - deltaInboundPacketsReceived L727:
this.deltaInboundPacketsReceived = accumulatedValue(this.deltaInboundPacketsReceived, monitor?.deltaPacketsReceived) - sendingAudioBitrate L745:
this.sendingAudioBitrate += monitor?.bitrate ?? 0 - deltaAudioBytesSent L746:
this.deltaAudioBytesSent = accumulatedValue(this.deltaAudioBytesSent, monitor?.deltaBytesSent) - hasOutboundMedia L747:
this.hasOutboundMedia = true - sendingVideoBitrate L750:
this.sendingVideoBitrate += monitor?.bitrate ?? 0 - deltaVideoBytesSent L751:
this.deltaVideoBytesSent = accumulatedValue(this.deltaVideoBytesSent, monitor?.deltaBytesSent) - deltaVideoEncodeTimeInMs L754:
this.deltaVideoEncodeTimeInMs = accumulatedValue( this.deltaVideoEncodeTimeInMs, monitor.deltaEncodeTime === undefined ? undefined : monitor.deltaEncodeTime * 1000, ) - totalPacketSendDelayInSec L761:
this.totalPacketSendDelayInSec = accumulatedValue(this.totalPacketSendDelayInSec, monitor?.deltaPacketSendDelay) - deltaPacketSendDelayInSec L762:
this.deltaPacketSendDelayInSec = accumulatedValue(this.deltaPacketSendDelayInSec, monitor?.deltaPacketSendDelay) - deltaVideoPacketsSent L763:
this.deltaVideoPacketsSent = accumulatedValue(this.deltaVideoPacketsSent, monitor?.deltaPacketsSent) - hasOutboundMedia L764:
this.hasOutboundMedia = true - deltaOutboundPacketsSent L767:
this.deltaOutboundPacketsSent = accumulatedValue(this.deltaOutboundPacketsSent, monitor?.deltaPacketsSent) - outboundFractionLost L786:
this.outboundFractionLost += monitor?.deltaFractionLost ?? 0.0 - deltaOutboundPacketsLost L787:
this.deltaOutboundPacketsLost = accumulatedValue(this.deltaOutboundPacketsLost, monitor?.deltaPacketsLost) - deltaOutboundPacketsReceived L788:
this.deltaOutboundPacketsReceived = accumulatedValue(this.deltaOutboundPacketsReceived, monitor?.deltaPacketsReceived) - deltaDataChannelBytesSent L795:
this.deltaDataChannelBytesSent = accumulatedValue(this.deltaDataChannelBytesSent, monitor?.deltaBytesSent) - deltaDataChannelBytesReceived L796:
this.deltaDataChannelBytesReceived = accumulatedValue(this.deltaDataChannelBytesReceived, monitor?.deltaBytesReceived) - dataChannelSendingBitrate L797:
this.dataChannelSendingBitrate += monitor?.sendingBitrate ?? 0 - dataChannelReceivingBitrate L798:
this.dataChannelReceivingBitrate += monitor?.receivingBitrate ?? 0 - rtcpRttInSec L846:
this.rtcpRttInSec = rtcpRttMeasurementsInS.reduce((acc, rtt) => acc + rtt, 0) / rtcpRttMeasurementsInS.length - ewmaRtcpRttInSec L847:
this.ewmaRtcpRttInSec = this.ewmaRtcpRttInSec !== undefined ? (this.rtcpRttInSec * 0.1) + (this.ewmaRtcpRttInSec * 0.9) : this.rtcpRttInSec - totalAvailableIncomingBitrate L856:
this.totalAvailableIncomingBitrate = accumulatedValue(this.totalAvailableIncomingBitrate, selectedPair.availableIncomingBitrate) - totalAvailableOutgoingBitrate L857:
this.totalAvailableOutgoingBitrate = accumulatedValue(this.totalAvailableOutgoingBitrate, selectedPair.availableOutgoingBitrate) - iceRttInSec L868:
this.iceRttInSec = iceRttMeasurementsInS.reduce((acc, rtt) => acc + rtt, 0) / iceRttMeasurementsInS.length - ewmaIceRttInSec L869:
this.ewmaIceRttInSec = this.ewmaIceRttInSec !== undefined ? (this.iceRttInSec * 0.1) + (this.ewmaIceRttInSec * 0.9) : this.iceRttInSec - usingTCP L876:
this.usingTCP = selectedIceCandidatePairs.some(pair => pair.usingTcp) - usingTURN L877:
this.usingTURN = selectedIceCandidatePairs.some(pair => pair.usingTurn) - iceState L879:
this.iceState = this._mostSevereIceState() - avgPacketSendDelayInMs L883:
this.avgPacketSendDelayInMs = this.deltaPacketSendDelayInSec !== undefined && this.deltaVideoPacketsSent !== undefined && this.deltaVideoPacketsSent > 0 ? (this.deltaPacketSendDelayInSec * 1000) / this.deltaVideoPacketsSent : undefined - avgInboundVideoJitterBufferDelayInMs L891:
this.avgInboundVideoJitterBufferDelayInMs = this.deltaInboundVideoJitterBufferDelayInSec !== undefined && this.deltaInboundVideoJitterBufferEmittedCount !== undefined && this.deltaInboundVideoJitterBufferEmittedCount > 0 ? (this.deltaInboundVideoJitterBufferDelayInSec * 1000) / this.deltaInboundVideoJitterBufferEmittedCount : undefined - totalDataChannelBytesReceived L897:
this.totalDataChannelBytesReceived = accumulatedValue(this.totalDataChannelBytesReceived, this.deltaDataChannelBytesReceived) - totalDataChannelBytesSent L898:
this.totalDataChannelBytesSent = accumulatedValue(this.totalDataChannelBytesSent, this.deltaDataChannelBytesSent) - totalSentAudioBytes L899:
this.totalSentAudioBytes = accumulatedValue(this.totalSentAudioBytes, this.deltaAudioBytesSent) - totalSentVideoBytes L900:
this.totalSentVideoBytes = accumulatedValue(this.totalSentVideoBytes, this.deltaVideoBytesSent) - totalReceivedAudioBytes L901:
this.totalReceivedAudioBytes = accumulatedValue(this.totalReceivedAudioBytes, this.deltaAudioBytesReceived) - totalReceivedVideoBytes L902:
this.totalReceivedVideoBytes = accumulatedValue(this.totalReceivedVideoBytes, this.deltaVideoBytesReceived) - totalVideoEncodeTimeInMs L903:
this.totalVideoEncodeTimeInMs = accumulatedValue(this.totalVideoEncodeTimeInMs, this.deltaVideoEncodeTimeInMs) - totalVideoDecodeTimeInMs L904:
this.totalVideoDecodeTimeInMs = accumulatedValue(this.totalVideoDecodeTimeInMs, this.deltaVideoDecodeTimeInMs) - totalOutboundPacketsSent L905:
this.totalOutboundPacketsSent = accumulatedValue(this.totalOutboundPacketsSent, this.deltaOutboundPacketsSent) - totalOutboundPacketsReceived L906:
this.totalOutboundPacketsReceived = accumulatedValue(this.totalOutboundPacketsReceived, this.deltaOutboundPacketsReceived) - totalOutboundPacketsLost L907:
this.totalOutboundPacketsLost = accumulatedValue(this.totalOutboundPacketsLost, this.deltaOutboundPacketsLost) - totalInboundPacketsLost L908:
this.totalInboundPacketsLost = accumulatedValue(this.totalInboundPacketsLost, this.deltaInboundPacketsLost) - totalInboundPacketsReceived L909:
this.totalInboundPacketsReceived = accumulatedValue(this.totalInboundPacketsReceived, this.deltaInboundPacketsReceived) - connectingStartedAt L1155:
this.connectingStartedAt = Date.now() - connectedAt L1157:
this.connectedAt = Date.now() - connectingStartedAt L1159:
this.connectingStartedAt = undefined - connectedAt L1160:
this.connectedAt = undefined - qualityLimitationReason L1213:
this.qualityLimitationReason = newReason - qualityLimitationReason L1221:
this.qualityLimitationReason = newReason - transportStability L1241:
this.transportStability = rttInSec === undefined || jitterInMs === undefined || lossFraction === undefined ? undefined : transportStability({ rttInMs: rttInSec * 1000, jitterInMs, packetLossPercent: Math.max( this.avgInboundFractionLost ?? 0, this.avgOutboundFractionLost ?? 0, ) * 100, }) - avgInboundFractionLost L1272:
this.avgInboundFractionLost = 0 < lossCount ? lossSum / lossCount : undefined - avgInboundJitterInMs L1273:
this.avgInboundJitterInMs = 0 < jitterCount ? jitterSum / jitterCount : undefined - avgOutboundFractionLost L1285:
this.avgOutboundFractionLost = 0 < outboundLossCount ? outboundLossSum / outboundLossCount : undefined - closed L1426:
this.closed = true
Exact wire projection
public createSample(): PeerConnectionSample {
return {
peerConnectionId: this.peerConnectionId,
attachments: this.attachments,
codecs: this.codecs.map(codec => codec.createSample()),
inboundRtps: this.inboundRtps.map(inboundRtp => inboundRtp.createSample()),
remoteOutboundRtps: this.remoteOutboundRtps.map(remoteOutboundRtp => remoteOutboundRtp.createSample()),
outboundRtps: this.outboundRtps.map(outboundRtp => outboundRtp.createSample()),
remoteInboundRtps: this.remoteInboundRtps.map(remoteInboundRtp => remoteInboundRtp.createSample()),
mediaSources: this.mediaSources.map(mediaSource => mediaSource.createSample()),
mediaPlayouts: this.mediaPlayouts.map(mediaPlayout => mediaPlayout.createSample()),
peerConnectionTransports: this.peerConnectionTransports.map(peerConnectionTransport => peerConnectionTransport.createSample()),
dataChannels: this.dataChannels.map(dataChannel => dataChannel.createSample()),
iceTransports: this.iceTransports.map(iceTransport => iceTransport.createSample()),
iceCandidates: this.iceCandidates.map(iceCandidate => iceCandidate.createSample()),
iceCandidatePairs: this.iceCandidatePairs.map(iceCandidatePair => iceCandidatePair.createSample()),
certificates: this.certificates.map(certificate => certificate.createSample()),
inboundTracks: [ ...this.mappedInboundTracks.values() ].map(inboundTrack => inboundTrack.createSample()),
outboundTracks: [ ...this.mappedOutboundTracks.values() ].map(outboundTrack => outboundTrack.createSample()),
score: this.score,
scoreReasons: sampledScoreReasons(this.calculatedStabilityScore.reasons, this.parent.config.sendScoreReasonsToServer)
}
}PeerConnectionTransportMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
timestamp | number | L7 |
id | string | L8 |
dataChannelsOpened | number | L9 |
dataChannelsClosed | number | L10 |
attachments | Record<string, unknown> / undefined | L16 |
appData | Record<string, unknown> / undefined | L21 |
visited | boolean | L33 |
Assignment and formula index
Exact wire projection
public createSample(): PeerConnectionTransportStats {
return {
id: this.id,
timestamp: this.timestamp,
dataChannelsOpened: this.dataChannelsOpened,
dataChannelsClosed: this.dataChannelsClosed,
attachments: this.attachments,
};
}RemoteInboundRtpMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
timestamp | number | L8 |
id | string | L9 |
ssrc | number | L10 |
kind | string | L11 |
transportId | string / undefined | L12 |
codecId | string / undefined | L13 |
packetsReceived | number / undefined | L14 |
packetsReceivedWithEct1 | number / undefined | L15 |
packetsReceivedWithCe | number / undefined | L16 |
packetsReportedAsLost | number / undefined | L17 |
packetsReportedAsLostButRecovered | number / undefined | L18 |
packetsLost | number / undefined | L19 |
jitter | number / undefined | L20 |
localId | string / undefined | L21 |
roundTripTime | number / undefined | L22 |
totalRoundTripTime | number / undefined | L23 |
fractionLost | number / undefined | L24 |
roundTripTimeMeasurements | number / undefined | L25 |
packetsWithBleachedEct1Marking | number / undefined | L26 |
packetRate | number | L29 |
deltaPacketsLost | number | L31 |
deltaPacketsReceived | number | L32 |
deltaFractionLost | number | L33 |
avgRoundTripTimeInSec | number | L39 |
deltaTotalRoundTripTime | number | L41 |
deltaRoundTripTimeMeasurements | number | L42 |
deltaTime | number / undefined | L45 |
attachments | Record<string, unknown> / undefined | L49 |
appData | Record<string, unknown> / undefined | L51 |
visited | boolean | L66 |
statsClockTime | public statsClockTime = 0; | L75 |
Assignment and formula index
- id L57:
this.id = options.id - timestamp L58:
this.timestamp = options.timestamp - ssrc L59:
this.ssrc = options.ssrc - kind L60:
this.kind = options.kind - deltaTime L105:
this.deltaTime = 0 - deltaPacketsReceived L106:
this.deltaPacketsReceived = undefined - deltaPacketsLost L107:
this.deltaPacketsLost = undefined - deltaFractionLost L108:
this.deltaFractionLost = undefined - deltaTotalRoundTripTime L109:
this.deltaTotalRoundTripTime = undefined - deltaRoundTripTimeMeasurements L110:
this.deltaRoundTripTimeMeasurements = undefined - avgRoundTripTimeInSec L111:
this.avgRoundTripTimeInSec = undefined - packetRate L112:
this.packetRate = undefined - deltaTime L117:
this.deltaTime = elapsedInMs - statsClockTime L118:
this.statsClockTime += elapsedInMs - deltaPacketsReceived L121:
this.deltaPacketsReceived = positiveDelta(stats.packetsReceived, this.packetsReceived) - packetRate L123:
this.packetRate = this.deltaPacketsReceived / elapsedInSeconds - deltaPacketsLost L126:
this.deltaPacketsLost = positiveDelta(stats.packetsLost, this.packetsLost) - deltaTotalRoundTripTime L127:
this.deltaTotalRoundTripTime = positiveDelta(stats.totalRoundTripTime, this.totalRoundTripTime) - deltaRoundTripTimeMeasurements L128:
this.deltaRoundTripTimeMeasurements = positiveDelta(stats.roundTripTimeMeasurements, this.roundTripTimeMeasurements) - avgRoundTripTimeInSec L130:
this.avgRoundTripTimeInSec = this.deltaTotalRoundTripTime !== undefined && this.deltaRoundTripTimeMeasurements !== undefined && this.deltaRoundTripTimeMeasurements > 0 ? this.deltaTotalRoundTripTime / this.deltaRoundTripTimeMeasurements : undefined - deltaFractionLost L138:
this.deltaFractionLost = totalDelta > 0 ? this.deltaPacketsLost / totalDelta : 0.0
Exact wire projection
public createSample(): RemoteInboundRtpStats {
return {
timestamp: this.timestamp,
id: this.id,
ssrc: this.ssrc,
kind: this.kind,
transportId: this.transportId,
codecId: this.codecId,
packetsReceived: this.packetsReceived,
packetsReceivedWithEct1: this.packetsReceivedWithEct1,
packetsReceivedWithCe: this.packetsReceivedWithCe,
packetsReportedAsLost: this.packetsReportedAsLost,
packetsReportedAsLostButRecovered: this.packetsReportedAsLostButRecovered,
packetsLost: this.packetsLost,
jitter: this.jitter,
localId: this.localId,
roundTripTime: this.roundTripTime,
totalRoundTripTime: this.totalRoundTripTime,
fractionLost: this.fractionLost,
roundTripTimeMeasurements: this.roundTripTimeMeasurements,
packetsWithBleachedEct1Marking: this.packetsWithBleachedEct1Marking,
attachments: this.attachments,
};
}RemoteOutboundRtpMonitor
| Public field / getter | Type or declaration | Source |
|---|---|---|
timestamp | number | L8 |
id | string | L9 |
ssrc | number | L10 |
kind | string | L11 |
transportId | string / undefined | L12 |
codecId | string / undefined | L13 |
packetsSent | number / undefined | L14 |
bytesSent | number / undefined | L15 |
deltaPacketsSent | number / undefined | L18 |
deltaBytesSent | number / undefined | L19 |
localId | string / undefined | L20 |
remoteTimestamp | number / undefined | L21 |
reportsSent | number / undefined | L22 |
roundTripTime | number / undefined | L23 |
totalRoundTripTime | number / undefined | L24 |
roundTripTimeMeasurements | number / undefined | L25 |
bitrate | number / undefined | L28 |
deltaTime | number / undefined | L31 |
attachments | Record<string, unknown> / undefined | L36 |
appData | Record<string, unknown> / undefined | L38 |
visited | boolean | L52 |
statsClockTime | public statsClockTime = 0; | L61 |
Assignment and formula index
- id L44:
this.id = options.id - timestamp L45:
this.timestamp = options.timestamp - ssrc L46:
this.ssrc = options.ssrc - kind L47:
this.kind = options.kind - deltaTime L91:
this.deltaTime = 0 - deltaPacketsSent L92:
this.deltaPacketsSent = undefined - deltaBytesSent L93:
this.deltaBytesSent = undefined - deltaTime L98:
this.deltaTime = elapsedInMs - statsClockTime L99:
this.statsClockTime += elapsedInMs - deltaPacketsSent L100:
this.deltaPacketsSent = positiveDelta(stats.packetsSent, this.packetsSent) - deltaBytesSent L101:
this.deltaBytesSent = positiveDelta(stats.bytesSent, this.bytesSent)
Exact wire projection
public createSample(): RemoteOutboundRtpStats {
return {
id: this.id,
timestamp: this.timestamp,
ssrc: this.ssrc,
kind: this.kind,
transportId: this.transportId,
codecId: this.codecId,
packetsSent: this.packetsSent,
bytesSent: this.bytesSent,
localId: this.localId,
remoteTimestamp: this.remoteTimestamp,
reportsSent: this.reportsSent,
roundTripTime: this.roundTripTime,
totalRoundTripTime: this.totalRoundTripTime,
roundTripTimeMeasurements: this.roundTripTimeMeasurements,
attachments: this.attachments,
};
}SelectedIcePath
| Public field / getter | Type or declaration | Source |
|---|---|---|
createdAt | public readonly createdAt = Date.now(); | L88 |
updatedAt | public updatedAt = Date.now(); | L89 |
closed | public closed = false; | L90 |
durations | IcePathDurations | L93 |
pathSwitches | public pathSwitches = 0; | L95 |
directToRelaySwitches | public directToRelaySwitches = 0; | L96 |
relayToDirectSwitches | public relayToDirectSwitches = 0; | L97 |
relayProtocolSwitches | public relayProtocolSwitches = 0; | L98 |
turnServerSwitches | public turnServerSwitches = 0; | L99 |
firstRelaySelectedAt | number | L102 |
lastSwitchedAt | number | L103 |
totalBytesSent | public totalBytesSent = 0; | L105 |
totalBytesReceived | public totalBytesReceived = 0; | L106 |
totalPacketsSent | public totalPacketsSent = 0; | L107 |
totalPacketsReceived | public totalPacketsReceived = 0; | L108 |
relayBytesSent | public relayBytesSent = 0; | L111 |
relayBytesReceived | public relayBytesReceived = 0; | L112 |
relayPacketsSent | public relayPacketsSent = 0; | L113 |
relayPacketsReceived | public relayPacketsReceived = 0; | L114 |
appData | Record<string, unknown> / undefined | L126 |
pair | IceCandidatePairMonitor | L149 |
localCandidate | public get localCandidate() { | L153 |
remoteCandidate | public get remoteCandidate() { | L157 |
iceTransport | public get iceTransport() { | L161 |
pairId | public get pairId() { | L167 |
transportId | public get transportId() { | L171 |
kind | IcePathKind | L175 |
usingTurn | boolean | L179 |
usingTcp | boolean | L183 |
relayProtocol | public get relayProtocol() { | L187 |
turnUrl | public get turnUrl() { | L191 |
turnServer | public get turnServer() { | L195 |
tuple | public get tuple() { | L199 |
protocol | public get protocol() { | L203 |
localCandidateType | public get localCandidateType() { | L207 |
remoteCandidateType | public get remoteCandidateType() { | L211 |
localAddress | public get localAddress() { | L215 |
localPort | public get localPort() { | L219 |
localAddressFamily | public get localAddressFamily() { | L223 |
remoteAddress | public get remoteAddress() { | L227 |
remotePort | public get remotePort() { | L231 |
remoteAddressFamily | public get remoteAddressFamily() { | L235 |
currentRoundTripTime | public get currentRoundTripTime() { | L239 |
state | public get state() { | L243 |
durationInMs | number | L250 |
relayDurationInMs | number | L255 |
timeToFirstRelayInMs | number / undefined | L266 |
relayBytesRatio | number / undefined | L271 |
Assignment and formula index
- firstRelaySelectedAt L139:
this.firstRelaySelectedAt = this.createdAt - durations[previousKind] L311:
this.durations[previousKind] += Math.max(0, now - this._kindSince) - updatedAt L314:
this.updatedAt = now - firstRelaySelectedAt L323:
this.firstRelaySelectedAt = now - lastSwitchedAt L340:
this.lastSwitchedAt = now - closed L370:
this.closed = true - durations[this._kind] L372:
this.durations[this._kind] += Math.max(0, Date.now() - this._kindSince) - totalBytesSent L384:
this.totalBytesSent += bytesSent - totalBytesReceived L385:
this.totalBytesReceived += bytesReceived - totalPacketsSent L386:
this.totalPacketsSent += packetsSent - totalPacketsReceived L387:
this.totalPacketsReceived += packetsReceived - relayBytesSent L391:
this.relayBytesSent += bytesSent - relayBytesReceived L392:
this.relayBytesReceived += bytesReceived - relayPacketsSent L393:
this.relayPacketsSent += packetsSent - relayPacketsReceived L394:
this.relayPacketsReceived += packetsReceived