Showing the changes to plugins/opusCodec/src/OpusDecoder.cpp (1 of 4 files). Show all
Unified · Split
| @@ -18,36 +18,35 @@ static QLoggingCategory decoder("AthenaOpusDecoder"); · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | static QString error_to_string(int error) { | 19 | static QString error_to_string(int error) { |
| 20 | switch (error) { | 20 | switch (error) { |
| 21 | case OPUS_OK: | 21 | case OPUS_OK: |
| 22 | return "OK"; | 22 | return "OK"; |
| 23 | case OPUS_BAD_ARG: | 23 | case OPUS_BAD_ARG: |
| 24 | return "One or more invalid/out of range arguments."; | 24 | return "One or more invalid/out of range arguments."; |
| 25 | case OPUS_BUFFER_TOO_SMALL: | 25 | case OPUS_BUFFER_TOO_SMALL: |
| 26 | return "The mode struct passed is invalid."; | 26 | return "The mode struct passed is invalid."; |
| 27 | case OPUS_INTERNAL_ERROR: | 27 | case OPUS_INTERNAL_ERROR: |
| 28 | return "An internal error was detected."; | 28 | return "An internal error was detected."; |
| 29 | case OPUS_INVALID_PACKET: | 29 | case OPUS_INVALID_PACKET: |
| 30 | return "The compressed data passed is corrupted."; | 30 | return "The compressed data passed is corrupted."; |
| 31 | case OPUS_UNIMPLEMENTED: | 31 | case OPUS_UNIMPLEMENTED: |
| 32 | return "Invalid/unsupported request number."; | 32 | return "Invalid/unsupported request number."; |
| 33 | case OPUS_INVALID_STATE: | 33 | case OPUS_INVALID_STATE: |
| 34 | return "An encoder or decoder structure is invalid or already freed."; | 34 | return "An encoder or decoder structure is invalid or already freed."; |
| 35 | default: | 35 | default: |
| 36 | return QString("Unknown error code: %i").arg(error); | 36 | return QString("Unknown error code: %i").arg(error); |
| 37 | } | 37 | } |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | AthenaOpusDecoder::AthenaOpusDecoder(int sampleRate, int numChannels) | 41 | AthenaOpusDecoder::AthenaOpusDecoder(int sampleRate, int numChannels) { |
| 42 | { | ||
| 43 | int error; | 42 | int error; |
| 44 | 43 | ||
| 45 | _opus_sample_rate = sampleRate; | 44 | _opusSampleRate = sampleRate; |
| 46 | _opus_num_channels = numChannels; | 45 | _opusNumChannels = numChannels; |
| 47 | 46 | ||
| 48 | _decoder = opus_decoder_create(sampleRate, numChannels, &error); | 47 | _decoder = opus_decoder_create(sampleRate, numChannels, &error); |
| 49 | 48 | ||
| 50 | if ( error != OPUS_OK ) { | 49 | if (error != OPUS_OK) { |
| 51 | qCCritical(decoder) << "Failed to initialize Opus encoder: " << error_to_string(error); | 50 | qCCritical(decoder) << "Failed to initialize Opus encoder: " << error_to_string(error); |
| 52 | _decoder = nullptr; | 51 | _decoder = nullptr; |
| 53 | return; | 52 | return; |
| @@ -57,42 +56,39 @@ AthenaOpusDecoder::AthenaOpusDecoder(int sampleRate, int numChannels) · 3 unmodified lines | |||
| 57 | qCDebug(decoder) << "Opus decoder initialized, sampleRate = " << sampleRate << "; numChannels = " << numChannels; | 56 | qCDebug(decoder) << "Opus decoder initialized, sampleRate = " << sampleRate << "; numChannels = " << numChannels; |
| 58 | } | 57 | } |
| 59 | 58 | ||
| 60 | AthenaOpusDecoder::~AthenaOpusDecoder() | 59 | AthenaOpusDecoder::~AthenaOpusDecoder() { |
| 61 | { | 60 | if (_decoder) |
| 62 | if ( _decoder ) | ||
| 63 | opus_decoder_destroy(_decoder); | 61 | opus_decoder_destroy(_decoder); |
| 64 | 62 | ||
| 65 | } | 63 | } |
| 66 | 64 | ||
| 67 | void AthenaOpusDecoder::decode(const QByteArray &encodedBuffer, QByteArray &decodedBuffer) | 65 | void AthenaOpusDecoder::decode(const QByteArray &encodedBuffer, QByteArray &decodedBuffer) { |
| 68 | { | ||
| 69 | assert(_decoder); | 66 | assert(_decoder); |
| 70 | PerformanceTimer perfTimer("AthenaOpusDecoder::decode"); | 67 | PerformanceTimer perfTimer("AthenaOpusDecoder::decode"); |
| 71 | 68 | ||
| 72 | // The audio system encodes and decodes always in fixed size chunks | 69 | // The audio system encodes and decodes always in fixed size chunks |
| 73 | int buffer_size = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast<int>(sizeof(int16_t)) | 70 | int bufferSize = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast<int>(sizeof(int16_t)) |
| 74 | * _opus_num_channels; | 71 | * _opusNumChannels; |
| 75 | 72 | ||
| 76 | decodedBuffer.resize( buffer_size ); | 73 | decodedBuffer.resize(bufferSize); |
| 77 | int buffer_frames = decodedBuffer.size() / _opus_num_channels / static_cast<int>(sizeof( opus_int16 )); | 74 | int bufferFrames = decodedBuffer.size() / _opusNumChannels / static_cast<int>(sizeof( opus_int16 )); |
| 78 | 75 | ||
| 79 | qCDebug(decoder) << "Opus decode: encodedBytes = " << encodedBuffer.length() << "; decodedBufferBytes = " | 76 | qCDebug(decoder) << "Opus decode: encodedBytes = " << encodedBuffer.length() << "; decodedBufferBytes = " |
| 80 | << decodedBuffer.size() << "; frameCount = " << buffer_frames; | 77 | << decodedBuffer.size() << "; frameCount = " << bufferFrames; |
| 81 | int decoded_frames = opus_decode( _decoder, reinterpret_cast<const unsigned char*>(encodedBuffer.data()), | 78 | int decoded_frames = opus_decode(_decoder, reinterpret_cast<const unsigned char*>(encodedBuffer.data()), |
| 82 | encodedBuffer.length(), reinterpret_cast<opus_int16*>(decodedBuffer.data()), buffer_frames, 0 ); | 79 | encodedBuffer.length(), reinterpret_cast<opus_int16*>(decodedBuffer.data()), bufferFrames, 0); |
| 83 | 80 | ||
| 84 | if ( decoded_frames >= 0 ) { | 81 | if (decoded_frames >= 0) { |
| 85 | //qCDebug(decoder) << "Decoded " << decoded_frames << " Opus frames, " << buffer_frames << " expected"; | ||
| 86 | 82 | ||
| 87 | if ( decoded_frames < buffer_frames ) { | 83 | if (decoded_frames < bufferFrames) { |
| 88 | qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << buffer_frames | 84 | qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << bufferFrames |
| 89 | << " were expected!"; | 85 | << " were expected!"; |
| 90 | 86 | ||
| 91 | int start = decoded_frames * static_cast<int>(sizeof(int16_t)) * _opus_num_channels; | 87 | int start = decoded_frames * static_cast<int>(sizeof(int16_t)) * _opusNumChannels; |
| 92 | memset( &decodedBuffer.data()[start], 0, static_cast<size_t>(decodedBuffer.length() - start)); | 88 | memset( &decodedBuffer.data()[start], 0, static_cast<size_t>(decodedBuffer.length() - start)); |
| 93 | } else if ( decoded_frames > buffer_frames ) { | 89 | } else if (decoded_frames > bufferFrames) { |
| 94 | // This should never happen | 90 | // This should never happen |
| 95 | qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << buffer_frames | 91 | qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << bufferFrames |
| 96 | << " were expected! Buffer overflow!?"; | 92 | << " were expected! Buffer overflow!?"; |
| 97 | } | 93 | } |
| 98 | } else { | 94 | } else { |
| @@ -102,40 +98,36 @@ void AthenaOpusDecoder::decode(const QByteArray &encodedBuffer, QByteArray &deco · 3 unmodified lines | |||
| 102 | 98 | ||
| 103 | } | 99 | } |
| 104 | 100 | ||
| 105 | void AthenaOpusDecoder::lostFrame(QByteArray &decodedBuffer) | 101 | void AthenaOpusDecoder::lostFrame(QByteArray &decodedBuffer) { |
| 106 | { | ||
| 107 | assert(_decoder); | 102 | assert(_decoder); |
| 108 | 103 | ||
| 109 | PerformanceTimer perfTimer("AthenaOpusDecoder::lostFrame"); | 104 | PerformanceTimer perfTimer("AthenaOpusDecoder::lostFrame"); |
| 110 | 105 | ||
| 111 | int buffer_size = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast<int>(sizeof(int16_t)) | 106 | int bufferSize = AudioConstants::NETWORK_FRAME_SAMPLES_PER_CHANNEL * static_cast<int>(sizeof(int16_t)) |
| 112 | * _opus_num_channels; | 107 | * _opusNumChannels; |
| 113 | decodedBuffer.resize( buffer_size ); | 108 | decodedBuffer.resize(bufferSize); |
| 114 | int buffer_frames = decodedBuffer.size() / _opus_num_channels / static_cast<int>(sizeof( opus_int16 )); | 109 | int bufferFrames = decodedBuffer.size() / _opusNumChannels / static_cast<int>(sizeof(opus_int16)); |
| 115 | 110 | ||
| 116 | int decoded_frames = opus_decode( _decoder, nullptr, 0, reinterpret_cast<opus_int16*>(decodedBuffer.data()), | 111 | int decoded_frames = opus_decode(_decoder, nullptr, 0, reinterpret_cast<opus_int16*>(decodedBuffer.data()), |
| 117 | buffer_frames, 1 ); | 112 | bufferFrames, 1 ); |
| 118 | 113 | ||
| 119 | if ( decoded_frames >= 0 ) { | 114 | if (decoded_frames >= 0) { |
| 120 | //qCDebug(decoder) << "Produced " << decoded_frames << " opus frames from a lost frame, " << buffer_frames | ||
| 121 | // << " expected"; | ||
| 122 | 115 | ||
| 123 | if ( decoded_frames < buffer_frames ) { | 116 | if ( decoded_frames < bufferFrames ) { |
| 124 | qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << buffer_frames | 117 | qCWarning(decoder) << "Opus decoder returned " << decoded_frames << ", but " << bufferFrames |
| 125 | << " were expected!"; | 118 | << " were expected!"; |
| 126 | 119 | ||
| 127 | int start = decoded_frames * static_cast<int>(sizeof(int16_t)) * _opus_num_channels; | 120 | int start = decoded_frames * static_cast<int>(sizeof(int16_t)) * _opusNumChannels; |
| 128 | memset( &decodedBuffer.data()[start], 0, static_cast<size_t>(decodedBuffer.length() - start)); | 121 | memset( &decodedBuffer.data()[start], 0, static_cast<size_t>(decodedBuffer.length() - start)); |
| 129 | } else if ( decoded_frames > buffer_frames ) { | 122 | } else if (decoded_frames > bufferFrames) { |
| 130 | // This should never happen | 123 | // This should never happen |
| 131 | qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << buffer_frames | 124 | qCCritical(decoder) << "Opus decoder returned " << decoded_frames << ", but only " << bufferFrames |
| 132 | << " were expected! Buffer overflow!?"; | 125 | << " were expected! Buffer overflow!?"; |
| 133 | } | 126 | } |
| 127 | |||
| 134 | } else { | 128 | } else { |
| 135 | qCCritical(decoder) << "Failed to decode lost frame: " << error_to_string(decoded_frames); | 129 | qCCritical(decoder) << "Failed to decode lost frame: " << error_to_string(decoded_frames); |
| 136 | decodedBuffer.fill('\0'); | 130 | decodedBuffer.fill('\0'); |
| 137 | } | 131 | } |
| 138 | 132 | ||
| 139 | } | 133 | } |
| 140 | |||
| 141 | |||