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

132 lines
4.3 KiB
C++
Raw Permalink Normal View History

2020-01-28 16:14:43 +01:00
#include "AudioPacketSender.h"
2020-03-25 15:49:13 +01:00
#include "../../VoIPController.h"
2020-01-28 16:14:43 +01:00
using namespace tgvoip;
2020-03-26 20:37:25 +01:00
AudioPacketSender::AudioPacketSender(VoIPController *controller, std::shared_ptr<OutgoingAudioStream> _stream, const std::shared_ptr<OpusEncoder> &encoder) : PacketSender(controller, dynamic_pointer_cast<OutgoingStream>(_stream)), stream(_stream)
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
}
void AudioPacketSender::SetSource(const std::shared_ptr<OpusEncoder> &encoder)
{
if (this->encoder == encoder || !encoder)
return;
this->encoder = encoder;
2020-03-24 21:59:49 +01:00
encoder->SetCallback(std::bind(&AudioPacketSender::SendFrame, this, placeholders::_1, placeholders::_2, placeholders::_3, placeholders::_4));
2020-01-28 16:14:43 +01:00
}
void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char *secondaryData, size_t secondaryLen)
{
2020-03-25 15:49:13 +01:00
if (controller->stopping)
2020-01-28 16:14:43 +01:00
return;
2020-03-28 12:52:15 +01:00
std::shared_ptr<Packet> pkt = std::make_shared<Packet>();
2020-03-25 15:49:13 +01:00
pkt->data = std::make_unique<Buffer>(len);
pkt->data->CopyFrom(data, 0, len);
2020-03-28 12:38:23 +01:00
std::shared_ptr<Buffer> secondaryPtr;
2020-03-25 15:49:13 +01:00
if (secondaryLen)
2020-01-28 16:14:43 +01:00
{
2020-03-28 12:52:15 +01:00
secondaryPtr = std::make_shared<Buffer>(secondaryLen);
2020-03-25 15:49:13 +01:00
secondaryPtr->CopyFrom(secondaryData, 0, secondaryLen);
2020-01-28 16:14:43 +01:00
}
2020-03-28 12:38:23 +01:00
controller->messageThread.Post([this, pkt, secondaryPtr]() {
2020-01-28 16:14:43 +01:00
/*
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);
2020-03-25 15:49:13 +01:00
if (!controller->receivedInitAck)
2020-01-28 16:14:43 +01:00
return;
2020-03-28 12:38:23 +01:00
pkt->prepare(packetManager); // Populate seqno (aka PTS), ack mask if viable
if (secondaryPtr)
{
if (shittyInternetMode)
{
uint8_t maxEC = std::min(
std::min(
static_cast<uint8_t>(ecAudioPackets.size()),
static_cast<uint8_t>(pkt->seq - 1)),
extraEcLevel);
for (auto ecPkt = std::prev(ecAudioPackets.end(), maxEC); ecPkt != ecAudioPackets.end(); ecPkt++)
{
auto distance = std::distance(ecPkt, ecAudioPackets.end());
if (!packetManager.wasLocalAcked(pkt->seq - distance))
{
pkt->extraEC.v[8 - distance].d = std::make_shared<InputBytes>(*ecPkt);
}
}
}
ecAudioPackets.push_back(std::move(secondaryPtr));
if (ecAudioPackets.size() == 9)
{
ecAudioPackets.pop_front();
}
}
//LOGE("SEND: For pts %u = seq %u, using seq %u", audioTimestampOut, audioTimestampOut/60 + 1, packetManager.getLocalSeq());
2020-03-25 15:49:13 +01:00
if (!packetLoss)
2020-01-28 16:14:43 +01:00
{
2020-03-25 15:49:13 +01:00
controller->SendPacket(std::move(*pkt));
2020-01-28 16:14:43 +01:00
}
else
{
2020-03-25 15:49:13 +01:00
double retry = stream->frameDuration / (resendCount * 4.0);
2020-01-28 16:14:43 +01:00
2020-03-25 15:49:13 +01:00
controller->SendPacket(std::move(*pkt), retry / 1000.0, (stream->frameDuration * 4) / 1000.0, resendCount);
2020-01-28 16:14:43 +01:00
}
});
#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-03-29 19:27:34 +02:00
resendCount = std::clamp(percent / 2, 0.0, 2.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;
2020-03-25 15:49:13 +01:00
}