File tree 4 files changed +65
-0
lines changed
4 files changed +65
-0
lines changed Original file line number Diff line number Diff line change
1
+ import { isDtxLikeBehavior } from '../helpers/streams' ;
1
2
import {
2
3
IssueDetectorResult ,
3
4
IssueReason ,
@@ -71,6 +72,12 @@ class FrozenVideoTrackDetector extends BaseIssueDetector {
71
72
return undefined ;
72
73
}
73
74
75
+ const isDtx = isDtxLikeBehavior ( videoStream . ssrc , allLastProcessedStats ) ;
76
+ if ( isDtx ) {
77
+ // DTX-like behavior detected, ignoring freezes check
78
+ return undefined ;
79
+ }
80
+
74
81
const deltaFreezeCount = videoStream . freezeCount - ( prevStat . freezeCount ?? 0 ) ;
75
82
const deltaFreezesTimeMs = ( videoStream . totalFreezesDuration - ( prevStat . totalFreezesDuration ?? 0 ) ) * 1000 ;
76
83
const avgFreezeDurationMs = deltaFreezeCount > 0 ? deltaFreezesTimeMs / deltaFreezeCount : 0 ;
Original file line number Diff line number Diff line change 1
1
import { calculateVolatility } from '../helpers/calc' ;
2
+ import { isDtxLikeBehavior } from '../helpers/streams' ;
2
3
import {
3
4
IssueDetectorResult ,
4
5
IssueReason ,
@@ -84,6 +85,12 @@ class VideoDecoderIssueDetector extends BaseIssueDetector {
84
85
return undefined ;
85
86
}
86
87
88
+ const isDtx = isDtxLikeBehavior ( incomeVideoStream . ssrc , allProcessedStats ) ;
89
+ if ( isDtx ) {
90
+ // DTX-like behavior detected, ignoring FPS volatility check
91
+ return undefined ;
92
+ }
93
+
87
94
const volatility = calculateVolatility ( allFps ) ;
88
95
89
96
if ( volatility > this . #volatilityThreshold) {
Original file line number Diff line number Diff line change 1
1
export const calculateMean = ( values : number [ ] ) => values . reduce ( ( acc , val ) => acc + val , 0 ) / values . length ;
2
2
3
+ export const calculateVariance = ( mean : number , values : number [ ] ) => values
4
+ . reduce ( ( sum , val ) => sum + ( val - mean ) ** 2 , 0 ) / values . length ;
5
+
6
+ export const calculateStandardDeviation = ( values : number [ ] ) => {
7
+ const mean = calculateMean ( values ) ;
8
+ const variance = calculateVariance ( mean , values ) ;
9
+ return Math . sqrt ( variance ) ;
10
+ } ;
11
+
3
12
export const calculateVolatility = ( values : number [ ] ) => {
4
13
if ( values . length === 0 ) {
5
14
throw new Error ( 'Cannot calculate volatility for empty array' ) ;
Original file line number Diff line number Diff line change
1
+ import { WebRTCStatsParsedWithNetworkScores } from '../types' ;
2
+ import { calculateStandardDeviation } from './calc' ;
3
+
4
+ export const isDtxLikeBehavior = (
5
+ ssrc : number ,
6
+ allProcessedStats : WebRTCStatsParsedWithNetworkScores [ ] ,
7
+ stdDevThreshold = 30 ,
8
+ ) : boolean => {
9
+ const frameIntervals : number [ ] = [ ] ;
10
+ for ( let i = 1 ; i < allProcessedStats . length - 1 ; i += 1 ) {
11
+ const videoStreamStats = allProcessedStats [ i ] ?. video ?. inbound . find (
12
+ ( stream ) => stream . ssrc === ssrc ,
13
+ ) ;
14
+
15
+ if ( ! videoStreamStats ) {
16
+ continue ;
17
+ }
18
+
19
+ const previousVideoStreamStats = allProcessedStats [ i - 1 ] ?. video ?. inbound ?. find (
20
+ ( stream ) => stream . ssrc === ssrc ,
21
+ ) ;
22
+
23
+ if ( ! videoStreamStats || ! previousVideoStreamStats ) {
24
+ continue ;
25
+ }
26
+
27
+ const deltaTime = videoStreamStats . timestamp - previousVideoStreamStats . timestamp ;
28
+ const deltaFrames = videoStreamStats . framesDecoded - previousVideoStreamStats . framesDecoded ;
29
+
30
+ if ( deltaFrames > 0 ) {
31
+ const frameInterval = deltaTime / deltaFrames ; // Average time per frame
32
+ frameIntervals . push ( frameInterval ) ;
33
+ }
34
+ }
35
+
36
+ if ( frameIntervals . length <= 1 ) {
37
+ return false ;
38
+ }
39
+
40
+ const stdDev = calculateStandardDeviation ( frameIntervals ) ;
41
+ return stdDev > stdDevThreshold ;
42
+ } ;
You can’t perform that action at this time.
0 commit comments