Add support for changing Opus encoder bitrate. #11

This commit is contained in:
Michał Słomkowski 2016-04-15 03:13:56 +02:00
parent fa3956f081
commit b7720cc7f3
5 changed files with 61 additions and 11 deletions

View File

@ -10,6 +10,8 @@
namespace mumlib { namespace mumlib {
constexpr int DEFAULT_OPUS_ENCODER_BITRATE = 16000;
using namespace std; using namespace std;
using namespace boost::asio; using namespace boost::asio;
@ -18,6 +20,11 @@ namespace mumlib {
MumlibException(string message) : runtime_error(message) { } MumlibException(string message) : runtime_error(message) { }
}; };
struct MumlibConfiguration {
int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE;
// additional fields will be added in the future
};
struct _Mumlib_Private; struct _Mumlib_Private;
@ -27,6 +34,10 @@ namespace mumlib {
Mumlib(Callback &callback, io_service &ioService); Mumlib(Callback &callback, io_service &ioService);
Mumlib(Callback &callback, MumlibConfiguration &configuration);
Mumlib(Callback &callback, io_service &ioService, MumlibConfiguration &configuration);
virtual ~Mumlib(); virtual ~Mumlib();
void connect(string host, int port, string user, string password); void connect(string host, int port, string user, string password);

View File

@ -28,7 +28,7 @@ namespace mumlib {
class Audio : boost::noncopyable { class Audio : boost::noncopyable {
public: public:
Audio(); Audio(int opusEncoderBitrate = DEFAULT_OPUS_ENCODER_BITRATE);
virtual ~Audio(); virtual ~Audio();
@ -46,6 +46,10 @@ namespace mumlib {
uint8_t *outputBuffer, uint8_t *outputBuffer,
int outputBufferSize = MAX_UDP_LENGTH); int outputBufferSize = MAX_UDP_LENGTH);
void setOpusEncoderBitrate(int bitrate);
int getOpusEncoderBitrate();
void resetEncoder(); void resetEncoder();
private: private:

View File

@ -48,7 +48,9 @@ int main(int argc, char *argv[]) {
while (true) { while (true) {
try { try {
mumlib::Mumlib mum(myCallback); mumlib::MumlibConfiguration conf;
conf.opusEncoderBitrate = 32000;
mumlib::Mumlib mum(myCallback, conf);
myCallback.mum = &mum; myCallback.mum = &mum;
mum.connect(argv[1], 64738, "mumlib_example", argv[2]); mum.connect(argv[1], 64738, "mumlib_example", argv[2]);
mum.run(); mum.run();

View File

@ -4,7 +4,7 @@
static boost::posix_time::seconds RESET_SEQUENCE_NUMBER_INTERVAL(5); static boost::posix_time::seconds RESET_SEQUENCE_NUMBER_INTERVAL(5);
mumlib::Audio::Audio() mumlib::Audio::Audio(int opusEncoderBitrate)
: logger(log4cpp::Category::getInstance("mumlib.Audio")), : logger(log4cpp::Category::getInstance("mumlib.Audio")),
opusDecoder(nullptr), opusDecoder(nullptr),
opusEncoder(nullptr), opusEncoder(nullptr),
@ -24,6 +24,8 @@ mumlib::Audio::Audio()
opus_encoder_ctl(opusEncoder, OPUS_SET_VBR(0)); opus_encoder_ctl(opusEncoder, OPUS_SET_VBR(0));
setOpusEncoderBitrate(opusEncoderBitrate);
resetEncoder(); resetEncoder();
} }
@ -37,6 +39,23 @@ mumlib::Audio::~Audio() {
} }
} }
void mumlib::Audio::setOpusEncoderBitrate(int bitrate) {
int error = opus_encoder_ctl(opusEncoder, OPUS_SET_BITRATE(bitrate));
if (error != OPUS_OK) {
throw AudioException((boost::format("failed to initialize transmission bitrate to %d B/s: %s")
% bitrate % opus_strerror(error)).str());
}
}
int mumlib::Audio::getOpusEncoderBitrate() {
opus_int32 bitrate;
int error = opus_encoder_ctl(opusEncoder, OPUS_GET_BITRATE(&bitrate));
if (error != OPUS_OK) {
throw AudioException((boost::format("failed to read Opus bitrate: %s") % opus_strerror(error)).str());
}
return bitrate;
}
std::pair<int, bool> mumlib::Audio::decodeOpusPayload(uint8_t *inputBuffer, std::pair<int, bool> mumlib::Audio::decodeOpusPayload(uint8_t *inputBuffer,
int inputLength, int inputLength,
int16_t *pcmBuffer, int16_t *pcmBuffer,
@ -166,3 +185,5 @@ mumlib::IncomingAudioPacket mumlib::Audio::decodeIncomingAudioPacket(uint8_t *in
return incomingAudioPacket; return incomingAudioPacket;
} }

View File

@ -33,17 +33,20 @@ namespace mumlib {
int sessionId = 0; int sessionId = 0;
int channelId = 0; int channelId = 0;
_Mumlib_Private(Callback &callback) _Mumlib_Private(Callback &callback, MumlibConfiguration &configuration)
: _Mumlib_Private(callback, *(new io_service())) { : _Mumlib_Private(callback, *(new io_service()), configuration) {
externalIoService = false; externalIoService = false;
} }
_Mumlib_Private(Callback &callback, io_service &ioService) _Mumlib_Private(Callback &callback, io_service &ioService, MumlibConfiguration &configuration)
: callback(callback), : callback(callback),
ioService(ioService), ioService(ioService),
externalIoService(true), externalIoService(true),
transport(ioService, boost::bind(&_Mumlib_Private::processIncomingTcpMessage, this, _1, _2, _3), transport(ioService, boost::bind(&_Mumlib_Private::processIncomingTcpMessage, this, _1, _2, _3),
boost::bind(&_Mumlib_Private::processAudioPacket, this, _1, _2, _3)) { } boost::bind(&_Mumlib_Private::processAudioPacket, this, _1, _2, _3)) {
audio.setOpusEncoderBitrate(configuration.opusEncoderBitrate);
}
virtual ~_Mumlib_Private() { virtual ~_Mumlib_Private() {
if (not externalIoService) { if (not externalIoService) {
@ -334,12 +337,21 @@ namespace mumlib {
}; };
Mumlib::Mumlib(Callback &callback) Mumlib::Mumlib(Callback &callback) {
: impl(new _Mumlib_Private(callback)) { MumlibConfiguration conf;
impl = new _Mumlib_Private(callback, conf);
} }
Mumlib::Mumlib(Callback &callback, io_service &ioService) Mumlib::Mumlib(Callback &callback, io_service &ioService) {
: impl(new _Mumlib_Private(callback, ioService)) { } MumlibConfiguration conf;
impl = new _Mumlib_Private(callback, ioService, conf);
}
Mumlib::Mumlib(Callback &callback, MumlibConfiguration &configuration)
: impl(new _Mumlib_Private(callback, configuration)) { }
Mumlib::Mumlib(Callback &callback, io_service &ioService, MumlibConfiguration &configuration)
: impl(new _Mumlib_Private(callback, ioService, configuration)) { }
Mumlib::~Mumlib() { Mumlib::~Mumlib() {
disconnect(); disconnect();