- fix Opus decoder - now audio is smooth
This commit is contained in:
parent
8cb34fad83
commit
e0b02db39d
|
|
@ -410,7 +410,7 @@ OpusCodec::OpusCodec(int samplerate, int channels, int ptime)
|
||||||
:mEncoderCtx(nullptr), mDecoderCtx(nullptr), mChannels(channels), mPTime(ptime), mSamplerate(samplerate), mDecoderChannels(0)
|
:mEncoderCtx(nullptr), mDecoderCtx(nullptr), mChannels(channels), mPTime(ptime), mSamplerate(samplerate), mDecoderChannels(0)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
mEncoderCtx = opus_encoder_create(48000, mChannels, OPUS_APPLICATION_VOIP, &status);
|
mEncoderCtx = opus_encoder_create(mSamplerate, mChannels, OPUS_APPLICATION_VOIP, &status);
|
||||||
if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_COMPLEXITY(OPUS_CODEC_COMPLEXITY)))
|
if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_COMPLEXITY(OPUS_CODEC_COMPLEXITY)))
|
||||||
ICELogError(<< "Failed to set Opus encoder complexity");
|
ICELogError(<< "Failed to set Opus encoder complexity");
|
||||||
//if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_FORCE_CHANNELS(AUDIO_CHANNELS)))
|
//if (OPUS_OK != opus_encoder_ctl(mEncoderCtx, OPUS_SET_FORCE_CHANNELS(AUDIO_CHANNELS)))
|
||||||
|
|
@ -433,7 +433,7 @@ void OpusCodec::applyParams(const Params ¶ms)
|
||||||
if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_PACKET_LOSS_PERC(params.mExpectedPacketLoss))))
|
if (OPUS_OK != (error = opus_encoder_ctl(mEncoderCtx, OPUS_SET_PACKET_LOSS_PERC(params.mExpectedPacketLoss))))
|
||||||
ICELogError(<< "Failed to (un)set expected packet loss. Error " << opus_strerror(error));
|
ICELogError(<< "Failed to (un)set expected packet loss. Error " << opus_strerror(error));
|
||||||
|
|
||||||
mDecodeResampler.start(channels(), 48000, mSamplerate);
|
// mDecodeResampler.start(channels(), 48000, mSamplerate);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpusCodec::~OpusCodec()
|
OpusCodec::~OpusCodec()
|
||||||
|
|
@ -493,10 +493,10 @@ int OpusCodec::encode(const void* input, int inputBytes, void* output, int outpu
|
||||||
|
|
||||||
int OpusCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity)
|
int OpusCodec::decode(const void* input, int inputBytes, void* output, int outputCapacity)
|
||||||
{
|
{
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
// Examine the number of channels available in incoming packet
|
// Examine the number of channels available in incoming packet
|
||||||
int nr_of_channels = opus_packet_get_nb_channels((const unsigned char *) input);
|
int nr_of_channels = opus_packet_get_nb_channels((const unsigned char *) input);
|
||||||
int nr_of_frames = opus_decoder_get_nb_samples(mDecoderCtx, (const unsigned char *) input,
|
|
||||||
inputBytes);
|
|
||||||
|
|
||||||
// Recreate decoder if needed
|
// Recreate decoder if needed
|
||||||
if (mDecoderChannels != nr_of_channels)
|
if (mDecoderChannels != nr_of_channels)
|
||||||
|
|
@ -508,10 +508,17 @@ int OpusCodec::decode(const void* input, int inputBytes, void* output, int outpu
|
||||||
}
|
}
|
||||||
mDecoderChannels = nr_of_channels;
|
mDecoderChannels = nr_of_channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mDecoderCtx)
|
||||||
|
{
|
||||||
int status = 0;
|
int status = 0;
|
||||||
mDecoderCtx = opus_decoder_create(48000, mDecoderChannels, &status);
|
mDecoderCtx = opus_decoder_create(mSamplerate, mDecoderChannels, &status);
|
||||||
if (status)
|
if (status)
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nr_of_frames = opus_decoder_get_nb_samples(mDecoderCtx, (const unsigned char *) input,
|
||||||
|
inputBytes);
|
||||||
|
|
||||||
// We support stereo and mono here.
|
// We support stereo and mono here.
|
||||||
int buffer_capacity = nr_of_frames * sizeof(opus_int16) * nr_of_channels;
|
int buffer_capacity = nr_of_frames * sizeof(opus_int16) * nr_of_channels;
|
||||||
|
|
@ -522,28 +529,32 @@ int OpusCodec::decode(const void* input, int inputBytes, void* output, int outpu
|
||||||
|
|
||||||
size_t resampler_processed = 0;
|
size_t resampler_processed = 0;
|
||||||
opus_int16 *buffer_stereo = nullptr;
|
opus_int16 *buffer_stereo = nullptr;
|
||||||
|
int buffer_stereo_capacity = buffer_capacity * 2;
|
||||||
|
|
||||||
switch (nr_of_channels) {
|
switch (nr_of_channels) {
|
||||||
case 1:
|
case 1:
|
||||||
// Convert to stereo before
|
// Convert to stereo before
|
||||||
buffer_stereo = (opus_int16 *) alloca(buffer_capacity * 2);
|
buffer_stereo = (opus_int16 *) alloca(buffer_stereo_capacity);
|
||||||
for (int i = 0; i < nr_of_frames; i++) {
|
for (int i = 0; i < nr_of_frames; i++) {
|
||||||
buffer_stereo[i * 2 + 1] = buffer_decode[i];
|
buffer_stereo[i * 2 + 1] = buffer_decode[i];
|
||||||
buffer_stereo[i * 2] = buffer_decode[i];
|
buffer_stereo[i * 2] = buffer_decode[i];
|
||||||
}
|
}
|
||||||
return (int) mDecodeResampler.processBuffer(buffer_stereo,
|
assert(buffer_stereo_capacity <= outputCapacity);
|
||||||
decoded * sizeof(opus_int16) * 2,
|
memcpy(output, buffer_stereo, buffer_stereo_capacity);
|
||||||
resampler_processed, output,
|
result = buffer_stereo_capacity;
|
||||||
outputCapacity);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
return (int) mDecodeResampler.processBuffer(buffer_decode,
|
assert(buffer_capacity <= outputCapacity);
|
||||||
decoded * sizeof(opus_int16) *
|
memcpy(output, buffer_decode, buffer_capacity);
|
||||||
nr_of_channels, resampler_processed, output,
|
result = buffer_capacity;
|
||||||
outputCapacity);
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int OpusCodec::plc(int lostPackets, void* output, int outputCapacity)
|
int OpusCodec::plc(int lostPackets, void* output, int outputCapacity)
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ protected:
|
||||||
OpusEncoder *mEncoderCtx;
|
OpusEncoder *mEncoderCtx;
|
||||||
OpusDecoder *mDecoderCtx;
|
OpusDecoder *mDecoderCtx;
|
||||||
int mPTime, mSamplerate, mChannels;
|
int mPTime, mSamplerate, mChannels;
|
||||||
Audio::SpeexResampler mDecodeResampler;
|
// Audio::SpeexResampler mDecodeResampler;
|
||||||
int mDecoderChannels;
|
int mDecoderChannels;
|
||||||
public:
|
public:
|
||||||
struct Params
|
struct Params
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue