mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-07 13:12:39 +02:00
Initial attempt at Opus compression.
This commit is contained in:
parent
a39ad97a1f
commit
cf56bf415f
7 changed files with 486 additions and 33 deletions
|
@ -22,6 +22,9 @@
|
|||
#include <opus/opus_multistream.h>
|
||||
#include <opus/opus_projection.h>
|
||||
|
||||
#include "OpusEncoder.h"
|
||||
#include "OpusDecoder.h"
|
||||
|
||||
#define FRAME_SIZE 960
|
||||
#define SAMPLE_RATE 48000
|
||||
#define CHANNELS 2
|
||||
|
@ -31,56 +34,41 @@
|
|||
#define MAX_FRAME_SIZE 6*FRAME_SIZE
|
||||
#define MAX_PACKET_SIZE 3*1276
|
||||
|
||||
const char* OpusCodec::NAME { "opus" };
|
||||
const char* AthenaOpusCodec::NAME { "opus" };
|
||||
|
||||
void OpusCodec::init() {
|
||||
void AthenaOpusCodec::init() {
|
||||
}
|
||||
|
||||
void OpusCodec::deinit() {
|
||||
void AthenaOpusCodec::deinit() {
|
||||
}
|
||||
|
||||
bool OpusCodec::activate() {
|
||||
bool AthenaOpusCodec::activate() {
|
||||
CodecPlugin::activate();
|
||||
return true;
|
||||
}
|
||||
|
||||
void OpusCodec::deactivate() {
|
||||
void AthenaOpusCodec::deactivate() {
|
||||
CodecPlugin::deactivate();
|
||||
}
|
||||
|
||||
|
||||
bool OpusCodec::isSupported() const {
|
||||
bool AthenaOpusCodec::isSupported() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
class OpusEncoder : public Encoder {
|
||||
public:
|
||||
OpusEncoder(int sampleRate, int numChannels) {
|
||||
|
||||
}
|
||||
|
||||
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override {
|
||||
encodedBuffer.resize(_encodedSize);
|
||||
}
|
||||
|
||||
private:
|
||||
int _encodedSize;
|
||||
};
|
||||
|
||||
|
||||
Encoder* OpusCodec::createEncoder(int sampleRate, int numChannels) {
|
||||
return new OpusEncoder(sampleRate, numChannels);
|
||||
Encoder* AthenaOpusCodec::createEncoder(int sampleRate, int numChannels) {
|
||||
return new AthenaOpusEncoder(sampleRate, numChannels);
|
||||
}
|
||||
|
||||
Decoder* OpusCodec::createDecoder(int sampleRate, int numChannels) {
|
||||
return this;
|
||||
Decoder* AthenaOpusCodec::createDecoder(int sampleRate, int numChannels) {
|
||||
return new AthenaOpusDecoder(sampleRate, numChannels);
|
||||
}
|
||||
|
||||
void OpusCodec::releaseEncoder(Encoder* encoder) {
|
||||
void AthenaOpusCodec::releaseEncoder(Encoder* encoder) {
|
||||
delete encoder;
|
||||
}
|
||||
|
||||
void OpusCodec::releaseDecoder(Decoder* decoder) {
|
||||
void AthenaOpusCodec::releaseDecoder(Decoder* decoder) {
|
||||
delete decoder;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <plugins/CodecPlugin.h>
|
||||
|
||||
class OpusCodec : public CodecPlugin, public Encoder, public Decoder {
|
||||
class AthenaOpusCodec : public CodecPlugin {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
@ -35,6 +35,7 @@ public:
|
|||
virtual void releaseEncoder(Encoder* encoder) override;
|
||||
virtual void releaseDecoder(Decoder* decoder) override;
|
||||
|
||||
|
||||
private:
|
||||
static const char* NAME;
|
||||
};
|
||||
|
|
|
@ -17,20 +17,20 @@
|
|||
|
||||
#include "OpusCodecManager.h"
|
||||
|
||||
class OpusCodecProvider : public QObject, public CodecProvider {
|
||||
class AthenaOpusCodecProvider : public QObject, public CodecProvider {
|
||||
Q_OBJECT
|
||||
Q_PLUGIN_METADATA(IID CodecProvider_iid FILE "plugin.json")
|
||||
Q_INTERFACES(CodecProvider)
|
||||
|
||||
public:
|
||||
OpusCodecProvider(QObject* parent = nullptr) : QObject(parent) {}
|
||||
virtual ~OpusCodecProvider() {}
|
||||
AthenaOpusCodecProvider(QObject* parent = nullptr) : QObject(parent) {}
|
||||
virtual ~AthenaOpusCodecProvider() {}
|
||||
|
||||
virtual CodecPluginList getCodecPlugins() override {
|
||||
static std::once_flag once;
|
||||
std::call_once(once, [&] {
|
||||
|
||||
CodecPluginPointer opusCodec(new OpusCodec());
|
||||
CodecPluginPointer opusCodec(new AthenaOpusCodec());
|
||||
if (opusCodec->isSupported()) {
|
||||
_codecPlugins.push_back(opusCodec);
|
||||
}
|
||||
|
|
97
plugins/opusCodec/src/OpusDecoder.cpp
Normal file
97
plugins/opusCodec/src/OpusDecoder.cpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
#include <PerfStat.h>
|
||||
#include <QtCore/QLoggingCategory>
|
||||
|
||||
|
||||
|
||||
#include "OpusDecoder.h"
|
||||
|
||||
static QLoggingCategory decoder("AthenaOpusDecoder");
|
||||
|
||||
static QString error_to_string(int error) {
|
||||
switch (error) {
|
||||
case OPUS_OK:
|
||||
return "OK";
|
||||
case OPUS_BAD_ARG:
|
||||
return "One or more invalid/out of range arguments.";
|
||||
case OPUS_BUFFER_TOO_SMALL:
|
||||
return "The mode struct passed is invalid.";
|
||||
case OPUS_INTERNAL_ERROR:
|
||||
return "An internal error was detected.";
|
||||
case OPUS_INVALID_PACKET:
|
||||
return "The compressed data passed is corrupted.";
|
||||
case OPUS_UNIMPLEMENTED:
|
||||
return "Invalid/unsupported request number.";
|
||||
case OPUS_INVALID_STATE:
|
||||
return "An encoder or decoder structure is invalid or already freed.";
|
||||
default:
|
||||
return QString("Unknown error code: %i").arg(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
AthenaOpusDecoder::AthenaOpusDecoder(int sampleRate, int numChannels)
|
||||
{
|
||||
int error;
|
||||
|
||||
_opus_sample_rate = sampleRate;
|
||||
_opus_num_channels = numChannels;
|
||||
|
||||
_decoder = opus_decoder_create(sampleRate, numChannels, &error);
|
||||
|
||||
if ( error != OPUS_OK ) {
|
||||
qCCritical(decoder) << "Failed to initialize Opus encoder: " << error_to_string(error);
|
||||
_decoder = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
qCDebug(decoder) << "Opus decoder initialized";
|
||||
}
|
||||
|
||||
AthenaOpusDecoder::~AthenaOpusDecoder()
|
||||
{
|
||||
if ( _decoder )
|
||||
opus_decoder_destroy(_decoder);
|
||||
|
||||
}
|
||||
|
||||
void AthenaOpusDecoder::decode(const QByteArray &encodedBuffer, QByteArray &decodedBuffer)
|
||||
{
|
||||
assert(_decoder);
|
||||
|
||||
PerformanceTimer perfTimer("AthenaOpusDecoder::decode");
|
||||
|
||||
decodedBuffer.resize( 65536 ); // Brute force, yeah!
|
||||
int frame_size = decodedBuffer.size() / _opus_num_channels / static_cast<int>(sizeof( opus_int16 ));
|
||||
|
||||
int frames = opus_decode( _decoder, reinterpret_cast<const unsigned char*>(encodedBuffer.data()), encodedBuffer.length(), reinterpret_cast<opus_int16*>(decodedBuffer.data()), frame_size, 1 );
|
||||
|
||||
if ( frames >= 0 ) {
|
||||
qCDebug(decoder) << "Decoded " << frames << " Opus frames";
|
||||
decodedBuffer.resize( frames * static_cast<int>(sizeof( opus_int16 )) * _opus_num_channels );
|
||||
} else {
|
||||
qCCritical(decoder) << "Failed to decode audio: " << error_to_string(frames);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void AthenaOpusDecoder::lostFrame(QByteArray &decodedBuffer)
|
||||
{
|
||||
assert(_decoder);
|
||||
|
||||
PerformanceTimer perfTimer("AthenaOpusDecoder::lostFrame");
|
||||
|
||||
decodedBuffer.resize( 65536 ); // Brute force, yeah!
|
||||
int frame_size = decodedBuffer.size() / _opus_num_channels / static_cast<int>(sizeof( opus_int16 ));
|
||||
|
||||
int frames = opus_decode( _decoder, nullptr, 0, reinterpret_cast<opus_int16*>(decodedBuffer.data()), frame_size, 1 );
|
||||
|
||||
if ( frames >= 0 ) {
|
||||
qCDebug(decoder) << "Produced " << frames << " opus frames from a lost frame";
|
||||
decodedBuffer.resize( frames * static_cast<int>(sizeof( opus_int16 )) * _opus_num_channels );
|
||||
} else {
|
||||
qCCritical(decoder) << "Failed to decode lost frame: " << error_to_string(frames);
|
||||
}
|
||||
}
|
||||
|
||||
|
28
plugins/opusCodec/src/OpusDecoder.h
Normal file
28
plugins/opusCodec/src/OpusDecoder.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef OPUSDECODER_H
|
||||
#define OPUSDECODER_H
|
||||
|
||||
|
||||
#include <plugins/CodecPlugin.h>
|
||||
#include "opus/opus.h"
|
||||
|
||||
|
||||
class AthenaOpusDecoder : public Decoder {
|
||||
public:
|
||||
AthenaOpusDecoder(int sampleRate, int numChannels);
|
||||
~AthenaOpusDecoder() override;
|
||||
|
||||
|
||||
virtual void decode(const QByteArray& encodedBuffer, QByteArray& decodedBuffer) override;
|
||||
virtual void lostFrame( QByteArray &decodedBuffer) override;
|
||||
|
||||
|
||||
private:
|
||||
int _encodedSize;
|
||||
|
||||
OpusDecoder *_decoder = nullptr;
|
||||
int _opus_sample_rate = 0;
|
||||
int _opus_num_channels = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif // OPUSDECODER_H
|
270
plugins/opusCodec/src/OpusEncoder.cpp
Normal file
270
plugins/opusCodec/src/OpusEncoder.cpp
Normal file
|
@ -0,0 +1,270 @@
|
|||
|
||||
#include <PerfStat.h>
|
||||
#include <QtCore/QLoggingCategory>
|
||||
|
||||
#include "OpusEncoder.h"
|
||||
#include "OpusWrapper.h"
|
||||
#include "opus/opus.h"
|
||||
|
||||
static QLoggingCategory encoder("AthenaOpusEncoder");
|
||||
|
||||
static QString error_to_string(int error) {
|
||||
switch (error) {
|
||||
case OPUS_OK:
|
||||
return "OK";
|
||||
case OPUS_BAD_ARG:
|
||||
return "One or more invalid/out of range arguments.";
|
||||
case OPUS_BUFFER_TOO_SMALL:
|
||||
return "The mode struct passed is invalid.";
|
||||
case OPUS_INTERNAL_ERROR:
|
||||
return "An internal error was detected.";
|
||||
case OPUS_INVALID_PACKET:
|
||||
return "The compressed data passed is corrupted.";
|
||||
case OPUS_UNIMPLEMENTED:
|
||||
return "Invalid/unsupported request number.";
|
||||
case OPUS_INVALID_STATE:
|
||||
return "An encoder or decoder structure is invalid or already freed.";
|
||||
default:
|
||||
return QString("Unknown error code: %i").arg(error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
AthenaOpusEncoder::AthenaOpusEncoder(int sampleRate, int numChannels)
|
||||
{
|
||||
_opus_sample_rate = sampleRate;
|
||||
_opus_channels = numChannels;
|
||||
|
||||
int error;
|
||||
|
||||
_encoder = opus_encoder_create(sampleRate, numChannels, DEFAULT_APPLICATION, &error);
|
||||
|
||||
if ( error != OPUS_OK ) {
|
||||
qCCritical(encoder) << "Failed to initialize Opus encoder: " << error_to_string(error);
|
||||
_encoder = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
setBitrate(DEFAULT_BITRATE);
|
||||
setComplexity(DEFAULT_COMPLEXITY);
|
||||
setApplication(DEFAULT_APPLICATION);
|
||||
setSignal(DEFAULT_SIGNAL);
|
||||
|
||||
qCDebug(encoder) << "Opus encoder initialized";
|
||||
}
|
||||
|
||||
AthenaOpusEncoder::~AthenaOpusEncoder()
|
||||
{
|
||||
opus_encoder_destroy(_encoder);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void AthenaOpusEncoder::encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) {
|
||||
|
||||
PerformanceTimer perfTimer("AthenaOpusEncoder::encode");
|
||||
assert(_encoder);
|
||||
|
||||
encodedBuffer.resize( decodedBuffer.size() );
|
||||
int frame_size = decodedBuffer.length()/ _opus_channels / static_cast<int>(sizeof(opus_int16));
|
||||
|
||||
int bytes = opus_encode(_encoder, reinterpret_cast<const opus_int16*>(decodedBuffer.data()), frame_size, reinterpret_cast<unsigned char*>(encodedBuffer.data()), encodedBuffer.size() );
|
||||
|
||||
if ( bytes >= 0 ) {
|
||||
qCDebug(encoder) << "Encoded " << decodedBuffer.length() << " bytes into " << bytes << " opus bytes";
|
||||
encodedBuffer.resize(bytes);
|
||||
} else {
|
||||
encodedBuffer.resize(0);
|
||||
|
||||
qCWarning(encoder) << "Error when encoding " << decodedBuffer.length() << " bytes of audio: " << error_to_string(bytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getComplexity() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_COMPLEXITY(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setComplexity(int complexity)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_COMPLEXITY(complexity));
|
||||
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting complexity to " << complexity << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getBitrate() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_BITRATE(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setBitrate(int bitrate)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_BITRATE(bitrate));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting bitrate to " << bitrate << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getVBR() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_VBR(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setVBR(int vbr)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_VBR(vbr));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting VBR to " << vbr << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getVBRConstraint() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_VBR_CONSTRAINT(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setVBRConstraint(int vbr_const)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_VBR_CONSTRAINT(vbr_const));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting VBR constraint to " << vbr_const << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getMaxBandwidth() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_MAX_BANDWIDTH(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setMaxBandwidth(int maxbw)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_MAX_BANDWIDTH(maxbw));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting max bandwidth to " << maxbw << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getBandwidth() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_BANDWIDTH(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setBandwidth(int bw)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_BANDWIDTH(bw));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting bandwidth to " << bw << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getSignal() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_SIGNAL(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setSignal(int signal)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_SIGNAL(signal));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting signal to " << signal << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getApplication() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_APPLICATION(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setApplication(int app)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_APPLICATION(app));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting application to " << app << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getLookahead() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_LOOKAHEAD(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getInbandFEC() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_INBAND_FEC(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setInbandFEC(int fec)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_INBAND_FEC(fec));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting inband FEC to " << fec << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getExpectedPacketLossPercent() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_PACKET_LOSS_PERC(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setExpectedPacketLossPercent(int perc)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_PACKET_LOSS_PERC(perc));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting loss percent to " << perc << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
int AthenaOpusEncoder::getDTX() const
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret;
|
||||
opus_encoder_ctl(_encoder, OPUS_GET_DTX(&ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void AthenaOpusEncoder::setDTX(int dtx)
|
||||
{
|
||||
assert(_encoder);
|
||||
int ret = opus_encoder_ctl(_encoder, OPUS_SET_DTX(dtx));
|
||||
if ( ret != OPUS_OK )
|
||||
qCWarning(encoder) << "Error when setting DTX to " << dtx << ": " << error_to_string(ret);
|
||||
}
|
||||
|
||||
|
69
plugins/opusCodec/src/OpusEncoder.h
Normal file
69
plugins/opusCodec/src/OpusEncoder.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
#ifndef OPUSENCODER_H
|
||||
#define OPUSENCODER_H
|
||||
#include <plugins/CodecPlugin.h>
|
||||
#include "OpusWrapper.h"
|
||||
#include "opus/opus.h"
|
||||
|
||||
|
||||
class AthenaOpusEncoder : public Encoder {
|
||||
public:
|
||||
const int DEFAULT_BITRATE = 44100;
|
||||
const int DEFAULT_COMPLEXITY = 10;
|
||||
const int DEFAULT_APPLICATION = OPUS_APPLICATION_VOIP;
|
||||
const int DEFAULT_SIGNAL = OPUS_AUTO;
|
||||
|
||||
|
||||
AthenaOpusEncoder(int sampleRate, int numChannels);
|
||||
~AthenaOpusEncoder() override;
|
||||
|
||||
virtual void encode(const QByteArray& decodedBuffer, QByteArray& encodedBuffer) override;
|
||||
|
||||
|
||||
int getComplexity() const;
|
||||
void setComplexity(int complexity);
|
||||
|
||||
int getBitrate() const;
|
||||
void setBitrate(int bitrate);
|
||||
|
||||
int getVBR() const;
|
||||
void setVBR(int vbr);
|
||||
|
||||
int getVBRConstraint() const;
|
||||
void setVBRConstraint(int vbr_const);
|
||||
|
||||
int getMaxBandwidth() const;
|
||||
void setMaxBandwidth(int maxbw);
|
||||
|
||||
int getBandwidth() const;
|
||||
void setBandwidth(int bw);
|
||||
|
||||
int getSignal() const;
|
||||
void setSignal(int signal);
|
||||
|
||||
int getApplication() const;
|
||||
void setApplication(int app);
|
||||
|
||||
int getLookahead() const;
|
||||
|
||||
int getInbandFEC() const;
|
||||
void setInbandFEC(int fec);
|
||||
|
||||
int getExpectedPacketLossPercent() const;
|
||||
void setExpectedPacketLossPercent(int perc);
|
||||
|
||||
int getDTX() const;
|
||||
void setDTX(int dtx);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
int _opus_sample_rate = 0;
|
||||
int _opus_channels = 0;
|
||||
int _opus_expected_loss = 0;
|
||||
|
||||
|
||||
OpusEncoder *_encoder = nullptr;
|
||||
};
|
||||
|
||||
|
||||
#endif // OPUSENCODER_H
|
Loading…
Reference in a new issue