1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-11-30 04:39:03 +01:00

Fix jitter buffer bug and add some comments

This commit is contained in:
Daniil Gentili 2020-03-27 14:50:29 +01:00
parent ded4338153
commit 457576e93f
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
2 changed files with 35 additions and 36 deletions

View File

@ -126,14 +126,14 @@ void JitterBuffer::HandleInput(std::unique_ptr<Buffer> &&buf, uint32_t timestamp
// Time deviation check // Time deviation check
double time = VoIPController::GetCurrentTime(); double time = VoIPController::GetCurrentTime();
if (expectNextAtTime) if (expectNextAtTimeMs)
{ {
deviationHistory.Add(expectNextAtTime - time); deviationHistory.Add(expectNextAtTimeMs - time);
expectNextAtTime += step / 1000.0; expectNextAtTimeMs += step / 1000.0;
} }
else else
{ {
expectNextAtTime = time + step / 1000.0; expectNextAtTimeMs = time + step / 1000.0;
} }
// Late packet check // Late packet check
@ -174,9 +174,9 @@ void JitterBuffer::HandleInput(std::unique_ptr<Buffer> &&buf, uint32_t timestamp
Advance(); Advance();
} }
LOGW("Putting into jitter buffer"); /*LOGW("Putting into jitter buffer");
std::string pad(slot - slots.begin(), ' '); std::string pad(slot - slots.begin(), ' ');
pad += '^'; pad += '^';*/
slot->timestamp = timestamp; slot->timestamp = timestamp;
slot->size = size; slot->size = size;
@ -202,10 +202,10 @@ void JitterBuffer::Reset()
adjustingDelay = false; adjustingDelay = false;
lostSinceReset = 0; lostSinceReset = 0;
gotSinceReset = 0; gotSinceReset = 0;
expectNextAtTime = 0; expectNextAtTimeMs = 0;
deviationHistory.Reset(); deviationHistory.Reset();
outstandingDelayChange = 0; outstandingDelayChange = 0;
dontChangeDelay = 0; dontChangeDelayFor = 0;
} }
std::unique_ptr<Buffer> JitterBuffer::HandleOutput(bool advance, int &playbackScaledDuration, bool &isEC) std::unique_ptr<Buffer> JitterBuffer::HandleOutput(bool advance, int &playbackScaledDuration, bool &isEC)
@ -236,7 +236,7 @@ std::unique_ptr<Buffer> JitterBuffer::HandleOutput(bool advance, int &playbackSc
jitter_packet_t pkt; jitter_packet_t pkt;
int result = GetInternal(pkt, advance); int result = GetInternal(pkt, advance);
if (outstandingDelayChange != 0) if (outstandingDelayChange)
{ {
if (outstandingDelayChange < 0) if (outstandingDelayChange < 0)
{ {
@ -280,17 +280,10 @@ int JitterBuffer::GetInternal(jitter_packet_t &pkt, bool advance)
if (slot != slots.end()) if (slot != slots.end())
{ {
/*if (pkt.size < slot->size)
{
LOGE("jitter: packet won't fit into provided buffer of %d (need %d)", int(slot->size), int(pkt.size));
}
else
{*/
pkt.size = slot->size; pkt.size = slot->size;
pkt.timestamp = slot->timestamp; pkt.timestamp = slot->timestamp;
pkt.buffer = std::move(slot->buffer); pkt.buffer = std::move(slot->buffer);
pkt.isEC = slot->isEC; pkt.isEC = slot->isEC;
//}
slot->buffer = nullptr; slot->buffer = nullptr;
//LOGV("out ts=%d, ec=%d", pkt.timestamp, pkt.isEC); //LOGV("out ts=%d, ec=%d", pkt.timestamp, pkt.isEC);
Advance(); Advance();
@ -313,11 +306,13 @@ int JitterBuffer::GetInternal(jitter_packet_t &pkt, bool advance)
{ {
LOGW("jitter: lost %d packets in a row, resetting", lostCount); LOGW("jitter: lost %d packets in a row, resetting", lostCount);
//minDelay++; //minDelay++;
dontIncMinDelay = 16; dontIncMinDelayFor = 16;
dontDecMinDelay += 128; dontDecMinDelayFor += 128;
auto currentDelay = GetCurrentDelay(); auto currentDelay = GetCurrentDelay();
LOGW("currentDelay=%u, minDelay=%lf, nextFetchTS=%lu", currentDelay, minDelay.load(), nextFetchTimestamp.load())
if (currentDelay < minDelay) if (currentDelay < minDelay)
nextFetchTimestamp -= static_cast<int64_t>(minDelay - currentDelay); nextFetchTimestamp -= static_cast<int64_t>(minDelay - currentDelay) * step;
LOGW("currentDelay=%u, minDelay=%lf, nextFetchTS=%lu", currentDelay, minDelay.load(), nextFetchTimestamp.load())
lostCount = 0; lostCount = 0;
Reset(); Reset();
} }
@ -358,8 +353,8 @@ void JitterBuffer::Tick()
if (absolutelyNoLatePackets) if (absolutelyNoLatePackets)
{ {
if (dontDecMinDelay > 0) if (dontDecMinDelayFor > 0)
dontDecMinDelay--; dontDecMinDelayFor--;
} }
delayHistory.Add(GetCurrentDelay()); delayHistory.Add(GetCurrentDelay());
@ -373,51 +368,55 @@ void JitterBuffer::Tick()
stddev += (d * d); stddev += (d * d);
} }
stddev = sqrt(stddev / 64); stddev = sqrt(stddev / 64);
uint32_t stddevDelay = std::clamp((uint32_t)ceil(stddev * 2 * 1000 / step), minMinDelay, maxMinDelay); uint32_t stddevDelay = std::clamp(static_cast<uint32_t>(ceil(stddev * 2 * 1000 / step)), minMinDelay, maxMinDelay);
//LOGW("Average delay diff of %lf s, stddev=%lf s, stddevPacket=%u (minDelayPacket=%lf)", avgDelay, stddev, stddevDelay, minDelay.load());
// The difference between estimated time of arrival and actual TOA (=packet jitter) is used to calculate standard deviation of packet jitter.
// if the packet jitter is normally and consistently bigger than the jitter buffer delay, increase the jitter buffer delay.
if (stddevDelay != minDelay) if (stddevDelay != minDelay)
{ {
int32_t diff = std::clamp((int32_t)(stddevDelay - minDelay), -1, 1); int32_t diff = std::clamp((int32_t)(stddevDelay - minDelay), -1, 1);
if (diff > 0) if (diff > 0)
{ {
dontDecMinDelay = 100; dontDecMinDelayFor = 100;
} }
if ((diff > 0 && dontIncMinDelay == 0) || (diff < 0 && dontDecMinDelay == 0)) if ((diff > 0 && dontIncMinDelayFor == 0) || (diff < 0 && dontDecMinDelayFor == 0))
{ {
//nextFetchTimestamp+=diff*(int32_t)step; //nextFetchTimestamp+=diff*(int32_t)step;
minDelay.store(minDelay + diff); minDelay.store(minDelay + diff);
outstandingDelayChange += diff * 60; outstandingDelayChange += diff * 60;
dontChangeDelay += 32; dontChangeDelayFor += 32;
//LOGD("new delay from stddev %f", minDelay); //LOGD("new delay from stddev %f", minDelay);
if (diff < 0) if (diff < 0)
{ {
dontDecMinDelay += 25; dontDecMinDelayFor += 25;
} }
if (diff > 0) if (diff > 0)
{ {
dontIncMinDelay = 25; dontIncMinDelayFor = 25;
} }
} }
} }
lastMeasuredJitter = stddev; lastMeasuredJitter = stddev;
lastMeasuredDelay = stddevDelay; lastMeasuredDelay = stddevDelay;
//LOGV("stddev=%.3f, avg=%.3f, ndelay=%d, dontDec=%u", stddev, avgdev, stddevDelay, dontDecMinDelay); //LOGV("stddev=%.3f, avg=%.3f, ndelay=%d, dontDec=%u", stddev, avgdev, stddevDelay, dontDecMinDelayFor);
if (dontChangeDelay) if (dontChangeDelayFor)
{ {
--dontChangeDelay; --dontChangeDelayFor;
} }
else else
{ {
//LOGW("avgDelay=%lf, minDelay=%lf", avgDelay, minDelay.load());
if (avgDelay > minDelay + 0.5) if (avgDelay > minDelay + 0.5)
{ {
outstandingDelayChange -= avgDelay > minDelay + 2 ? 60 : 20; outstandingDelayChange -= avgDelay > minDelay + 2 ? 60 : 20;
dontChangeDelay += 10; dontChangeDelayFor += 10;
} }
else if (avgDelay < minDelay - 0.3) else if (avgDelay < minDelay - 0.3)
{ {
outstandingDelayChange += 20; outstandingDelayChange += 20;
dontChangeDelay += 10; dontChangeDelayFor += 10;
} }
} }

View File

@ -90,16 +90,16 @@ private:
bool adjustingDelay = false; bool adjustingDelay = false;
unsigned int tickCount = 0; unsigned int tickCount = 0;
unsigned int latePacketCount = 0; unsigned int latePacketCount = 0;
unsigned int dontIncMinDelay = 0; unsigned int dontIncMinDelayFor = 0;
unsigned int dontDecMinDelay = 0; unsigned int dontDecMinDelayFor = 0;
int lostPackets = 0; int lostPackets = 0;
double prevRecvTime = 0; double prevRecvTime = 0;
double expectNextAtTime = 0; double expectNextAtTimeMs = 0;
HistoricBuffer<double, 64> deviationHistory; HistoricBuffer<double, 64> deviationHistory;
double lastMeasuredJitter = 0; double lastMeasuredJitter = 0;
double lastMeasuredDelay = 0; double lastMeasuredDelay = 0;
int outstandingDelayChange = 0; int outstandingDelayChange = 0;
unsigned int dontChangeDelay = 0; unsigned int dontChangeDelayFor = 0;
double avgDelay = 0; double avgDelay = 0;
bool first = true; bool first = true;
#ifdef TGVOIP_DUMP_JITTER_STATS #ifdef TGVOIP_DUMP_JITTER_STATS