From ed9715ae5f25a828dca312740c9da33690653b96 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sun, 10 Jul 2016 17:40:58 -0700 Subject: [PATCH] some cleanup, proper memory allocation/deallocation --- assignment-client/src/audio/AudioMixer.cpp | 22 ++++---------- .../src/audio/AudioMixerClientData.cpp | 30 +++++++++++++++---- .../src/audio/AudioMixerClientData.h | 20 +++++++++---- libraries/audio-client/src/AudioClient.cpp | 15 ++++++++-- libraries/audio/src/InboundAudioStream.cpp | 18 +++++++++++ libraries/audio/src/InboundAudioStream.h | 11 ++++--- 6 files changed, 81 insertions(+), 35 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 825f970f2e..2f1a5de309 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -478,7 +478,7 @@ void AudioMixer::handleNegotiateAudioFormat(QSharedPointer mess qDebug() << "No Codecs available..."; } - CodecPluginPointer selectedCoded; + CodecPluginPointer selectedCodec; QString selectedCodecName; QStringList codecPreferenceList = _codecPreferenceOrder.split(","); @@ -513,7 +513,7 @@ void AudioMixer::handleNegotiateAudioFormat(QSharedPointer mess for (auto& plugin : codecPlugins) { if (selectedCodecName == plugin->getName()) { qDebug() << "Selecting codec:" << selectedCodecName; - selectedCoded = plugin; + selectedCodec = plugin; break; } } @@ -531,18 +531,13 @@ void AudioMixer::handleNegotiateAudioFormat(QSharedPointer mess connect(clientData, &AudioMixerClientData::injectorStreamFinished, this, &AudioMixer::removeHRTFsForFinishedInjector); } - clientData->_codec = selectedCoded; - clientData->_selectedCodecName = selectedCodecName; - clientData->_encoder = selectedCoded->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::STEREO); - clientData->_decoder = selectedCoded->createDecoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO); + clientData->setupCodec(selectedCodec, selectedCodecName); qDebug() << "selectedCodecName:" << selectedCodecName; auto avatarAudioStream = clientData->getAvatarAudioStream(); if (avatarAudioStream) { - avatarAudioStream->_codec = selectedCoded; - avatarAudioStream->_selectedCodecName = selectedCodecName; - avatarAudioStream->_decoder = selectedCoded->createDecoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO); + avatarAudioStream->setupCodec(selectedCodec, selectedCodecName, AudioConstants::MONO); } auto replyPacket = NLPacket::create(PacketType::SelectedAudioFormat); @@ -777,14 +772,9 @@ void AudioMixer::broadcastMixes() { quint16 sequence = nodeData->getOutgoingSequenceNumber(); mixPacket->writePrimitive(sequence); - // TODO - codec encode goes here - QByteArray decocedBuffer(reinterpret_cast(_clampedSamples), AudioConstants::NETWORK_FRAME_BYTES_STEREO); + QByteArray decodedBuffer(reinterpret_cast(_clampedSamples), AudioConstants::NETWORK_FRAME_BYTES_STEREO); QByteArray encodedBuffer; - if (nodeData->_codec) { - nodeData->_encoder->encode(decocedBuffer, encodedBuffer); - } else { - encodedBuffer = decocedBuffer; - } + nodeData->encode(decodedBuffer, encodedBuffer); // pack mixed audio samples mixPacket->write(encodedBuffer.constData(), encodedBuffer.size()); diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 3e9b72d60e..c733683e5a 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -110,12 +110,8 @@ int AudioMixerClientData::parseData(ReceivedMessage& message) { bool isStereo = channelFlag == 1; auto avatarAudioStream = new AvatarAudioStream(isStereo, AudioMixer::getStreamSettings()); - avatarAudioStream->_codec = _codec; - avatarAudioStream->_selectedCodecName = _selectedCodecName; - if (_codec) { - avatarAudioStream->_decoder = _codec->createDecoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO); - } - qDebug() << "creating new AvatarAudioStream... codec:" << avatarAudioStream->_selectedCodecName; + avatarAudioStream->setupCodec(_codec, _selectedCodecName, AudioConstants::MONO); + qDebug() << "creating new AvatarAudioStream... codec:" << _selectedCodecName; auto emplaced = _audioStreams.emplace( QUuid(), @@ -340,3 +336,25 @@ QJsonObject AudioMixerClientData::getAudioStreamStats() { return result; } + +void AudioMixerClientData::setupCodec(CodecPluginPointer codec, const QString& codecName) { + cleanupCodec(); // cleanup any previously allocated coders first + _codec = codec; + _selectedCodecName = codecName; + _encoder = codec->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::STEREO); + _decoder = codec->createDecoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO); +} + +void AudioMixerClientData::cleanupCodec() { + // release any old codec encoder/decoder first... + if (_codec) { + if (_decoder) { + _codec->releaseDecoder(_decoder); + _decoder = nullptr; + } + if (_encoder) { + _codec->releaseEncoder(_encoder); + _encoder = nullptr; + } + } +} diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index ee6f22ff3b..da2bf8997c 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -68,12 +68,15 @@ public: AudioLimiter audioLimiter; - // FIXME -- maybe make these private - CodecPluginPointer _codec; - QString _selectedCodecName; - Encoder* _encoder { nullptr }; // for outbound mixed stream - Decoder* _decoder { nullptr }; // for mic stream - + void setupCodec(CodecPluginPointer codec, const QString& codecName); + void cleanupCodec(); + void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) { + if (_encoder) { + _encoder->encode(decodedBuffer, encodedBuffer); + } else { + encodedBuffer = decodedBuffer; + } + } signals: void injectorStreamFinished(const QUuid& streamIdentifier); @@ -91,6 +94,11 @@ private: AudioStreamStats _downstreamAudioStreamStats; int _frameToSendStats { 0 }; + + CodecPluginPointer _codec; + QString _selectedCodecName; + Encoder* _encoder{ nullptr }; // for outbound mixed stream + Decoder* _decoder{ nullptr }; // for mic stream }; #endif // hifi_AudioMixerClientData_h diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index db5376a380..28fd95f599 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -140,6 +140,10 @@ AudioClient::AudioClient() : AudioClient::~AudioClient() { stop(); + if (_codec && _encoder) { + _codec->releaseEncoder(_encoder); + _encoder = nullptr; + } } void AudioClient::reset() { @@ -529,14 +533,19 @@ void AudioClient::negotiateAudioFormat() { void AudioClient::handleSelectedAudioFormat(QSharedPointer message) { qDebug() << __FUNCTION__; - _receivedAudioStream._selectedCodecName = _selectedCodecName = message->readString(); + _selectedCodecName = message->readString(); qDebug() << "Selected Codec:" << _selectedCodecName; auto codecPlugins = PluginManager::getInstance()->getCodecPlugins(); for (auto& plugin : codecPlugins) { if (_selectedCodecName == plugin->getName()) { - _receivedAudioStream._codec = _codec = plugin; - _receivedAudioStream._decoder = plugin->createDecoder(AudioConstants::SAMPLE_RATE, AudioConstants::STEREO); + // release any old codec encoder/decoder first... + if (_codec && _encoder) { + _codec->releaseEncoder(_encoder); + _encoder = nullptr; + } + _codec = plugin; + _receivedAudioStream.setupCodec(plugin, _selectedCodecName, AudioConstants::STEREO); _encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO); qDebug() << "Selected Codec Plugin:" << _codec.get(); break; diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index f47c6cce46..144005bc11 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -504,3 +504,21 @@ float calculateRepeatedFrameFadeFactor(int indexOfRepeat) { return 0.0f; } +void InboundAudioStream::setupCodec(CodecPluginPointer codec, const QString& codecName, int numChannels) { + cleanupCodec(); // cleanup any previously allocated coders first + _codec = codec; + _selectedCodecName = codecName; + if (_codec) { + _decoder = codec->createDecoder(AudioConstants::SAMPLE_RATE, numChannels); + } +} + +void InboundAudioStream::cleanupCodec() { + // release any old codec encoder/decoder first... + if (_codec) { + if (_decoder) { + _codec->releaseDecoder(_decoder); + _decoder = nullptr; + } + } +} diff --git a/libraries/audio/src/InboundAudioStream.h b/libraries/audio/src/InboundAudioStream.h index 57bff80fff..5da63f96c2 100644 --- a/libraries/audio/src/InboundAudioStream.h +++ b/libraries/audio/src/InboundAudioStream.h @@ -105,6 +105,7 @@ public: public: InboundAudioStream(int numFrameSamples, int numFramesCapacity, const Settings& settings); + ~InboundAudioStream() { cleanupCodec(); } void reset(); virtual void resetStats(); @@ -176,10 +177,8 @@ public: void setReverb(float reverbTime, float wetLevel); void clearReverb() { _hasReverb = false; } - // FIXME -- maybe make these private - CodecPluginPointer _codec; - QString _selectedCodecName; - Decoder* _decoder { nullptr }; + void setupCodec(CodecPluginPointer codec, const QString& codecName, int numChannels); + void cleanupCodec(); public slots: /// This function should be called every second for all the stats to function properly. If dynamic jitter buffers @@ -274,6 +273,10 @@ protected: bool _hasReverb; float _reverbTime; float _wetLevel; + + CodecPluginPointer _codec; + QString _selectedCodecName; + Decoder* _decoder{ nullptr }; }; float calculateRepeatedFrameFadeFactor(int indexOfRepeat);