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

Fix secondary encoder bitrate

This commit is contained in:
Daniil Gentili 2020-03-12 16:57:39 +01:00
parent d85228f124
commit c6fa5e0edf
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
5 changed files with 38 additions and 20 deletions

View File

@ -129,7 +129,14 @@ void AudioOutputCallback::RunThread()
while (running)
{
double t = VoIPController::GetCurrentTime();
InvokeCallback(reinterpret_cast<unsigned char *>(buf), 960 * 2);
if (playing)
{
InvokeCallback(reinterpret_cast<unsigned char *>(buf), 960 * 2);
}
else
{
memset(buf, 0, sizeof(buf));
}
dataCallback(buf, 960);
double sl = 0.02 - (VoIPController::GetCurrentTime() - t);
if (sl > 0)

View File

@ -58,9 +58,10 @@ void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char
BufferOutputStream pkt(1500);
bool hasExtraFEC = PeerVersion() >= 7 && secondaryLen && shittyInternetMode;
unsigned char flags = (unsigned char)(len > 255 || hasExtraFEC ? STREAM_DATA_FLAG_LEN16 : 0);
pkt.WriteByte((unsigned char)(1 | flags)); // streamID + flags
if (len > 255 || hasExtraFEC)
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)
{
int16_t lenAndFlags = static_cast<int16_t>(len);
if (hasExtraFEC)
@ -69,8 +70,9 @@ void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char
}
else
{
pkt.WriteByte((unsigned char)len);
pkt.WriteByte(static_cast<uint8_t>(len));
}
pkt.WriteInt32(audioTimestampOut);
pkt.WriteBytes(*dataBufPtr, 0, len);
@ -78,6 +80,14 @@ void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char
if (hasExtraFEC)
{
Buffer ecBuf(secondaryLen);
ecBuf.CopyFromOtherBuffer(*secondaryDataBufPtr, secondaryLen);
ecAudioPackets.push_back(move(ecBuf));
if (ecAudioPackets.size() > 4)
{
ecAudioPackets.pop_front();
}
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)
@ -85,13 +95,6 @@ void AudioPacketSender::SendFrame(unsigned char *data, size_t len, unsigned char
pkt.WriteByte(static_cast<uint8_t>(ecData->Length()));
pkt.WriteBytes(*ecData);
}
Buffer ecBuf(secondaryLen);
ecBuf.CopyFromOtherBuffer(*secondaryDataBufPtr, secondaryLen);
ecAudioPackets.push_back(move(ecBuf));
while (ecAudioPackets.size() > 4)
{
ecAudioPackets.pop_front();
}
}
//unsentStreamPackets++;

View File

@ -40,6 +40,7 @@ tgvoip::OpusEncoder::OpusEncoder(const std::shared_ptr<MediaStreamItf> &source,
{
this->source = source;
source->SetCallback(tgvoip::OpusEncoder::Callback, this);
enc = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, NULL);
opus_encoder_ctl(enc, OPUS_SET_COMPLEXITY(10));
opus_encoder_ctl(enc, OPUS_SET_PACKET_LOSS_PERC(1));
@ -59,12 +60,13 @@ tgvoip::OpusEncoder::OpusEncoder(const std::shared_ptr<MediaStreamItf> &source,
secondaryEnabledBandwidth = serverConfigValueToBandwidth(ServerConfig::GetSharedInstance()->GetInt("audio_extra_ec_bandwidth", 2));
secondaryEncoderEnabled = false;
currentSecondaryBitrate = 8000;
if (needSecondary)
{
secondaryEncoder = opus_encoder_create(48000, 1, OPUS_APPLICATION_VOIP, NULL);
opus_encoder_ctl(secondaryEncoder, OPUS_SET_COMPLEXITY(10));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_SIGNAL(OPUS_SIGNAL_VOICE));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(8000));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentSecondaryBitrate));
}
else
{
@ -185,7 +187,7 @@ void tgvoip::OpusEncoder::RunThread()
LOGV("starting encoder, packets per frame=%d", packetsPerFrame);
int16_t *frame;
if (packetsPerFrame > 1)
frame = (int16_t *)malloc(960 * 2 * packetsPerFrame);
frame = reinterpret_cast<uint16_t *>(std::malloc(960 * 2 * packetsPerFrame));
else
frame = NULL;
bool frameHasVoice = false;
@ -195,7 +197,7 @@ void tgvoip::OpusEncoder::RunThread()
Buffer _packet = queue.GetBlocking();
if (!_packet.IsEmpty())
{
int16_t *packet = (int16_t *)*_packet;
int16_t *packet = reinterpret_cast<int16_t *>(*_packet);
bool hasVoice = true;
if (echoCanceller)
echoCanceller->ProcessInput(packet, 960, hasVoice);
@ -212,7 +214,7 @@ void tgvoip::OpusEncoder::RunThread()
}
else
{
memcpy(frame + (960 * bufferedCount), packet, 960 * 2);
memcpy(frame + (960 * bufferedCount), packet, 960 * 2); // Accumulate raw frames
frameHasVoice = frameHasVoice || hasVoice;
bufferedCount++;
if (bufferedCount == packetsPerFrame)
@ -224,7 +226,7 @@ void tgvoip::OpusEncoder::RunThread()
opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate));
if (secondaryEncoder)
{
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentSecondaryBitrate));
}
}
else
@ -243,7 +245,7 @@ void tgvoip::OpusEncoder::RunThread()
opus_encoder_ctl(enc, OPUS_SET_BITRATE(currentBitrate));
if (secondaryEncoder)
{
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentBitrate));
opus_encoder_ctl(secondaryEncoder, OPUS_SET_BITRATE(currentSecondaryBitrate));
}
}
Encode(frame, 960 * packetsPerFrame);
@ -307,6 +309,9 @@ void tgvoip::OpusEncoder::SetVadMode(bool vad)
{
vadMode = vad;
}
void tgvoip::OpusEncoder::AddAudioEffect(const std::shared_ptr<effects::AudioEffect> &effect)
{
postProcEffects.push_back(effect);

View File

@ -58,6 +58,9 @@ private:
unsigned char buffer[4096];
std::atomic<uint32_t> requestedBitrate;
uint32_t currentBitrate;
uint32_t currentSecondaryBitrate;
Thread *thread;
BlockingQueue<Buffer> queue;
BufferPool<960 * 2, 10> bufferPool;

View File

@ -43,6 +43,8 @@ void VoIPController::InitializeAudio()
encoder->AddAudioEffect(inputVolume);
}
dynamic_cast<AudioPacketSender *>(outgoingAudioStream->packetSender.get())->SetSource(encoder);
#if defined(TGVOIP_USE_CALLBACK_AUDIO_IO)
dynamic_cast<audio::AudioInputCallback *>(audioInput.get())->SetDataCallback(audioInputDataCallback);
dynamic_cast<audio::AudioOutputCallback *>(audioOutput.get())->SetDataCallback(audioOutputDataCallback);
@ -57,8 +59,6 @@ void VoIPController::InitializeAudio()
return;
}
dynamic_cast<AudioPacketSender *>(outgoingAudioStream->packetSender.get())->SetSource(encoder);
UpdateAudioBitrateLimit();
LOGI("Audio initialization took %f seconds", GetCurrentTime() - t);
}