|
|
|
|
@ -2,12 +2,15 @@
|
|
|
|
|
#include <algorithm> |
|
|
|
|
#include <cstdint> |
|
|
|
|
|
|
|
|
|
// Десять секундных интервалов. Время передаёт аудиопоток из монотонных часов.
|
|
|
|
|
// Десять секундных интервалов. Отдельные экземпляры для глубины очереди и задержки доставки.
|
|
|
|
|
struct call_jitter_window { |
|
|
|
|
struct bucket { int64_t second = -1; int low = 0, high = 0; } buckets[10]; |
|
|
|
|
int low = 0, high = 0, reserve = 60; |
|
|
|
|
struct bucket { int64_t second = -1, low = 0, high = 0; } buckets[10]; |
|
|
|
|
int64_t low = 0, high = 0; |
|
|
|
|
int reserve = 60; |
|
|
|
|
int max_reserve = 1000; |
|
|
|
|
bool observe(int64_t now_ms, int depth) { |
|
|
|
|
int64_t last_received_ms = -1, transit_ms = 0; |
|
|
|
|
uint32_t last_sent_ms = 0; |
|
|
|
|
bool observe(int64_t now_ms, int64_t depth) { |
|
|
|
|
int64_t second = now_ms / 1000; |
|
|
|
|
auto& b = buckets[second % 10]; |
|
|
|
|
bool changed_second = b.second != second; |
|
|
|
|
@ -18,7 +21,14 @@ struct call_jitter_window {
|
|
|
|
|
if (item.second < 0 || item.second > second || second - item.second >= 10) continue; |
|
|
|
|
low = std::min(low, item.low); high = std::max(high, item.high); |
|
|
|
|
} |
|
|
|
|
reserve = std::max(60, std::min(max_reserve, high - low)); |
|
|
|
|
reserve = (int)std::max<int64_t>(60, std::min<int64_t>(max_reserve, high - low)); |
|
|
|
|
return changed_second; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Разность интервалов прихода и отправки: смещение часов исключается, uint32 timestamp разворачивается.
|
|
|
|
|
bool observe_arrival(int64_t received_ms, uint32_t sent_ms) { |
|
|
|
|
if (last_received_ms >= 0) transit_ms += received_ms - last_received_ms - (int32_t)(sent_ms - last_sent_ms); |
|
|
|
|
last_received_ms = received_ms; last_sent_ms = sent_ms; |
|
|
|
|
return observe(received_ms, transit_ms); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|