Schema 3.2.0

Entirely additive on the record level: no field was removed or renamed. Several counters were widened from int to long.

Added — ECN and RFC 8888 congestion feedback

Explicit Congestion Notification lets the network mark packets as “congestion experienced” instead of dropping them, and RFC 8888 defines the feedback report that carries per-packet arrival information back to the sender. Together they are the foundation of L4S-style congestion control.

InboundRtpStats

FieldTypeDescription
packetsReceivedWithEct1int optionalTotal RTP packets received for this SSRC marked with the ECT(1) marking
packetsReceivedWithCeint optionalTotal RTP packets received for this SSRC marked with the CE marking
packetsReportedAsLostint optionalTotal RTP packets for which an RFC 8888 report has been sent with a zero R bit
packetsReportedAsLostButRecoveredint optionalTotal RTP packets reported as lost but later recovered in a subsequent RFC 8888 report

RemoteInboundRtpStats

The same four fields, plus:

FieldTypeDescription
packetsWithBleachedEct1Markinglong optionalPackets with ECT(1) marking that were bleached by a middlebox

OutboundRtpStats

FieldTypeDescription
packetsSentWithEct1long optionalPackets sent with ECT(1) congestion marking

IceTransportStats

FieldTypeDescription
ccfbMessagesSentlong optionalCongestion Control Feedback messages sent on this transport
ccfbMessagesReceivedlong optionalCongestion Control Feedback messages received on this transport

Sparse by nature

Only browsers implementing ECN and RFC 8888 populate these. Treat every one of them as optional in your processing — most samples in the field will not carry them for some time.

packetsWithBleachedEct1Marking is the interesting one operationally: it says a middlebox on the path stripped the ECN marking, which silently disables the congestion signalling you thought you had.

Added — video quality measurement

PsnrSum (new record)

Peak signal-to-noise ratio per colour plane, nested in OutboundRtpStats.psnrSum.

FieldTypeDescription
ydoublePSNR value for the Y (luminance) component
udoublePSNR value for the U (chrominance) component
vdoublePSNR value for the V (chrominance) component

OutboundRtpStats

FieldTypeDescription
psnrSumPsnrSum optionalCumulative PSNR measurements for Y, U, V components
psnrMeasurementslong optionalTotal number of PSNR measurements collected
encodingIndexint optionalIndex of the encoding in the encodings array

encodingIndex is small but useful for simulcast: it identifies which configured encoding an outbound RTP stream corresponds to, without inferring it from rid or resolution.

Divide psnrSum by psnrMeasurements for the average PSNR per plane over the session.

Changed — qualityLimitationDurations

Restructured from a loose map into a named record:

type QualityLimitationDurations = {
    none: number;       // seconds with no quality limitation
    cpu: number;        // seconds limited by CPU
    bandwidth: number;  // seconds limited by bandwidth
    other: number;      // seconds limited for other reasons
};

Why this matters for analysis

qualityLimitationReason tells you what is limiting the encoder right now — a single sample of a state that flickers. qualityLimitationDurations is cumulative, so differencing it across two samples gives you how many seconds of this interval were CPU-limited versus bandwidth-limited. That is the number that actually answers “was this call CPU-bound or network-bound?”.

CallHealthAggregator in observer-js surfaces exactly this as health.qualityLimitation.

Changed — counter widening

Byte and packet counters that could realistically exceed 32 bits on long, high-bitrate sessions were widened from int to long across the inbound, remote-inbound, outbound and transport records.

Changed — infrastructure

  • frozen added as a state on IceCandidatePairStats.
  • Node 22 across the CI workflows.
  • Protobuf handling reworked, dependencies updated, CONTRIBUTING.md added.

Compatibility

Additive on the record level, but remember that protobuf field numbers derive from sorted field order — new fields inserted before existing ones in the sort renumber what follows. Keep encoder and decoder on matching versions.

← Back to version history · 3.1.0 →