mirror of
https://github.com/overte-org/overte.git
synced 2025-08-04 02:23:38 +02:00
rework plugins to allow different decoder/encoder instances per streams
This commit is contained in:
parent
a71baf5601
commit
ba6bb24595
11 changed files with 135 additions and 24 deletions
|
@ -533,12 +533,16 @@ void AudioMixer::handleNegotiateAudioFormat(QSharedPointer<ReceivedMessage> mess
|
||||||
|
|
||||||
clientData->_codec = selectedCoded;
|
clientData->_codec = selectedCoded;
|
||||||
clientData->_selectedCodecName = selectedCodecName;
|
clientData->_selectedCodecName = selectedCodecName;
|
||||||
|
clientData->_encoder = selectedCoded->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::STEREO);
|
||||||
|
clientData->_decoder = selectedCoded->createDecoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO);
|
||||||
|
|
||||||
qDebug() << "selectedCodecName:" << selectedCodecName;
|
qDebug() << "selectedCodecName:" << selectedCodecName;
|
||||||
|
|
||||||
auto avatarAudioStream = clientData->getAvatarAudioStream();
|
auto avatarAudioStream = clientData->getAvatarAudioStream();
|
||||||
if (avatarAudioStream) {
|
if (avatarAudioStream) {
|
||||||
avatarAudioStream->_codec = selectedCoded;
|
avatarAudioStream->_codec = selectedCoded;
|
||||||
avatarAudioStream->_selectedCodecName = selectedCodecName;
|
avatarAudioStream->_selectedCodecName = selectedCodecName;
|
||||||
|
avatarAudioStream->_decoder = selectedCoded->createDecoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto replyPacket = NLPacket::create(PacketType::SelectedAudioFormat);
|
auto replyPacket = NLPacket::create(PacketType::SelectedAudioFormat);
|
||||||
|
@ -777,7 +781,7 @@ void AudioMixer::broadcastMixes() {
|
||||||
QByteArray decocedBuffer(reinterpret_cast<char*>(_clampedSamples), AudioConstants::NETWORK_FRAME_BYTES_STEREO);
|
QByteArray decocedBuffer(reinterpret_cast<char*>(_clampedSamples), AudioConstants::NETWORK_FRAME_BYTES_STEREO);
|
||||||
QByteArray encodedBuffer;
|
QByteArray encodedBuffer;
|
||||||
if (nodeData->_codec) {
|
if (nodeData->_codec) {
|
||||||
nodeData->_codec->encode(decocedBuffer, encodedBuffer);
|
nodeData->_encoder->encode(decocedBuffer, encodedBuffer);
|
||||||
} else {
|
} else {
|
||||||
encodedBuffer = decocedBuffer;
|
encodedBuffer = decocedBuffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,14 @@ AudioMixerClientData::AudioMixerClientData(const QUuid& nodeID) :
|
||||||
_frameToSendStats = distribution(numberGenerator);
|
_frameToSendStats = distribution(numberGenerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioMixerClientData::~AudioMixerClientData() {
|
||||||
|
if (_codec) {
|
||||||
|
_codec->releaseDecoder(_decoder);
|
||||||
|
_codec->releaseEncoder(_encoder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() {
|
AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() {
|
||||||
QReadLocker readLocker { &_streamsLock };
|
QReadLocker readLocker { &_streamsLock };
|
||||||
|
|
||||||
|
@ -104,6 +112,9 @@ int AudioMixerClientData::parseData(ReceivedMessage& message) {
|
||||||
auto avatarAudioStream = new AvatarAudioStream(isStereo, AudioMixer::getStreamSettings());
|
auto avatarAudioStream = new AvatarAudioStream(isStereo, AudioMixer::getStreamSettings());
|
||||||
avatarAudioStream->_codec = _codec;
|
avatarAudioStream->_codec = _codec;
|
||||||
avatarAudioStream->_selectedCodecName = _selectedCodecName;
|
avatarAudioStream->_selectedCodecName = _selectedCodecName;
|
||||||
|
if (_codec) {
|
||||||
|
avatarAudioStream->_decoder = _codec->createDecoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO);
|
||||||
|
}
|
||||||
qDebug() << "creating new AvatarAudioStream... codec:" << avatarAudioStream->_selectedCodecName;
|
qDebug() << "creating new AvatarAudioStream... codec:" << avatarAudioStream->_selectedCodecName;
|
||||||
|
|
||||||
auto emplaced = _audioStreams.emplace(
|
auto emplaced = _audioStreams.emplace(
|
||||||
|
|
|
@ -29,6 +29,7 @@ class AudioMixerClientData : public NodeData {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AudioMixerClientData(const QUuid& nodeID);
|
AudioMixerClientData(const QUuid& nodeID);
|
||||||
|
~AudioMixerClientData();
|
||||||
|
|
||||||
using SharedStreamPointer = std::shared_ptr<PositionalAudioStream>;
|
using SharedStreamPointer = std::shared_ptr<PositionalAudioStream>;
|
||||||
using AudioStreamMap = std::unordered_map<QUuid, SharedStreamPointer>;
|
using AudioStreamMap = std::unordered_map<QUuid, SharedStreamPointer>;
|
||||||
|
@ -70,6 +71,8 @@ public:
|
||||||
// FIXME -- maybe make these private
|
// FIXME -- maybe make these private
|
||||||
CodecPluginPointer _codec;
|
CodecPluginPointer _codec;
|
||||||
QString _selectedCodecName;
|
QString _selectedCodecName;
|
||||||
|
Encoder* _encoder { nullptr }; // for outbound mixed stream
|
||||||
|
Decoder* _decoder { nullptr }; // for mic stream
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
|
@ -536,6 +536,8 @@ void AudioClient::handleSelectedAudioFormat(QSharedPointer<ReceivedMessage> mess
|
||||||
for (auto& plugin : codecPlugins) {
|
for (auto& plugin : codecPlugins) {
|
||||||
if (_selectedCodecName == plugin->getName()) {
|
if (_selectedCodecName == plugin->getName()) {
|
||||||
_receivedAudioStream._codec = _codec = plugin;
|
_receivedAudioStream._codec = _codec = plugin;
|
||||||
|
_receivedAudioStream._decoder = plugin->createDecoder(AudioConstants::SAMPLE_RATE, AudioConstants::STEREO);
|
||||||
|
_encoder = plugin->createEncoder(AudioConstants::SAMPLE_RATE, AudioConstants::MONO);
|
||||||
qDebug() << "Selected Codec Plugin:" << _codec.get();
|
qDebug() << "Selected Codec Plugin:" << _codec.get();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -815,8 +817,8 @@ void AudioClient::handleAudioInput() {
|
||||||
// TODO - codec encode goes here
|
// TODO - codec encode goes here
|
||||||
QByteArray decocedBuffer(reinterpret_cast<char*>(networkAudioSamples), numNetworkBytes);
|
QByteArray decocedBuffer(reinterpret_cast<char*>(networkAudioSamples), numNetworkBytes);
|
||||||
QByteArray encodedBuffer;
|
QByteArray encodedBuffer;
|
||||||
if (_codec) {
|
if (_encoder) {
|
||||||
_codec->encode(decocedBuffer, encodedBuffer);
|
_encoder->encode(decocedBuffer, encodedBuffer);
|
||||||
} else {
|
} else {
|
||||||
encodedBuffer = decocedBuffer;
|
encodedBuffer = decocedBuffer;
|
||||||
}
|
}
|
||||||
|
@ -833,8 +835,8 @@ void AudioClient::handleRecordedAudioInput(const QByteArray& audio) {
|
||||||
|
|
||||||
// TODO - codec encode goes here
|
// TODO - codec encode goes here
|
||||||
QByteArray encodedBuffer;
|
QByteArray encodedBuffer;
|
||||||
if (_codec) {
|
if (_encoder) {
|
||||||
_codec->encode(audio, encodedBuffer);
|
_encoder->encode(audio, encodedBuffer);
|
||||||
} else {
|
} else {
|
||||||
encodedBuffer = audio;
|
encodedBuffer = audio;
|
||||||
}
|
}
|
||||||
|
|
|
@ -299,6 +299,7 @@ private:
|
||||||
|
|
||||||
CodecPluginPointer _codec;
|
CodecPluginPointer _codec;
|
||||||
QString _selectedCodecName;
|
QString _selectedCodecName;
|
||||||
|
Encoder* _encoder { nullptr }; // for outbound mic stream
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -179,8 +179,8 @@ int InboundAudioStream::parseStreamProperties(PacketType type, const QByteArray&
|
||||||
|
|
||||||
int InboundAudioStream::parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties) {
|
int InboundAudioStream::parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties) {
|
||||||
QByteArray decodedBuffer;
|
QByteArray decodedBuffer;
|
||||||
if (_codec) {
|
if (_decoder) {
|
||||||
_codec->decode(packetAfterStreamProperties, decodedBuffer);
|
_decoder->decode(packetAfterStreamProperties, decodedBuffer);
|
||||||
} else {
|
} else {
|
||||||
decodedBuffer = packetAfterStreamProperties;
|
decodedBuffer = packetAfterStreamProperties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,6 +179,7 @@ public:
|
||||||
// FIXME -- maybe make these private
|
// FIXME -- maybe make these private
|
||||||
CodecPluginPointer _codec;
|
CodecPluginPointer _codec;
|
||||||
QString _selectedCodecName;
|
QString _selectedCodecName;
|
||||||
|
Decoder* _decoder { nullptr };
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/// This function should be called every second for all the stats to function properly. If dynamic jitter buffers
|
/// This function should be called every second for all the stats to function properly. If dynamic jitter buffers
|
||||||
|
|
|
@ -44,8 +44,8 @@ int MixedProcessedAudioStream::writeLastFrameRepeatedWithFade(int samples) {
|
||||||
|
|
||||||
int MixedProcessedAudioStream::parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties) {
|
int MixedProcessedAudioStream::parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties) {
|
||||||
QByteArray decodedBuffer;
|
QByteArray decodedBuffer;
|
||||||
if (_codec) {
|
if (_decoder) {
|
||||||
_codec->decode(packetAfterStreamProperties, decodedBuffer);
|
_decoder->decode(packetAfterStreamProperties, decodedBuffer);
|
||||||
} else {
|
} else {
|
||||||
decodedBuffer = packetAfterStreamProperties;
|
decodedBuffer = packetAfterStreamProperties;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,23 @@
|
||||||
|
|
||||||
#include "Plugin.h"
|
#include "Plugin.h"
|
||||||
|
|
||||||
class CodecPlugin : public Plugin {
|
class Encoder {
|
||||||
public:
|
public:
|
||||||
virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) = 0;
|
|
||||||
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) = 0;
|
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Decoder {
|
||||||
|
public:
|
||||||
|
virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) = 0;
|
||||||
|
|
||||||
|
// numFrames - number of samples (mono) or sample-pairs (stereo)
|
||||||
|
virtual void trackLostFrames(int numFrames) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CodecPlugin : public Plugin {
|
||||||
|
public:
|
||||||
|
virtual Encoder* createEncoder(int sampleRate, int numChannels) = 0;
|
||||||
|
virtual Decoder* createDecoder(int sampleRate, int numChannels) = 0;
|
||||||
|
virtual void releaseEncoder(Encoder* encoder) = 0;
|
||||||
|
virtual void releaseDecoder(Decoder* decoder) = 0;
|
||||||
|
};
|
||||||
|
|
|
@ -37,15 +37,54 @@ bool PCMCodec::isSupported() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PCMEncoder : public Encoder {
|
||||||
|
public:
|
||||||
|
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override {
|
||||||
|
encodedBuffer = decodedBuffer;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void PCMCodec::decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) {
|
class PCMDecoder : public Decoder {
|
||||||
decodedBuffer = encodedBuffer;
|
public:
|
||||||
|
virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) override {
|
||||||
|
decodedBuffer = encodedBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void trackLostFrames(int numFrames) override { }
|
||||||
|
};
|
||||||
|
|
||||||
|
Encoder* PCMCodec::createEncoder(int sampleRate, int numChannels) {
|
||||||
|
return new PCMEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PCMCodec::encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) {
|
Decoder* PCMCodec::createDecoder(int sampleRate, int numChannels) {
|
||||||
encodedBuffer = decodedBuffer;
|
return new PCMDecoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PCMCodec::releaseEncoder(Encoder* encoder) {
|
||||||
|
delete encoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PCMCodec::releaseDecoder(Decoder* decoder) {
|
||||||
|
delete decoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class zLibEncoder : public Encoder {
|
||||||
|
public:
|
||||||
|
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override {
|
||||||
|
encodedBuffer = qCompress(decodedBuffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class zLibDecoder : public Decoder {
|
||||||
|
public:
|
||||||
|
virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) override {
|
||||||
|
decodedBuffer = qUncompress(encodedBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void trackLostFrames(int numFrames) override { }
|
||||||
|
};
|
||||||
|
|
||||||
const QString zLibCodec::NAME = "zlib";
|
const QString zLibCodec::NAME = "zlib";
|
||||||
|
|
||||||
|
@ -69,10 +108,19 @@ bool zLibCodec::isSupported() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void zLibCodec::decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) {
|
Encoder* zLibCodec::createEncoder(int sampleRate, int numChannels) {
|
||||||
decodedBuffer = qUncompress(encodedBuffer);
|
return new zLibEncoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void zLibCodec::encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) {
|
Decoder* zLibCodec::createDecoder(int sampleRate, int numChannels) {
|
||||||
encodedBuffer = qCompress(decodedBuffer);
|
return new zLibDecoder();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void zLibCodec::releaseEncoder(Encoder* encoder) {
|
||||||
|
delete encoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
void zLibCodec::releaseDecoder(Decoder* decoder) {
|
||||||
|
delete decoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,31 @@
|
||||||
#ifndef hifi__PCMCodecManager_h
|
#ifndef hifi__PCMCodecManager_h
|
||||||
#define hifi__PCMCodecManager_h
|
#define hifi__PCMCodecManager_h
|
||||||
|
|
||||||
|
|
||||||
#include <plugins/CodecPlugin.h>
|
#include <plugins/CodecPlugin.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
class Encoder {
|
||||||
|
public:
|
||||||
|
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Decoder {
|
||||||
|
public:
|
||||||
|
virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) = 0;
|
||||||
|
|
||||||
|
// numFrames - number of samples (mono) or sample-pairs (stereo)
|
||||||
|
virtual void trackLostFrames(int numFrames) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CodecPlugin : public Plugin {
|
||||||
|
public:
|
||||||
|
virtual Encoder* createEncoder(int sampleRate, int numChannels) = 0;
|
||||||
|
virtual Decoder* createDecoder(int sampleRate, int numChannels) = 0;
|
||||||
|
virtual void releaseEncoder(Encoder* encoder) = 0;
|
||||||
|
virtual void releaseDecoder(Decoder* decoder) = 0;
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
class PCMCodec : public CodecPlugin {
|
class PCMCodec : public CodecPlugin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
@ -31,8 +53,10 @@ public:
|
||||||
/// Called when a plugin is no longer being used. May be called multiple times.
|
/// Called when a plugin is no longer being used. May be called multiple times.
|
||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
|
|
||||||
virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) override;
|
virtual Encoder* createEncoder(int sampleRate, int numChannels) override;
|
||||||
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override;
|
virtual Decoder* createDecoder(int sampleRate, int numChannels) override;
|
||||||
|
virtual void releaseEncoder(Encoder* encoder) override;
|
||||||
|
virtual void releaseDecoder(Decoder* decoder) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
|
@ -54,8 +78,11 @@ public:
|
||||||
/// Called when a plugin is no longer being used. May be called multiple times.
|
/// Called when a plugin is no longer being used. May be called multiple times.
|
||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
|
|
||||||
virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) override;
|
virtual Encoder* createEncoder(int sampleRate, int numChannels) override;
|
||||||
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override;
|
virtual Decoder* createDecoder(int sampleRate, int numChannels) override;
|
||||||
|
virtual void releaseEncoder(Encoder* encoder) override;
|
||||||
|
virtual void releaseDecoder(Decoder* decoder) override;
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
|
|
Loading…
Reference in a new issue