summaryrefslogtreecommitdiff
path: root/src/metric.c
blob: f3e8d06bcabdb77531aa06c23e73f4fa7d0c46fe (plain)
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
/**
 * @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);

	if (!metric->started)
		return;

 	if (now <= metric->ts_last)
		return;

	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;
}


static void metric_start(struct metric *metric)
{
	if (metric->started)
		return;

	metric->ts_start = tmr_jiffies();

	metric->started = true;
}


void metric_init(struct metric *metric)
{
	if (!metric)
		return;

	tmr_start(&metric->tmr, 100, tmr_handler, metric);
}


void metric_reset(struct metric *metric)
{
	if (!metric)
		return;

	tmr_cancel(&metric->tmr);
}


void metric_add_packet(struct metric *metric, size_t packetsize)
{
	if (!metric)
		return;

	if (!metric->started)
		metric_start(metric);

	metric->n_bytes += (uint32_t)packetsize;
	metric->n_packets++;
}


uint32_t 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 * 8 * (metric->n_bytes / diff);
}