2022-06-03 13:25:32 +08:00
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
|
|
|
|
#include "Statistic.hpp"
|
2022-06-07 09:52:20 +08:00
|
|
|
|
|
2022-06-03 13:25:32 +08:00
|
|
|
|
namespace SRT {
|
2022-06-07 09:52:20 +08:00
|
|
|
|
|
2022-09-21 19:21:49 +08:00
|
|
|
|
PacketRecvRateContext::PacketRecvRateContext(TimePoint start)
|
|
|
|
|
|
: _last_arrive_time(start) {
|
|
|
|
|
|
for (size_t i = 0; i < SIZE; i++) {
|
|
|
|
|
|
_ts_arr[i] = 1000000;
|
|
|
|
|
|
_size_arr[i] = SRT_MAX_PAYLOAD_SIZE;
|
2022-06-07 09:52:20 +08:00
|
|
|
|
}
|
2022-09-21 19:21:49 +08:00
|
|
|
|
_cur_idx = 0;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void PacketRecvRateContext::inputPacket(TimePoint &ts,size_t len) {
|
|
|
|
|
|
auto tmp = DurationCountMicroseconds(ts - _last_arrive_time);
|
|
|
|
|
|
_ts_arr[_cur_idx] = tmp;
|
|
|
|
|
|
_size_arr[_cur_idx] = len;
|
|
|
|
|
|
_cur_idx = (1+_cur_idx)%SIZE;
|
|
|
|
|
|
_last_arrive_time = ts;
|
2022-06-03 13:25:32 +08:00
|
|
|
|
}
|
2022-06-07 09:52:20 +08:00
|
|
|
|
|
2022-09-21 19:21:49 +08:00
|
|
|
|
uint32_t PacketRecvRateContext::getPacketRecvRate(uint32_t &bytesps) {
|
|
|
|
|
|
int64_t tmp_arry[SIZE];
|
|
|
|
|
|
std::copy(_ts_arr, _ts_arr + SIZE, tmp_arry);
|
|
|
|
|
|
std::nth_element(tmp_arry, tmp_arry + (SIZE / 2), tmp_arry + SIZE);
|
|
|
|
|
|
int64_t median = tmp_arry[SIZE / 2];
|
2022-06-07 09:52:20 +08:00
|
|
|
|
|
2022-09-21 19:21:49 +08:00
|
|
|
|
unsigned count = 0;
|
|
|
|
|
|
int sum = 0;
|
|
|
|
|
|
int64_t upper = median << 3;
|
|
|
|
|
|
int64_t lower = median >> 3;
|
|
|
|
|
|
|
|
|
|
|
|
bytesps = 0;
|
|
|
|
|
|
size_t bytes = 0;
|
|
|
|
|
|
const size_t *bp = _size_arr;
|
|
|
|
|
|
// median filtering
|
|
|
|
|
|
const int64_t *p = _ts_arr;
|
|
|
|
|
|
for (int i = 0, n = SIZE; i < n; ++i) {
|
|
|
|
|
|
if ((*p < upper) && (*p > lower)) {
|
|
|
|
|
|
++count; // packet counter
|
|
|
|
|
|
sum += *p; // usec counter
|
|
|
|
|
|
bytes += *bp; // byte counter
|
2022-06-07 09:52:20 +08:00
|
|
|
|
}
|
2022-09-21 19:21:49 +08:00
|
|
|
|
++p; // advance packet pointer
|
|
|
|
|
|
++bp; // advance bytes pointer
|
2022-06-03 13:25:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-21 19:21:49 +08:00
|
|
|
|
// claculate speed, or return 0 if not enough valid value
|
|
|
|
|
|
|
|
|
|
|
|
bytesps = (unsigned long)ceil(1000000.0 / (double(sum) / double(bytes)));
|
|
|
|
|
|
auto ret = (uint32_t)ceil(1000000.0 / (sum / count));
|
|
|
|
|
|
if(_cur_idx == 0)
|
|
|
|
|
|
TraceL << bytesps << " byte/sec " << ret << " pkt/sec";
|
|
|
|
|
|
return ret;
|
2022-06-03 13:25:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-06-07 09:52:20 +08:00
|
|
|
|
void EstimatedLinkCapacityContext::inputPacket(TimePoint &ts) {
|
2022-06-03 20:18:34 +08:00
|
|
|
|
if (_pkt_map.size() > 16) {
|
2022-06-03 13:25:32 +08:00
|
|
|
|
_pkt_map.erase(_pkt_map.begin());
|
|
|
|
|
|
}
|
2022-06-03 20:18:34 +08:00
|
|
|
|
auto tmp = DurationCountMicroseconds(ts - _start);
|
|
|
|
|
|
_pkt_map.emplace(tmp, tmp);
|
2022-06-03 13:25:32 +08:00
|
|
|
|
}
|
2022-06-07 09:52:20 +08:00
|
|
|
|
|
2022-06-03 13:25:32 +08:00
|
|
|
|
uint32_t EstimatedLinkCapacityContext::getEstimatedLinkCapacity() {
|
2022-06-07 09:52:20 +08:00
|
|
|
|
decltype(_pkt_map.begin()) next;
|
|
|
|
|
|
std::vector<int64_t> tmp;
|
|
|
|
|
|
|
|
|
|
|
|
for (auto it = _pkt_map.begin(); it != _pkt_map.end(); ++it) {
|
|
|
|
|
|
next = it;
|
|
|
|
|
|
++next;
|
|
|
|
|
|
if (next != _pkt_map.end()) {
|
|
|
|
|
|
tmp.push_back(next->first - it->first);
|
|
|
|
|
|
} else {
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
std::sort(tmp.begin(), tmp.end());
|
|
|
|
|
|
if (tmp.empty()) {
|
|
|
|
|
|
return 1000;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (tmp.size() < 16) {
|
|
|
|
|
|
return 1000;
|
|
|
|
|
|
}
|
2022-06-03 13:25:32 +08:00
|
|
|
|
|
2022-06-07 09:52:20 +08:00
|
|
|
|
double dur = tmp[0] / 1e6;
|
|
|
|
|
|
return (uint32_t)(1.0 / dur);
|
2022-06-03 13:25:32 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2022-09-21 19:21:49 +08:00
|
|
|
|
/*
|
2022-06-07 09:52:20 +08:00
|
|
|
|
void RecvRateContext::inputPacket(TimePoint &ts, size_t size) {
|
2022-06-03 13:25:32 +08:00
|
|
|
|
if (_pkt_map.size() > 100) {
|
|
|
|
|
|
_pkt_map.erase(_pkt_map.begin());
|
|
|
|
|
|
}
|
2022-06-07 09:52:20 +08:00
|
|
|
|
auto tmp = DurationCountMicroseconds(ts - _start);
|
2022-09-21 19:21:49 +08:00
|
|
|
|
_pkt_map.emplace(tmp, size);
|
2022-06-03 13:25:32 +08:00
|
|
|
|
}
|
2022-06-07 09:52:20 +08:00
|
|
|
|
|
2022-06-03 13:25:32 +08:00
|
|
|
|
uint32_t RecvRateContext::getRecvRate() {
|
2022-06-07 09:52:20 +08:00
|
|
|
|
if (_pkt_map.size() < 2) {
|
2022-06-03 13:25:32 +08:00
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
auto first = _pkt_map.begin();
|
|
|
|
|
|
auto last = _pkt_map.rbegin();
|
2022-06-07 09:52:20 +08:00
|
|
|
|
double dur = (last->first - first->first) / 1000000.0;
|
2022-06-03 13:25:32 +08:00
|
|
|
|
|
|
|
|
|
|
size_t bytes = 0;
|
2022-06-07 09:52:20 +08:00
|
|
|
|
for (auto it : _pkt_map) {
|
2022-06-03 13:25:32 +08:00
|
|
|
|
bytes += it.second;
|
|
|
|
|
|
}
|
2022-06-07 09:52:20 +08:00
|
|
|
|
double rate = (double)bytes / dur;
|
2022-06-03 13:25:32 +08:00
|
|
|
|
return (uint32_t)rate;
|
|
|
|
|
|
}
|
2022-09-21 19:21:49 +08:00
|
|
|
|
*/
|
2022-06-03 13:25:32 +08:00
|
|
|
|
} // namespace SRT
|