@@ -384,7 +384,7 @@ struct ast_rtp {
384
384
unsigned int txcount ; /*!< How many packets have we sent? */
385
385
unsigned int txoctetcount ; /*!< How many octets have we sent? (txcount*160)*/
386
386
unsigned int cycles ; /*!< Shifted count of sequence number cycles */
387
- double rxjitter ; /*!< Interarrival jitter at the moment in seconds */
387
+ double rxjitter ; /*!< Interarrival jitter at the moment in seconds to be reported */
388
388
double rxtransit ; /*!< Relative transit time for previous packet */
389
389
struct ast_format * lasttxformat ;
390
390
struct ast_format * lastrxformat ;
@@ -511,34 +511,36 @@ struct ast_rtcp {
511
511
unsigned int reported_jitter ; /*!< The contents of their last jitter entry in the RR */
512
512
unsigned int reported_lost ; /*!< Reported lost packets in their RR */
513
513
514
- double reported_maxjitter ;
515
- double reported_minjitter ;
516
- double reported_normdev_jitter ;
517
- double reported_stdev_jitter ;
518
- unsigned int reported_jitter_count ;
519
-
520
- double reported_maxlost ;
521
- double reported_minlost ;
522
- double reported_normdev_lost ;
523
- double reported_stdev_lost ;
524
-
525
- double rxlost ;
526
- double maxrxlost ;
527
- double minrxlost ;
528
- double normdev_rxlost ;
529
- double stdev_rxlost ;
530
- unsigned int rxlost_count ;
531
-
532
- double maxrxjitter ;
533
- double minrxjitter ;
534
- double normdev_rxjitter ;
535
- double stdev_rxjitter ;
536
- unsigned int rxjitter_count ;
537
- double maxrtt ;
538
- double minrtt ;
539
- double normdevrtt ;
540
- double stdevrtt ;
541
- unsigned int rtt_count ;
514
+ double reported_maxjitter ; /*!< Maximum reported interarrival jitter */
515
+ double reported_minjitter ; /*!< Minimum reported interarrival jitter */
516
+ double reported_normdev_jitter ; /*!< Mean of reported interarrival jitter */
517
+ double reported_stdev_jitter ; /*!< Standard deviation of reported interarrival jitter */
518
+ unsigned int reported_jitter_count ; /*!< Reported interarrival jitter count */
519
+
520
+ double reported_maxlost ; /*!< Maximum reported packets lost */
521
+ double reported_minlost ; /*!< Minimum reported packets lost */
522
+ double reported_normdev_lost ; /*!< Mean of reported packets lost */
523
+ double reported_stdev_lost ; /*!< Standard deviation of reported packets lost */
524
+ unsigned int reported_lost_count ; /*!< Reported packets lost count */
525
+
526
+ double rxlost ; /*!< Calculated number of lost packets since last report */
527
+ double maxrxlost ; /*!< Maximum calculated lost number of packets between reports */
528
+ double minrxlost ; /*!< Minimum calculated lost number of packets between reports */
529
+ double normdev_rxlost ; /*!< Mean of calculated lost packets between reports */
530
+ double stdev_rxlost ; /*!< Standard deviation of calculated lost packets between reports */
531
+ unsigned int rxlost_count ; /*!< Calculated lost packets sample count */
532
+
533
+ double maxrxjitter ; /*!< Maximum of calculated interarrival jitter */
534
+ double minrxjitter ; /*!< Minimum of calculated interarrival jitter */
535
+ double normdev_rxjitter ; /*!< Mean of calculated interarrival jitter */
536
+ double stdev_rxjitter ; /*!< Standard deviation of calculated interarrival jitter */
537
+ unsigned int rxjitter_count ; /*!< Calculated interarrival jitter count */
538
+
539
+ double maxrtt ; /*!< Maximum of calculated round trip time */
540
+ double minrtt ; /*!< Minimum of calculated round trip time */
541
+ double normdevrtt ; /*!< Mean of calculated round trip time */
542
+ double stdevrtt ; /*!< Standard deviation of calculated round trip time */
543
+ unsigned int rtt_count ; /*!< Calculated round trip time count */
542
544
543
545
/* VP8: sequence number for the RTCP FIR FCI */
544
546
int firseq ;
@@ -3317,49 +3319,32 @@ static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
3317
3319
return interval ;
3318
3320
}
3319
3321
3320
- /*! \brief Calculate normal deviation */
3321
- static double normdev_compute (double normdev , double sample , unsigned int sample_count )
3322
+ static void calc_mean_and_standard_deviation (double new_sample , double * mean , double * std_dev , unsigned int * count )
3322
3323
{
3323
- normdev = normdev * sample_count + sample ;
3324
- sample_count ++ ;
3324
+ double delta1 ;
3325
+ double delta2 ;
3325
3326
3326
- /*
3327
- It's possible the sample_count hits the maximum value and back to 0.
3328
- Set to 1 to prevent the divide by zero crash if the sample_count is 0.
3329
- */
3330
- if (sample_count == 0 ) {
3331
- sample_count = 1 ;
3332
- }
3333
-
3334
- return normdev / sample_count ;
3335
- }
3327
+ /* First convert the standard deviation back into a sum of squares. */
3328
+ double last_sum_of_squares = (* std_dev ) * (* std_dev ) * (* count ?: 1 );
3336
3329
3337
- static double stddev_compute (double stddev , double sample , double normdev , double normdev_curent , unsigned int sample_count )
3338
- {
3339
- /*
3340
- for the formula check http://www.cs.umd.edu/~austinjp/constSD.pdf
3341
- return sqrt( (sample_count*pow(stddev,2) + sample_count*pow((sample-normdev)/(sample_count+1),2) + pow(sample-normdev_curent,2)) / (sample_count+1));
3342
- we can compute the sigma^2 and that way we would have to do the sqrt only 1 time at the end and would save another pow 2 compute
3343
- optimized formula
3344
- */
3345
- #define SQUARE (x ) ((x) * (x))
3346
-
3347
- stddev = sample_count * stddev ;
3348
- sample_count ++ ;
3330
+ if (++ (* count ) == 0 ) {
3331
+ /* Avoid potential divide by zero on an overflow */
3332
+ * count = 1 ;
3333
+ }
3349
3334
3350
3335
/*
3351
- It's possible the sample_count hits the maximum value and back to 0.
3352
- Set to 1 to prevent the divide by zero crash if the sample_count is 0.
3336
+ * Below is an implementation of Welford's online algorithm [1] for calculating
3337
+ * mean and variance in a single pass.
3338
+ *
3339
+ * [1] https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
3353
3340
*/
3354
- if (sample_count == 0 ) {
3355
- sample_count = 1 ;
3356
- }
3357
3341
3358
- return stddev +
3359
- ( sample_count * SQUARE ( ( sample - normdev ) / sample_count ) ) +
3360
- ( SQUARE ( sample - normdev_curent ) / sample_count ) ;
3342
+ delta1 = new_sample - * mean ;
3343
+ * mean += ( delta1 / * count );
3344
+ delta2 = new_sample - * mean ;
3361
3345
3362
- #undef SQUARE
3346
+ /* Now calculate the new variance, and subsequent standard deviation */
3347
+ * std_dev = sqrt ((last_sum_of_squares + (delta1 * delta2 )) / * count );
3363
3348
}
3364
3349
3365
3350
static int create_new_socket (const char * type , int af )
@@ -4434,7 +4419,6 @@ static void calculate_lost_packet_statistics(struct ast_rtp *rtp,
4434
4419
unsigned int expected_packets ;
4435
4420
unsigned int expected_interval ;
4436
4421
unsigned int received_interval ;
4437
- double rxlost_current ;
4438
4422
int lost_interval ;
4439
4423
4440
4424
/* Compute statistics */
@@ -4464,6 +4448,13 @@ static void calculate_lost_packet_statistics(struct ast_rtp *rtp,
4464
4448
/* Update RTCP statistics */
4465
4449
rtp -> rtcp -> received_prior = rtp -> rxcount ;
4466
4450
rtp -> rtcp -> expected_prior = expected_packets ;
4451
+
4452
+ /*
4453
+ * While rxlost represents the number of packets lost since the last report was sent, for
4454
+ * the calculations below it should be thought of as a single sample. Thus min/max are the
4455
+ * lowest/highest sample value seen, and the mean is the average number of packets lost
4456
+ * between each report. As such rxlost_count only needs to be incremented per report.
4457
+ */
4467
4458
if (lost_interval <= 0 ) {
4468
4459
rtp -> rtcp -> rxlost = 0 ;
4469
4460
} else {
@@ -4478,16 +4469,9 @@ static void calculate_lost_packet_statistics(struct ast_rtp *rtp,
4478
4469
if (lost_interval > rtp -> rtcp -> maxrxlost ) {
4479
4470
rtp -> rtcp -> maxrxlost = rtp -> rtcp -> rxlost ;
4480
4471
}
4481
- rxlost_current = normdev_compute (rtp -> rtcp -> normdev_rxlost ,
4482
- rtp -> rtcp -> rxlost ,
4483
- rtp -> rtcp -> rxlost_count );
4484
- rtp -> rtcp -> stdev_rxlost = stddev_compute (rtp -> rtcp -> stdev_rxlost ,
4485
- rtp -> rtcp -> rxlost ,
4486
- rtp -> rtcp -> normdev_rxlost ,
4487
- rxlost_current ,
4488
- rtp -> rtcp -> rxlost_count );
4489
- rtp -> rtcp -> normdev_rxlost = rxlost_current ;
4490
- rtp -> rtcp -> rxlost_count ++ ;
4472
+
4473
+ calc_mean_and_standard_deviation (rtp -> rtcp -> rxlost , & rtp -> rtcp -> normdev_rxlost ,
4474
+ & rtp -> rtcp -> stdev_rxlost , & rtp -> rtcp -> rxlost_count );
4491
4475
}
4492
4476
4493
4477
static int ast_rtcp_generate_report (struct ast_rtp_instance * instance , unsigned char * rtcpheader ,
@@ -5423,7 +5407,6 @@ static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int t
5423
5407
double prog ;
5424
5408
int rate = ast_rtp_get_rate (rtp -> f .subclass .format );
5425
5409
5426
- double normdev_rxjitter_current ;
5427
5410
if ((!rtp -> rxcore .tv_sec && !rtp -> rxcore .tv_usec ) || mark ) {
5428
5411
gettimeofday (& rtp -> rxcore , NULL );
5429
5412
rtp -> drxcore = (double ) rtp -> rxcore .tv_sec + (double ) rtp -> rxcore .tv_usec / 1000000 ;
@@ -5458,11 +5441,8 @@ static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int t
5458
5441
if (rtp -> rtcp && rtp -> rxjitter < rtp -> rtcp -> minrxjitter )
5459
5442
rtp -> rtcp -> minrxjitter = rtp -> rxjitter ;
5460
5443
5461
- normdev_rxjitter_current = normdev_compute (rtp -> rtcp -> normdev_rxjitter ,rtp -> rxjitter ,rtp -> rtcp -> rxjitter_count );
5462
- rtp -> rtcp -> stdev_rxjitter = stddev_compute (rtp -> rtcp -> stdev_rxjitter ,rtp -> rxjitter ,rtp -> rtcp -> normdev_rxjitter ,normdev_rxjitter_current ,rtp -> rtcp -> rxjitter_count );
5463
-
5464
- rtp -> rtcp -> normdev_rxjitter = normdev_rxjitter_current ;
5465
- rtp -> rtcp -> rxjitter_count ++ ;
5444
+ calc_mean_and_standard_deviation (rtp -> rxjitter , & rtp -> rtcp -> normdev_rxjitter ,
5445
+ & rtp -> rtcp -> stdev_rxjitter , & rtp -> rtcp -> rxjitter_count );
5466
5446
}
5467
5447
}
5468
5448
@@ -5778,7 +5758,6 @@ static int update_rtt_stats(struct ast_rtp *rtp, unsigned int lsr, unsigned int
5778
5758
unsigned int rtt_lsw ;
5779
5759
unsigned int lsr_a ;
5780
5760
unsigned int rtt ;
5781
- double normdevrtt_current ;
5782
5761
5783
5762
gettimeofday (& now , NULL );
5784
5763
timeval2ntp (now , & msw , & lsw );
@@ -5815,16 +5794,8 @@ static int update_rtt_stats(struct ast_rtp *rtp, unsigned int lsr, unsigned int
5815
5794
rtp -> rtcp -> maxrtt = rtp -> rtcp -> rtt ;
5816
5795
}
5817
5796
5818
- normdevrtt_current = normdev_compute (rtp -> rtcp -> normdevrtt ,
5819
- rtp -> rtcp -> rtt ,
5820
- rtp -> rtcp -> rtt_count );
5821
- rtp -> rtcp -> stdevrtt = stddev_compute (rtp -> rtcp -> stdevrtt ,
5822
- rtp -> rtcp -> rtt ,
5823
- rtp -> rtcp -> normdevrtt ,
5824
- normdevrtt_current ,
5825
- rtp -> rtcp -> rtt_count );
5826
- rtp -> rtcp -> normdevrtt = normdevrtt_current ;
5827
- rtp -> rtcp -> rtt_count ++ ;
5797
+ calc_mean_and_standard_deviation (rtp -> rtcp -> rtt , & rtp -> rtcp -> normdevrtt ,
5798
+ & rtp -> rtcp -> stdevrtt , & rtp -> rtcp -> rtt_count );
5828
5799
5829
5800
return 0 ;
5830
5801
}
@@ -5836,7 +5807,6 @@ static int update_rtt_stats(struct ast_rtp *rtp, unsigned int lsr, unsigned int
5836
5807
static void update_jitter_stats (struct ast_rtp * rtp , unsigned int ia_jitter )
5837
5808
{
5838
5809
double reported_jitter ;
5839
- double reported_normdev_jitter_current ;
5840
5810
5841
5811
rtp -> rtcp -> reported_jitter = ia_jitter ;
5842
5812
reported_jitter = (double ) rtp -> rtcp -> reported_jitter ;
@@ -5849,9 +5819,9 @@ static void update_jitter_stats(struct ast_rtp *rtp, unsigned int ia_jitter)
5849
5819
if (reported_jitter > rtp -> rtcp -> reported_maxjitter ) {
5850
5820
rtp -> rtcp -> reported_maxjitter = reported_jitter ;
5851
5821
}
5852
- reported_normdev_jitter_current = normdev_compute ( rtp -> rtcp -> reported_normdev_jitter , reported_jitter , rtp -> rtcp -> reported_jitter_count );
5853
- rtp -> rtcp -> reported_stdev_jitter = stddev_compute ( rtp -> rtcp -> reported_stdev_jitter , reported_jitter , rtp -> rtcp -> reported_normdev_jitter , reported_normdev_jitter_current , rtp -> rtcp -> reported_jitter_count );
5854
- rtp -> rtcp -> reported_normdev_jitter = reported_normdev_jitter_current ;
5822
+
5823
+ calc_mean_and_standard_deviation ( reported_jitter , & rtp -> rtcp -> reported_normdev_jitter ,
5824
+ & rtp -> rtcp -> reported_stdev_jitter , & rtp -> rtcp -> reported_jitter_count ) ;
5855
5825
}
5856
5826
5857
5827
/*!
@@ -5861,11 +5831,10 @@ static void update_jitter_stats(struct ast_rtp *rtp, unsigned int ia_jitter)
5861
5831
static void update_lost_stats (struct ast_rtp * rtp , unsigned int lost_packets )
5862
5832
{
5863
5833
double reported_lost ;
5864
- double reported_normdev_lost_current ;
5865
5834
5866
5835
rtp -> rtcp -> reported_lost = lost_packets ;
5867
5836
reported_lost = (double )rtp -> rtcp -> reported_lost ;
5868
- if (rtp -> rtcp -> reported_jitter_count == 0 ) {
5837
+ if (rtp -> rtcp -> reported_lost_count == 0 ) {
5869
5838
rtp -> rtcp -> reported_minlost = reported_lost ;
5870
5839
}
5871
5840
if (reported_lost < rtp -> rtcp -> reported_minlost ) {
@@ -5874,9 +5843,9 @@ static void update_lost_stats(struct ast_rtp *rtp, unsigned int lost_packets)
5874
5843
if (reported_lost > rtp -> rtcp -> reported_maxlost ) {
5875
5844
rtp -> rtcp -> reported_maxlost = reported_lost ;
5876
5845
}
5877
- reported_normdev_lost_current = normdev_compute ( rtp -> rtcp -> reported_normdev_lost , reported_lost , rtp -> rtcp -> reported_jitter_count );
5878
- rtp -> rtcp -> reported_stdev_lost = stddev_compute ( rtp -> rtcp -> reported_stdev_lost , reported_lost , rtp -> rtcp -> reported_normdev_lost , reported_normdev_lost_current , rtp -> rtcp -> reported_jitter_count );
5879
- rtp -> rtcp -> reported_normdev_lost = reported_normdev_lost_current ;
5846
+
5847
+ calc_mean_and_standard_deviation ( reported_lost , & rtp -> rtcp -> reported_normdev_lost ,
5848
+ & rtp -> rtcp -> reported_stdev_lost , & rtp -> rtcp -> reported_lost_count ) ;
5880
5849
}
5881
5850
5882
5851
/*! \pre instance is locked */
@@ -6449,7 +6418,6 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, s
6449
6418
}
6450
6419
update_jitter_stats (rtp , report_block -> ia_jitter );
6451
6420
update_lost_stats (rtp , report_block -> lost_count .packets );
6452
- rtp -> rtcp -> reported_jitter_count ++ ;
6453
6421
6454
6422
if (rtcp_debug_test_addr (addr )) {
6455
6423
ast_verbose (" Fraction lost: %d\n" , report_block -> lost_count .fraction );
0 commit comments