Skip to content

Commit b972e9f

Browse files
danxuliubackportbot[bot]
authored andcommitted
fix: Fix distributing staged stats when not updated three times in a row
The stats were supposed to be distributed once they had changed, but in practice they were always distributed, as the packet count is absolute rather than relative. Nevertheless, if the packet count did not change distributing them would have no effect. The problem could appear in the (rare) case of the timestamps not being updated three times in a row, as the distribution algorithm failed if the final timestamp was the same as the initial timestamp (causing NaN to be set for the packets and packets lost). Due to all that now the staged stats are always distributed before being commited (which is still done when the stats stalled for two seconds), although the distribution exits early if the timestamps did not change. Signed-off-by: Daniel Calviño Sánchez <[email protected]>
1 parent 6679282 commit b972e9f

File tree

2 files changed

+87
-5
lines changed

2 files changed

+87
-5
lines changed

src/utils/webrtc/analyzers/PeerConnectionAnalyzer.js

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -506,11 +506,10 @@ PeerConnectionAnalyzer.prototype = {
506506

507507
this._stageStats(kind, packets, packetsLost, timestamp, roundTripTime)
508508

509-
// If the packets have changed now it is assumed that the previous stats
510-
// were stalled.
511-
if (packets > 0) {
512-
this._distributeStagedStats(kind)
513-
}
509+
// Distributing the stats has no effect if the stats were not stalled
510+
// (that is, if the values are still unchanged, so it is probably an
511+
// actual connection problem rather than a stalled report).
512+
this._distributeStagedStats(kind)
514513

515514
while (this._stagedPackets[kind].length > 0) {
516515
const stagedPackets = this._stagedPackets[kind].shift()
@@ -550,6 +549,12 @@ PeerConnectionAnalyzer.prototype = {
550549
let packetsLostTotal = 0
551550
let timestampsTotal = 0
552551

552+
// If the last timestamp is still stalled there is nothing to
553+
// distribute.
554+
if (this._stagedTimestamps[kind][this._stagedTimestamps[kind].length - 1] === timestampsBase) {
555+
return
556+
}
557+
553558
// If the first timestamp stalled it is assumed that all of them
554559
// stalled and are thus evenly distributed based on the new timestamp.
555560
if (this._stagedTimestamps[kind][0] === timestampsBase) {

src/utils/webrtc/analyzers/PeerConnectionAnalyzer.spec.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3437,6 +3437,51 @@ describe('PeerConnectionAnalyzer', () => {
34373437
expect(peerConnectionAnalyzer._stagedRoundTripTime[kind]).toEqual([])
34383438
})
34393439

3440+
test.each([
3441+
['packet count repeated two times', 'audio'],
3442+
['packet count repeated two times', 'video'],
3443+
])('%s, %s', (name, kind) => {
3444+
peerConnectionAnalyzer._addStats(kind, 150, 40, 10000, 0.2)
3445+
peerConnectionAnalyzer._addStats(kind, 150, 40, 10000, 0.2)
3446+
peerConnectionAnalyzer._addStats(kind, 150, 40, 10000, 0.2)
3447+
3448+
expect(peerConnectionAnalyzer._packets[kind]._relativeValues).toEqual([0, 0, 0])
3449+
expect(peerConnectionAnalyzer._packetsLost[kind]._relativeValues).toEqual([0, 0, 0])
3450+
expect(peerConnectionAnalyzer._packetsLostRatio[kind]._relativeValues).toEqual([1.5, 1.5, 1.5])
3451+
expect(peerConnectionAnalyzer._timestamps[kind]._relativeValues).toEqual([0, 0])
3452+
expect(peerConnectionAnalyzer._timestampsForLogs[kind]._relativeValues).toEqual([0, 0, 0])
3453+
expect(peerConnectionAnalyzer._packetsPerSecond[kind]._relativeValues).toEqual([NaN, NaN, NaN])
3454+
expect(peerConnectionAnalyzer._roundTripTime[kind]._relativeValues).toEqual([0.2, 0.2, 0.2])
3455+
3456+
expect(peerConnectionAnalyzer._stagedPackets[kind]).toEqual([])
3457+
expect(peerConnectionAnalyzer._stagedPacketsLost[kind]).toEqual([])
3458+
expect(peerConnectionAnalyzer._stagedTimestamps[kind]).toEqual([])
3459+
expect(peerConnectionAnalyzer._stagedRoundTripTime[kind]).toEqual([])
3460+
})
3461+
3462+
test.each([
3463+
['packet count repeated two times then changed', 'audio'],
3464+
['packet count repeated two times then changed', 'video'],
3465+
])('%s, %s', (name, kind) => {
3466+
peerConnectionAnalyzer._addStats(kind, 150, 40, 10000, 0.2)
3467+
peerConnectionAnalyzer._addStats(kind, 150, 40, 10000, 0.2)
3468+
peerConnectionAnalyzer._addStats(kind, 150, 40, 10000, 0.2)
3469+
peerConnectionAnalyzer._addStats(kind, 300, 70, 13750, 0.3)
3470+
3471+
expect(peerConnectionAnalyzer._packets[kind]._relativeValues).toEqual([0, 0, 0, 150])
3472+
expect(peerConnectionAnalyzer._packetsLost[kind]._relativeValues).toEqual([0, 0, 0, 30])
3473+
expect(peerConnectionAnalyzer._packetsLostRatio[kind]._relativeValues).toEqual([1.5, 1.5, 1.5, 0.2])
3474+
expect(peerConnectionAnalyzer._timestamps[kind]._relativeValues).toEqual([0, 3750])
3475+
expect(peerConnectionAnalyzer._timestampsForLogs[kind]._relativeValues).toEqual([0, 0, 0, 3750])
3476+
expect(peerConnectionAnalyzer._packetsPerSecond[kind]._relativeValues).toEqual([NaN, NaN, NaN, 40])
3477+
expect(peerConnectionAnalyzer._roundTripTime[kind]._relativeValues).toEqual([0.2, 0.2, 0.2, 0.3])
3478+
3479+
expect(peerConnectionAnalyzer._stagedPackets[kind]).toEqual([])
3480+
expect(peerConnectionAnalyzer._stagedPacketsLost[kind]).toEqual([])
3481+
expect(peerConnectionAnalyzer._stagedTimestamps[kind]).toEqual([])
3482+
expect(peerConnectionAnalyzer._stagedRoundTripTime[kind]).toEqual([])
3483+
})
3484+
34403485
describe('distribute staged stats', () => {
34413486

34423487
const expectRelativeStagedStats = (kind, index, expectedPackets, expectedPacketsLost, expectedTimestamps, expectedRoundTripTime) => {
@@ -3502,6 +3547,20 @@ describe('PeerConnectionAnalyzer', () => {
35023547
expectRelativeStagedStats(kind, 1, 150, 40, 14000, 0.2)
35033548
})
35043549

3550+
test.each([
3551+
['two sets of fully repeated values', 'audio'],
3552+
['two sets of fully repeated values', 'video'],
3553+
])('%s, %s', (name, kind) => {
3554+
peerConnectionAnalyzer._commitStats(kind, 150, 40, 10000, 0.2)
3555+
peerConnectionAnalyzer._stageStats(kind, 150, 40, 10000, 0.2)
3556+
peerConnectionAnalyzer._stageStats(kind, 150, 40, 10000, 0.2)
3557+
3558+
peerConnectionAnalyzer._distributeStagedStats(kind)
3559+
3560+
expectRelativeStagedStats(kind, 0, 150, 40, 10000, 0.2)
3561+
expectRelativeStagedStats(kind, 1, 150, 40, 10000, 0.2)
3562+
})
3563+
35053564
test.each([
35063565
['several sets of different values with repeated timestamps', 'audio'],
35073566
['several sets of different values with repeated timestamps', 'video'],
@@ -3573,6 +3632,24 @@ describe('PeerConnectionAnalyzer', () => {
35733632
expectRelativeStagedStats(kind, 2, 150, 40, 17500, 0.2)
35743633
expectRelativeStagedStats(kind, 3, 150, 40, 20000, 0.2)
35753634
})
3635+
3636+
test.each([
3637+
['several sets of fully repeated values', 'audio'],
3638+
['several sets of fully repeated values', 'video'],
3639+
])('%s, %s', (name, kind) => {
3640+
peerConnectionAnalyzer._commitStats(kind, 150, 40, 10000, 0.2)
3641+
peerConnectionAnalyzer._stageStats(kind, 150, 40, 10000, 0.2)
3642+
peerConnectionAnalyzer._stageStats(kind, 150, 40, 10000, 0.2)
3643+
peerConnectionAnalyzer._stageStats(kind, 150, 40, 10000, 0.2)
3644+
peerConnectionAnalyzer._stageStats(kind, 150, 40, 10000, 0.2)
3645+
3646+
peerConnectionAnalyzer._distributeStagedStats(kind)
3647+
3648+
expectRelativeStagedStats(kind, 0, 150, 40, 10000, 0.2)
3649+
expectRelativeStagedStats(kind, 1, 150, 40, 10000, 0.2)
3650+
expectRelativeStagedStats(kind, 2, 150, 40, 10000, 0.2)
3651+
expectRelativeStagedStats(kind, 3, 150, 40, 10000, 0.2)
3652+
})
35763653
})
35773654
})
35783655
})

0 commit comments

Comments
 (0)