#define MS_CLASS "RTC::RateCalculator"
#include "RTC/RateCalculator.hpp"
#include "Logger.hpp"
#include <cmath>
namespace RTC
{
void RateCalculator::Update(size_t size, uint64_t nowMs)
{
MS_TRACE();
if (nowMs < this->oldestItemStartTime)
return;
this->bytes += size;
RemoveOldData(nowMs);
if (this->newestItemIndex < 0 || nowMs - this->newestItemStartTime >= this->itemSizeMs)
{
this->newestItemIndex++;
this->newestItemStartTime = nowMs;
if (this->newestItemIndex >= this->windowItems)
this->newestItemIndex = 0;
if (this->newestItemIndex == this->oldestItemIndex && this->oldestItemIndex != -1)
{
MS_WARN_TAG(
info,
"calculation buffer full, windowSizeMs:%zu ms windowItems:%" PRIu16,
this->windowSizeMs,
this->windowItems);
BufferItem& oldestItem = buffer[this->oldestItemIndex];
this->totalCount -= oldestItem.count;
oldestItem.count = 0u;
oldestItem.time = 0u;
if (++this->oldestItemIndex >= this->windowItems)
this->oldestItemIndex = 0;
}
BufferItem& item = buffer[this->newestItemIndex];
item.count = size;
item.time = nowMs;
}
else
{
BufferItem& item = buffer[this->newestItemIndex];
item.count += size;
}
if (this->oldestItemIndex < 0)
{
this->oldestItemIndex = this->newestItemIndex;
this->oldestItemStartTime = nowMs;
}
this->totalCount += size;
this->lastRate = 0;
this->lastTime = 0;
}
uint32_t RateCalculator::GetRate(uint64_t nowMs)
{
MS_TRACE();
if (nowMs == this->lastTime)
return this->lastRate;
RemoveOldData(nowMs);
float scale = this->scale / this->windowSizeMs;
this->lastTime = nowMs;
this->lastRate = static_cast<uint32_t>(std::trunc(this->totalCount * scale + 0.5f));
return this->lastRate;
}
inline void RateCalculator::RemoveOldData(uint64_t nowMs)
{
MS_TRACE();
if (this->newestItemIndex < 0 || this->oldestItemIndex < 0)
return;
uint64_t newoldestTime = nowMs - this->windowSizeMs;
if (newoldestTime <= this->oldestItemStartTime)
return;
if (newoldestTime > this->newestItemStartTime)
{
Reset(nowMs);
return;
}
while (this->oldestItemStartTime < newoldestTime)
{
BufferItem& oldestItem = buffer[this->oldestItemIndex];
this->totalCount -= oldestItem.count;
oldestItem.count = 0u;
oldestItem.time = 0u;
if (++this->oldestItemIndex >= this->windowItems)
this->oldestItemIndex = 0;
const BufferItem& newOldestItem = buffer[this->oldestItemIndex];
this->oldestItemStartTime = newOldestItem.time;
}
}
void RtpDataCounter::Update(RTC::RtpPacket* packet)
{
uint64_t nowMs = DepLibUV::GetTimeMs();
this->packets++;
this->rate.Update(packet->GetSize(), nowMs);
}
}