diff --git a/plugins/opusCodec/src/OpusDecoder.cpp b/plugins/opusCodec/src/OpusDecoder.cpp index 080742a127..6afd50d125 100644 --- a/plugins/opusCodec/src/OpusDecoder.cpp +++ b/plugins/opusCodec/src/OpusDecoder.cpp @@ -59,23 +59,32 @@ AthenaOpusDecoder::~AthenaOpusDecoder() void AthenaOpusDecoder::decode(const QByteArray &encodedBuffer, QByteArray &decodedBuffer) { assert(_decoder); - PerformanceTimer perfTimer("AthenaOpusDecoder::decode"); - + // The audio system encodes and decodes always in fixed size chunks int buffer_size = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast(sizeof(int16_t)) * _opus_num_channels; decodedBuffer.resize( buffer_size ); - int frame_size = decodedBuffer.size() / _opus_num_channels / static_cast(sizeof( opus_int16 )); + int buffer_frames = decodedBuffer.size() / _opus_num_channels / static_cast(sizeof( opus_int16 )); - qCDebug(decoder) << "Opus decode: encodedBytes = " << encodedBuffer.length() << "; decodedBufferBytes = " << decodedBuffer.size() << "; frameCount = " << frame_size; - int frames = opus_decode( _decoder, reinterpret_cast(encodedBuffer.data()), encodedBuffer.length(), reinterpret_cast(decodedBuffer.data()), frame_size, 0 ); + qCDebug(decoder) << "Opus decode: encodedBytes = " << encodedBuffer.length() << "; decodedBufferBytes = " << decodedBuffer.size() << "; frameCount = " << buffer_frames; + int decoded_frames = opus_decode( _decoder, reinterpret_cast(encodedBuffer.data()), encodedBuffer.length(), reinterpret_cast(decodedBuffer.data()), buffer_frames, 0 ); - if ( frames >= 0 ) { - qCDebug(decoder) << "Decoded " << frames << " Opus frames"; - decodedBuffer.resize( frames * static_cast(sizeof( opus_int16 )) * _opus_num_channels ); + if ( decoded_frames >= 0 ) { + qCDebug(decoder) << "Decoded " << decoded_frames << " Opus frames, " << buffer_frames << " expected"; + + if ( decoded_frames < buffer_frames ) { + qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << buffer_frames << " were expected!"; + + int start = decoded_frames * static_cast(sizeof(int16_t)) * _opus_num_channels; + memset( &decodedBuffer.data()[start], 0, static_cast(decodedBuffer.length() - start)); + } else if ( decoded_frames > buffer_frames ) { + // This should never happen + qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << buffer_frames << " were expected! Buffer overflow!?"; + } } else { - qCCritical(decoder) << "Failed to decode audio: " << error_to_string(frames); + qCCritical(decoder) << "Failed to decode audio: " << error_to_string(decoded_frames); + decodedBuffer.fill('\0'); } } @@ -88,15 +97,26 @@ void AthenaOpusDecoder::lostFrame(QByteArray &decodedBuffer) int buffer_size = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast(sizeof(int16_t)) * _opus_num_channels; decodedBuffer.resize( buffer_size ); - int frame_size = decodedBuffer.size() / _opus_num_channels / static_cast(sizeof( opus_int16 )); + int buffer_frames = decodedBuffer.size() / _opus_num_channels / static_cast(sizeof( opus_int16 )); - int frames = opus_decode( _decoder, nullptr, 0, reinterpret_cast(decodedBuffer.data()), frame_size, 1 ); + int decoded_frames = opus_decode( _decoder, nullptr, 0, reinterpret_cast(decodedBuffer.data()), buffer_frames, 1 ); - if ( frames >= 0 ) { - qCDebug(decoder) << "Produced " << frames << " opus frames from a lost frame"; - decodedBuffer.resize( frames * static_cast(sizeof( opus_int16 )) * _opus_num_channels ); + if ( decoded_frames >= 0 ) { + + qCDebug(decoder) << "Produced " << decoded_frames << " opus frames from a lost frame, " << buffer_frames << " expected"; + + if ( decoded_frames < buffer_frames ) { + qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << buffer_frames << " were expected!"; + + int start = decoded_frames * static_cast(sizeof(int16_t)) * _opus_num_channels; + memset( &decodedBuffer.data()[start], 0, static_cast(decodedBuffer.length() - start)); + } else if ( decoded_frames > buffer_frames ) { + // This should never happen + qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << buffer_frames << " were expected! Buffer overflow!?"; + } } else { - qCCritical(decoder) << "Failed to decode lost frame: " << error_to_string(frames); + qCCritical(decoder) << "Failed to decode lost frame: " << error_to_string(decoded_frames); + decodedBuffer.fill('\0'); } }