This commit is contained in:
Grishka
2018-06-04 22:37:43 +03:00
parent 5ae5b34cc7
commit 342cc5a295
32 changed files with 2594 additions and 1545 deletions

View File

@@ -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;
}