@@ -412,6 +412,19 @@ PeerConnectionAnalyzer.prototype = {
412
412
packetsLost [ kind ] = this . _packetsLost [ kind ] . getLastRawValue ( )
413
413
}
414
414
415
+ // In some (also strange) cases a newer stat may report a lower
416
+ // value than a previous one (it happens sometimes with garbage
417
+ // remote reports in simulcast video that cause the values to
418
+ // overflow, although it was also seen with a small value regression
419
+ // when enabling video). If that happens the stats are reset to
420
+ // prevent distorting the analysis with negative packet counts; note
421
+ // that in this case the previous value is not kept because it is
422
+ // not just an isolated wrong value, all the following stats
423
+ // increase from the regressed value.
424
+ if ( packets [ kind ] >= 0 && packets [ kind ] < this . _packets [ kind ] . getLastRawValue ( ) ) {
425
+ this . _resetStats ( kind )
426
+ }
427
+
415
428
this . _addStats ( kind , packets [ kind ] , packetsLost [ kind ] , timestamp [ kind ] , roundTripTime [ kind ] )
416
429
}
417
430
} ,
@@ -482,12 +495,13 @@ PeerConnectionAnalyzer.prototype = {
482
495
* The stats reported by the browser can sometimes stall for a second (or
483
496
* more, but typically they stall only for a single report). When that
484
497
* happens the stats are still reported, but with the same number of packets
485
- * as in the previous report (timestamp and round trip time are updated,
486
- * though). In that case the given stats are not added yet to the average
487
- * stats; they are kept on hold until more stats are provided by the browser
488
- * and it can be determined if the previous stats were stalled or not. If
489
- * they were stalled the previous and new stats are distributed, and if they
490
- * were not they are added as is to the average stats.
498
+ * as in the previous report (timestamp and round trip time may be updated
499
+ * or not, apparently depending on browser version and/or Janus version). In
500
+ * that case the given stats are not added yet to the average stats; they
501
+ * are kept on hold until more stats are provided by the browser and it can
502
+ * be determined if the previous stats were stalled or not. If they were
503
+ * stalled the previous and new stats are distributed, and if they were not
504
+ * they are added as is to the average stats.
491
505
*
492
506
* @param {string } kind the type of the stats ("audio" or "video")
493
507
* @param {number } packets the cumulative number of packets
@@ -552,6 +566,18 @@ PeerConnectionAnalyzer.prototype = {
552
566
let packetsLostTotal = 0
553
567
let timestampsTotal = 0
554
568
569
+ // If the first timestamp stalled it is assumed that all of them
570
+ // stalled and are thus evenly distributed based on the new timestamp.
571
+ if ( this . _stagedTimestamps [ kind ] [ 0 ] === timestampsBase ) {
572
+ const lastTimestamp = this . _stagedTimestamps [ kind ] [ this . _stagedTimestamps [ kind ] . length - 1 ]
573
+ const timestampsTotalDifference = lastTimestamp - timestampsBase
574
+ const timestampsDelta = timestampsTotalDifference / this . _stagedTimestamps [ kind ] . length
575
+
576
+ for ( let i = 0 ; i < this . _stagedTimestamps [ kind ] . length - 1 ; i ++ ) {
577
+ this . _stagedTimestamps [ kind ] [ i ] += timestampsDelta * ( i + 1 )
578
+ }
579
+ }
580
+
555
581
for ( let i = 0 ; i < this . _stagedPackets [ kind ] . length ; i ++ ) {
556
582
packetsTotal += ( this . _stagedPackets [ kind ] [ i ] - packetsBase )
557
583
packetsBase = this . _stagedPackets [ kind ] [ i ]
@@ -578,7 +604,11 @@ PeerConnectionAnalyzer.prototype = {
578
604
packetsLostBase = this . _stagedPacketsLost [ kind ] [ i ]
579
605
580
606
// Timestamps and round trip time are not distributed, as those
581
- // values are properly updated even if the stats are stalled.
607
+ // values may be properly updated even if the stats are stalled. In
608
+ // case they were not timestamps were already evenly distributed
609
+ // above, and round trip time can not be distributed, as it is
610
+ // already provided in the stats as a relative value rather than a
611
+ // cumulative one.
582
612
}
583
613
} ,
584
614
@@ -628,11 +658,19 @@ PeerConnectionAnalyzer.prototype = {
628
658
} ,
629
659
630
660
_calculateConnectionQuality ( kind ) {
661
+ const packets = this . _packets [ kind ]
662
+ const packetsLost = this . _packetsLost [ kind ]
663
+ const timestamps = this . _timestamps [ kind ]
631
664
const packetsLostRatio = this . _packetsLostRatio [ kind ]
632
665
const packetsPerSecond = this . _packetsPerSecond [ kind ]
633
666
const roundTripTime = this . _roundTripTime [ kind ]
634
667
635
- if ( ! packetsLostRatio . hasEnoughData ( ) || ! packetsPerSecond . hasEnoughData ( ) ) {
668
+ // packetsLostRatio and packetsPerSecond are relative values, but they
669
+ // are calculated from cumulative values. Therefore, it is necessary to
670
+ // check if the cumulative values that are their source have enough data
671
+ // or not, rather than checking if the relative values themselves have
672
+ // enough data.
673
+ if ( ! packets . hasEnoughData ( ) || ! packetsLost . hasEnoughData ( ) || ! timestamps . hasEnoughData ( ) ) {
636
674
return CONNECTION_QUALITY . UNKNOWN
637
675
}
638
676
@@ -671,10 +709,13 @@ PeerConnectionAnalyzer.prototype = {
671
709
// quality to keep a smooth video, albeit on a lower resolution. Thus
672
710
// with a threshold of 10 packets issues can be detected too for videos,
673
711
// although only once they can not be further downscaled.
712
+ // Despite all of the above it has been observed that less than 10
713
+ // packets are sometimes sent without any connection problem (for
714
+ // example, when the background is blurred and the video quality is
715
+ // reduced due to being in a call with several participants), so for now
716
+ // it is only logged but not reported.
674
717
if ( packetsPerSecond . getWeightedAverage ( ) < 10 ) {
675
718
this . _logStats ( kind , 'Low packets per second: ' + packetsPerSecond . getWeightedAverage ( ) )
676
-
677
- return CONNECTION_QUALITY . VERY_BAD
678
719
}
679
720
680
721
if ( packetsLostRatioWeightedAverage > 0.3 ) {
0 commit comments