1
0
mirror of https://github.com/danog/libtgvoip.git synced 2024-12-12 09:09:38 +01:00
libtgvoip/controller/audio/AudioPacketSender.cpp

205 lines
6.7 KiB
C++
Raw Normal View History

2020-01-28 16:14:43 +01:00
#include "AudioPacketSender.h"
2020-01-28 21:45:56 +01:00
#include "../PrivateDefines.h"
2020-01-28 16:14:43 +01:00
using namespace tgvoip;
2020-01-28 23:45:47 +01:00
AudioPacketSender::AudioPacketSender(VoIPController *controller, const std::shared_ptr<OpusEncoder> &encoder, const std::shared_ptr<VoIPController::Stream> &stream) : PacketSender(controller, stream), encoder(encoder)
2020-01-28 16:14:43 +01:00
{
2020-01-28 21:45:56 +01:00
SetSource(encoder);
2020-01-28 16:14:43 +01:00
}
AudioPacketSender::~AudioPacketSender()
{
}
void AudioPacketSender::SetSource(const std::shared_ptr<OpusEncoder> &encoder)
{
if (this->encoder == encoder || !encoder)
return;
this->encoder = encoder;
encoder->SetCallback(bind(&AudioPacketSender::SendFrame, this, placeholders::_1, placeholders::_2, placeholders::_3, placeholders::_4));
}
void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char *secondaryData, size_t secondaryLen)
{
if (IsStopping())
return;
Buffer dataBuf = outgoingAudioBufferPool.Get();
Buffer secondaryDataBuf = secondaryLen && secondaryData ? outgoingAudioBufferPool.Get() : Buffer();
dataBuf.CopyFrom(data, 0, len);
if (secondaryLen && secondaryData)
{
secondaryDataBuf.CopyFrom(secondaryData, 0, secondaryLen);
}
shared_ptr<Buffer> dataBufPtr = make_shared<Buffer>(move(dataBuf));
shared_ptr<Buffer> secondaryDataBufPtr = make_shared<Buffer>(move(secondaryDataBuf));
GetMessageThread().Post([this, dataBufPtr, secondaryDataBufPtr, len, secondaryLen]() {
/*
unsentStreamPacketsHistory.Add(static_cast<unsigned int>(unsentStreamPackets));
if (unsentStreamPacketsHistory.Average() >= maxUnsentStreamPackets && !videoPacketSender)
{
LOGW("Resetting stalled send queue");
sendQueue.clear();
unsentStreamPacketsHistory.Reset();
unsentStreamPackets = 0;
}
//if (waitingForAcks || dontSendPackets > 0 || ((unsigned int)unsentStreamPackets >= maxUnsentStreamPackets))
{
2020-01-28 16:14:43 +01:00
LOGV("waiting for queue, dropping outgoing audio packet, %d %d %d [%d]", (unsigned int)unsentStreamPackets, waitingForAcks, dontSendPackets, maxUnsentStreamPackets);
return;
}*/
//LOGV("Audio packet size %u", (unsigned int)len);
if (!ReceivedInitAck())
return;
BufferOutputStream pkt(1500);
bool hasExtraFEC = PeerVersion() >= 7 && secondaryLen && shittyInternetMode;
2020-03-12 16:57:39 +01:00
uint8_t flags = static_cast<uint8_t>(len > 255 || hasExtraFEC ? STREAM_DATA_FLAG_LEN16 : 0);
pkt.WriteByte(flags | 1); // flags + streamID
if (flags & STREAM_DATA_FLAG_LEN16)
2020-01-28 16:14:43 +01:00
{
int16_t lenAndFlags = static_cast<int16_t>(len);
if (hasExtraFEC)
lenAndFlags |= STREAM_DATA_XFLAG_EXTRA_FEC;
pkt.WriteInt16(lenAndFlags);
}
else
{
2020-03-12 16:57:39 +01:00
pkt.WriteByte(static_cast<uint8_t>(len));
2020-01-28 16:14:43 +01:00
}
2020-03-12 16:57:39 +01:00
2020-01-28 16:14:43 +01:00
pkt.WriteInt32(audioTimestampOut);
pkt.WriteBytes(*dataBufPtr, 0, len);
2020-01-29 15:52:43 +01:00
//LOGE("SEND: For pts %u = seq %u, using seq %u", audioTimestampOut, audioTimestampOut/60 + 1, packetManager.getLocalSeq());
2020-01-28 16:14:43 +01:00
if (hasExtraFEC)
{
2020-03-12 16:57:39 +01:00
Buffer ecBuf(secondaryLen);
ecBuf.CopyFromOtherBuffer(*secondaryDataBufPtr, secondaryLen);
ecAudioPackets.push_back(move(ecBuf));
if (ecAudioPackets.size() > 4)
{
ecAudioPackets.pop_front();
}
2020-01-28 16:14:43 +01:00
uint8_t fecCount = std::min(static_cast<uint8_t>(ecAudioPackets.size()), extraEcLevel);
pkt.WriteByte(fecCount);
for (auto ecData = ecAudioPackets.end() - fecCount; ecData != ecAudioPackets.end(); ++ecData)
{
2020-03-10 20:31:58 +01:00
pkt.WriteByte(static_cast<uint8_t>(ecData->Length()));
2020-01-28 16:14:43 +01:00
pkt.WriteBytes(*ecData);
}
}
//unsentStreamPackets++;
2020-01-28 21:45:56 +01:00
if (PeerVersion() < PROTOCOL_RELIABLE)
{
2020-01-29 15:52:43 +01:00
// Need to increase this anyway to go hand in hand with timestamp
2020-01-29 19:12:12 +01:00
// packetManager.nextLocalSeq();
2020-01-28 16:14:43 +01:00
2020-01-29 19:12:12 +01:00
if (!packetLoss)
{
PendingOutgoingPacket p{
0,
PKT_STREAM_DATA,
pkt.GetLength(),
Buffer(move(pkt)),
0,
};
SendPacket(std::move(p));
2020-01-29 19:12:12 +01:00
}
else
{
2020-01-29 21:14:20 +01:00
double retry = stream->frameDuration / (resendCount * 4.0);
2020-01-28 16:14:43 +01:00
2020-03-10 20:31:58 +01:00
SendPacketReliably(PKT_STREAM_DATA, pkt.GetBuffer(), pkt.GetLength(), retry / 1000.0, (stream->frameDuration * 4) / 1000.0, resendCount); // Todo Optimize RTT
2020-01-29 19:12:12 +01:00
}
2020-01-28 21:45:56 +01:00
}
else
{
2020-01-28 23:45:47 +01:00
PendingOutgoingPacket p{
/*.seq=*/0,
/*.type=*/PKT_STREAM_DATA,
/*.len=*/pkt.GetLength(),
/*.data=*/Buffer(move(pkt)),
/*.endpoint=*/0,
};
SendPacket(move(p));
2020-01-28 21:45:56 +01:00
}
2020-01-28 16:14:43 +01:00
if (PeerVersion() < 7 && secondaryLen && shittyInternetMode)
{
Buffer ecBuf(secondaryLen);
2020-03-10 19:36:27 +01:00
ecBuf.CopyFromOtherBuffer(*secondaryDataBufPtr, secondaryLen);
2020-01-28 16:14:43 +01:00
if (ecAudioPackets.size() == 4)
{
ecAudioPackets.pop_front();
}
ecAudioPackets.push_back(move(ecBuf));
pkt = BufferOutputStream(1500);
pkt.WriteByte(stream->id);
pkt.WriteInt32(audioTimestampOut);
uint8_t fecCount = std::min(static_cast<uint8_t>(ecAudioPackets.size()), extraEcLevel);
pkt.WriteByte(fecCount);
for (auto ecData = ecAudioPackets.end() - fecCount; ecData != ecAudioPackets.end(); ++ecData)
{
pkt.WriteByte((unsigned char)ecData->Length());
pkt.WriteBytes(*ecData);
}
PendingOutgoingPacket p{
0,
PKT_STREAM_EC,
pkt.GetLength(),
Buffer(move(pkt)),
0};
SendPacket(std::move(p));
}
audioTimestampOut += stream->frameDuration;
});
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
if (audioPreprocDataCallback)
{
int size = opus_decode(preprocDecoder.get(), data, len, preprocBuffer, 4096, 0);
audioPreprocDataCallback(preprocBuffer, size);
}
#endif
}
2020-01-29 19:12:12 +01:00
double AudioPacketSender::setPacketLoss(double percent)
{
packetLoss = percent;
if (percent > 2)
{
2020-01-29 21:14:20 +01:00
resendCount = std::clamp(percent / 2, 0.0, 10.0);
2020-01-29 19:12:12 +01:00
}
/*else if (percent > 5)
{
resendCount = 1.5;
}
else if (percent > 2)
{
resendCount = 1.3;
}*/
else
{
resendCount = 1;
}
++resendCount;
double newLoss = percent / resendCount;
LOGE("Packet loss %lf / resend count %lf = new packet loss %lf", percent, resendCount, newLoss);
return newLoss;
}