forked from baresip/baresip
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetric.c
111 lines (78 loc) · 1.78 KB
/
metric.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* @file metric.c Metrics for media transmit/receive
*
* Copyright (C) 2010 Creytiv.com
*/
#include <re.h>
#include <baresip.h>
#include "core.h"
enum {TMR_INTERVAL = 3};
static void tmr_handler(void *arg)
{
struct metric *metric = arg;
const uint64_t now = tmr_jiffies();
uint32_t diff;
tmr_start(&metric->tmr, TMR_INTERVAL * 1000, tmr_handler, metric);
lock_write_get(metric->lock);
if (!metric->started)
goto out;
if (now <= metric->ts_last)
goto out;
if (metric->ts_last) {
uint32_t bytes = metric->n_bytes - metric->n_bytes_last;
diff = (uint32_t)(now - metric->ts_last);
metric->cur_bitrate = 1000 * 8 * bytes / diff;
}
/* Update counters */
metric->ts_last = now;
metric->n_bytes_last = metric->n_bytes;
out:
lock_rel(metric->lock);
}
static void metric_start(struct metric *metric)
{
if (metric->started)
return;
metric->ts_start = tmr_jiffies();
metric->started = true;
}
int metric_init(struct metric *metric)
{
int err;
if (!metric)
return EINVAL;
err = lock_alloc(&metric->lock);
if (err)
return err;
tmr_start(&metric->tmr, 100, tmr_handler, metric);
return 0;
}
void metric_reset(struct metric *metric)
{
if (!metric)
return;
tmr_cancel(&metric->tmr);
metric->lock = mem_deref(metric->lock);
}
/*
* NOTE: may be called from any thread
*/
void metric_add_packet(struct metric *metric, size_t packetsize)
{
if (!metric)
return;
lock_write_get(metric->lock);
if (!metric->started)
metric_start(metric);
metric->n_bytes += (uint32_t)packetsize;
metric->n_packets++;
lock_rel(metric->lock);
}
double metric_avg_bitrate(const struct metric *metric)
{
int diff;
if (!metric || !metric->ts_start)
return 0;
diff = (int)(tmr_jiffies() - metric->ts_start);
return 1000.0 * 8 * (double)metric->n_bytes / (double)diff;
}