mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2026-01-15 17:06:54 +00:00
2.1
This commit is contained in:
@@ -16,9 +16,18 @@
|
||||
|
||||
using namespace tgvoip;
|
||||
|
||||
tgvoip::OpusDecoder::OpusDecoder(MediaStreamItf *dst, bool isAsync){
|
||||
async=isAsync;
|
||||
tgvoip::OpusDecoder::OpusDecoder(const std::shared_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC){
|
||||
dst->SetCallback(OpusDecoder::Callback, this);
|
||||
Initialize(isAsync, needEC);
|
||||
}
|
||||
|
||||
tgvoip::OpusDecoder::OpusDecoder(const std::unique_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC){
|
||||
dst->SetCallback(OpusDecoder::Callback, this);
|
||||
Initialize(isAsync, needEC);
|
||||
}
|
||||
|
||||
void tgvoip::OpusDecoder::Initialize(bool isAsync, bool needEC){
|
||||
async=isAsync;
|
||||
if(async){
|
||||
decodedQueue=new BlockingQueue<unsigned char*>(33);
|
||||
bufferPool=new BufferPool(PACKET_SIZE, 32);
|
||||
@@ -29,6 +38,10 @@ tgvoip::OpusDecoder::OpusDecoder(MediaStreamItf *dst, bool isAsync){
|
||||
semaphore=NULL;
|
||||
}
|
||||
dec=opus_decoder_create(48000, 1, NULL);
|
||||
if(needEC)
|
||||
ecDec=opus_decoder_create(48000, 1, NULL);
|
||||
else
|
||||
ecDec=NULL;
|
||||
buffer=(unsigned char *) malloc(8192);
|
||||
lastDecoded=NULL;
|
||||
outputBufferSize=0;
|
||||
@@ -42,10 +55,14 @@ tgvoip::OpusDecoder::OpusDecoder(MediaStreamItf *dst, bool isAsync){
|
||||
running=false;
|
||||
remainingDataLen=0;
|
||||
processedBuffer=NULL;
|
||||
prevWasEC=false;
|
||||
prevLastSample=0;
|
||||
}
|
||||
|
||||
tgvoip::OpusDecoder::~OpusDecoder(){
|
||||
opus_decoder_destroy(dec);
|
||||
if(ecDec)
|
||||
opus_decoder_destroy(ecDec);
|
||||
free(buffer);
|
||||
if(bufferPool)
|
||||
delete bufferPool;
|
||||
@@ -176,40 +193,44 @@ void tgvoip::OpusDecoder::RunThread(void* param){
|
||||
}
|
||||
|
||||
int tgvoip::OpusDecoder::DecodeNextFrame(){
|
||||
/*memcpy(buffer, nextBuffer, nextLen);
|
||||
size_t inLen=nextLen;
|
||||
int playbackDuration=0;
|
||||
nextLen=jitterBuffer->HandleOutput(nextBuffer, 8192, 0, &playbackDuration);
|
||||
if(first){
|
||||
first=false;
|
||||
return 0;
|
||||
}
|
||||
if(!inLen){
|
||||
LOGV("Trying to recover late packet");
|
||||
inLen=jitterBuffer->HandleOutput(buffer, 8192, -2, &playbackDuration);
|
||||
if(inLen)
|
||||
LOGV("Decoding late packet");
|
||||
}*/
|
||||
int playbackDuration=0;
|
||||
size_t len=jitterBuffer->HandleOutput(buffer, 8192, 0, true, &playbackDuration);
|
||||
bool isEC=false;
|
||||
size_t len=jitterBuffer->HandleOutput(buffer, 8192, 0, true, playbackDuration, isEC);
|
||||
bool fec=false;
|
||||
if(!len){
|
||||
fec=true;
|
||||
len=jitterBuffer->HandleOutput(buffer, 8192, 0, false, &playbackDuration);
|
||||
if(len)
|
||||
LOGV("Trying FEC...");
|
||||
len=jitterBuffer->HandleOutput(buffer, 8192, 0, false, playbackDuration, isEC);
|
||||
//if(len)
|
||||
// LOGV("Trying FEC...");
|
||||
}
|
||||
int size;
|
||||
if(len){
|
||||
size=opus_decode(dec, buffer, len, (opus_int16 *) decodeBuffer, packetsPerFrame*960, fec ? 1 : 0);
|
||||
size=opus_decode(isEC ? ecDec : dec, buffer, len, (opus_int16 *) decodeBuffer, packetsPerFrame*960, fec ? 1 : 0);
|
||||
consecutiveLostPackets=0;
|
||||
if(prevWasEC!=isEC && size){
|
||||
// It turns out the waveforms generated by the PLC feature are also great to help smooth out the
|
||||
// otherwise audible transition between the frames from different decoders. Those are basically an extrapolation
|
||||
// of the previous successfully decoded data -- which is exactly what we need here.
|
||||
size=opus_decode(prevWasEC ? ecDec : dec, NULL, 0, (opus_int16*)nextBuffer, packetsPerFrame*960, 0);
|
||||
if(size){
|
||||
int16_t* plcSamples=reinterpret_cast<int16_t*>(nextBuffer);
|
||||
int16_t* samples=reinterpret_cast<int16_t*>(decodeBuffer);
|
||||
constexpr float coeffs[]={0.999802, 0.995062, 0.984031, 0.966778, 0.943413, 0.914084, 0.878975, 0.838309, 0.792344,
|
||||
0.741368, 0.685706, 0.625708, 0.561754, 0.494249, 0.423619, 0.350311, 0.274788, 0.197527, 0.119018, 0.039757};
|
||||
for(int i=0;i<20;i++){
|
||||
samples[i]=(int16_t)round((plcSamples[i]*coeffs[i]+(float)samples[i]*(1.0-coeffs[i])));
|
||||
}
|
||||
}
|
||||
}
|
||||
prevWasEC=isEC;
|
||||
prevLastSample=decodeBuffer[size-1];
|
||||
}else{ // do packet loss concealment
|
||||
consecutiveLostPackets++;
|
||||
if(consecutiveLostPackets>2 && enableDTX){
|
||||
silentPacketCount+=packetsPerFrame;
|
||||
size=packetsPerFrame*960;
|
||||
}else{
|
||||
size=opus_decode(dec, NULL, 0, (opus_int16 *) decodeBuffer, packetsPerFrame*960, 0);
|
||||
size=opus_decode(prevWasEC ? ecDec : dec, NULL, 0, (opus_int16 *) decodeBuffer, packetsPerFrame*960, 0);
|
||||
//LOGV("PLC");
|
||||
}
|
||||
}
|
||||
@@ -235,7 +256,7 @@ void tgvoip::OpusDecoder::SetFrameDuration(uint32_t duration){
|
||||
}
|
||||
|
||||
|
||||
void tgvoip::OpusDecoder::SetJitterBuffer(JitterBuffer* jitterBuffer){
|
||||
void tgvoip::OpusDecoder::SetJitterBuffer(std::shared_ptr<JitterBuffer> jitterBuffer){
|
||||
this->jitterBuffer=jitterBuffer;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user