Opus support: Support multistream
This commit is contained in:
parent
7beef32a8a
commit
db28464d61
2 changed files with 441 additions and 39 deletions
|
@ -17,6 +17,8 @@ struct invalid_state : public std::runtime_error { invalid_state(); };
|
|||
|
||||
class encoder;
|
||||
class decoder;
|
||||
class multistream_encoder;
|
||||
class multistream_decoder;
|
||||
|
||||
template<typename T> struct generic_eget
|
||||
{
|
||||
|
@ -25,6 +27,12 @@ template<typename T> struct generic_eget
|
|||
T errordefault() const;
|
||||
};
|
||||
|
||||
template<typename T> struct generic_meget : public generic_eget<T>
|
||||
{
|
||||
using generic_eget<T>::operator();
|
||||
T operator()(multistream_encoder& e) const;
|
||||
};
|
||||
|
||||
template<typename T> struct generic_get
|
||||
{
|
||||
typedef T drettype;
|
||||
|
@ -34,6 +42,13 @@ template<typename T> struct generic_get
|
|||
T errordefault() const;
|
||||
};
|
||||
|
||||
template<typename T> struct generic_mget : public generic_get<T>
|
||||
{
|
||||
using generic_get<T>::operator();
|
||||
T operator()(multistream_decoder& e) const;
|
||||
T operator()(multistream_encoder& e) const;
|
||||
};
|
||||
|
||||
template<typename T> struct generic_dget
|
||||
{
|
||||
typedef T drettype;
|
||||
|
@ -41,6 +56,12 @@ template<typename T> struct generic_dget
|
|||
T errordefault() const;
|
||||
};
|
||||
|
||||
template<typename T> struct generic_mdget : public generic_dget<T>
|
||||
{
|
||||
using generic_dget<T>::operator();
|
||||
T operator()(multistream_decoder& e) const;
|
||||
};
|
||||
|
||||
struct samplerate
|
||||
{
|
||||
samplerate(int32_t _fs) { fs = _fs; }
|
||||
|
@ -52,6 +73,9 @@ struct samplerate
|
|||
operator int32_t() { return fs; }
|
||||
typedef samplerate erettype;
|
||||
samplerate operator()(encoder& e) const;
|
||||
samplerate operator()(multistream_encoder& e) const;
|
||||
samplerate operator()(decoder& e) const;
|
||||
samplerate operator()(multistream_decoder& e) const;
|
||||
samplerate errordefault() const { return samplerate(0); }
|
||||
private:
|
||||
int32_t fs;
|
||||
|
@ -61,9 +85,10 @@ struct complexity
|
|||
{
|
||||
complexity(int32_t _c) { c = _c; }
|
||||
operator int32_t() { return c; }
|
||||
static generic_eget<complexity> get;
|
||||
static generic_meget<complexity> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
int32_t c;
|
||||
|
@ -75,9 +100,10 @@ struct bitrate
|
|||
static bitrate _auto;
|
||||
static bitrate max;
|
||||
operator int32_t() { return b; }
|
||||
static generic_eget<bitrate> get;
|
||||
static generic_meget<bitrate> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
int32_t b;
|
||||
|
@ -89,9 +115,10 @@ struct vbr
|
|||
static vbr cbr;
|
||||
static vbr _vbr;
|
||||
operator bool() { return v; }
|
||||
static generic_eget<vbr> get;
|
||||
static generic_meget<vbr> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
bool v;
|
||||
|
@ -103,9 +130,10 @@ struct vbr_constraint
|
|||
static vbr_constraint unconstrained;
|
||||
static vbr_constraint constrained;
|
||||
operator bool() { return c; }
|
||||
static generic_eget<vbr_constraint> get;
|
||||
static generic_meget<vbr_constraint> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
bool c;
|
||||
|
@ -118,9 +146,10 @@ struct force_channels
|
|||
static force_channels mono;
|
||||
static force_channels stereo;
|
||||
operator int32_t() { return f; }
|
||||
static generic_eget<force_channels> get;
|
||||
static generic_meget<force_channels> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
int32_t f;
|
||||
|
@ -153,9 +182,10 @@ struct bandwidth
|
|||
static bandwidth superwide;
|
||||
static bandwidth full;
|
||||
operator int32_t() { return bw; }
|
||||
static generic_get<bandwidth> get;
|
||||
static generic_mget<bandwidth> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
int32_t bw;
|
||||
|
@ -168,9 +198,10 @@ struct signal
|
|||
static signal music;
|
||||
static signal voice;
|
||||
operator int32_t() { return s; }
|
||||
static generic_eget<signal> get;
|
||||
static generic_meget<signal> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
int32_t s;
|
||||
|
@ -183,9 +214,10 @@ struct application
|
|||
static application voice;
|
||||
static application lowdelay;
|
||||
operator int32_t() { return app; }
|
||||
static generic_eget<application> get;
|
||||
static generic_meget<application> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
int32_t app;
|
||||
|
@ -198,6 +230,7 @@ struct _lookahead
|
|||
operator uint32_t() { return l; }
|
||||
typedef _lookahead erettype;
|
||||
_lookahead operator()(encoder& e) const;
|
||||
_lookahead operator()(multistream_encoder& e) const;
|
||||
_lookahead errordefault() const { return _lookahead(0);}
|
||||
private:
|
||||
uint32_t l;
|
||||
|
@ -210,9 +243,10 @@ struct fec
|
|||
static fec disabled;
|
||||
static fec enabled;
|
||||
operator bool() { return f; }
|
||||
static generic_eget<fec> get;
|
||||
static generic_meget<fec> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
bool f;
|
||||
|
@ -222,9 +256,10 @@ struct lossperc
|
|||
{
|
||||
lossperc(uint32_t _loss) { loss = _loss; };
|
||||
operator uint32_t() { return loss; }
|
||||
static generic_eget<lossperc> get;
|
||||
static generic_meget<lossperc> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
uint32_t loss;
|
||||
|
@ -236,9 +271,10 @@ struct dtx
|
|||
static dtx disabled;
|
||||
static dtx enabled;
|
||||
operator bool() { return d; }
|
||||
static generic_eget<dtx> get;
|
||||
static generic_meget<dtx> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
bool d;
|
||||
|
@ -251,9 +287,10 @@ struct lsbdepth
|
|||
static lsbdepth d16;
|
||||
static lsbdepth d24;
|
||||
operator uint32_t() { return depth; }
|
||||
static generic_eget<lsbdepth> get;
|
||||
static generic_meget<lsbdepth> get;
|
||||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
uint32_t depth;
|
||||
|
@ -264,9 +301,10 @@ struct _pktduration
|
|||
_pktduration() { d = 0; }
|
||||
_pktduration(uint32_t _d) { d = _d; }
|
||||
operator uint32_t() { return d; }
|
||||
typedef _pktduration erettype;
|
||||
_pktduration operator()(encoder& e) const;
|
||||
_pktduration errordefault() const { return _pktduration(0); }
|
||||
typedef _pktduration drettype;
|
||||
_pktduration operator()(decoder& e) const;
|
||||
_pktduration operator()(multistream_decoder& e) const;
|
||||
_pktduration errordefault() const; /*{ return _pktduration(0); }*/
|
||||
private:
|
||||
uint32_t d;
|
||||
};
|
||||
|
@ -278,6 +316,8 @@ struct _reset
|
|||
typedef void erettype;
|
||||
void operator()(decoder& e) const;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(multistream_decoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void errordefault() const {}
|
||||
};
|
||||
extern _reset reset;
|
||||
|
@ -291,6 +331,8 @@ struct _finalrange
|
|||
typedef _finalrange erettype;
|
||||
_finalrange operator()(decoder& e) const;
|
||||
_finalrange operator()(encoder& e) const;
|
||||
_finalrange operator()(multistream_decoder& e) const;
|
||||
_finalrange operator()(multistream_encoder& e) const;
|
||||
_finalrange errordefault() const { return _finalrange(0); }
|
||||
private:
|
||||
uint32_t f;
|
||||
|
@ -316,9 +358,10 @@ struct gain
|
|||
{
|
||||
gain(int32_t _g) { g = _g; };
|
||||
operator int32_t() { return g; }
|
||||
static generic_dget<gain> get;
|
||||
static generic_mdget<gain> get;
|
||||
typedef void drettype;
|
||||
void operator()(decoder& d) const;
|
||||
void operator()(multistream_decoder& d) const;
|
||||
gain errordefault() const { return gain(0); }
|
||||
private:
|
||||
int32_t g;
|
||||
|
@ -331,6 +374,8 @@ struct set_control_int
|
|||
typedef void erettype;
|
||||
void operator()(encoder& e) const;
|
||||
void operator()(decoder& e) const;
|
||||
void operator()(multistream_encoder& e) const;
|
||||
void operator()(multistream_decoder& e) const;
|
||||
void errordefault() const {}
|
||||
private:
|
||||
int32_t ctl;
|
||||
|
@ -344,6 +389,8 @@ struct get_control_int
|
|||
typedef int32_t erettype;
|
||||
int32_t operator()(encoder& e) const;
|
||||
int32_t operator()(decoder& e) const;
|
||||
int32_t operator()(multistream_encoder& e) const;
|
||||
int32_t operator()(multistream_decoder& e) const;
|
||||
int32_t errordefault() const { return -1; }
|
||||
private:
|
||||
int32_t ctl;
|
||||
|
@ -358,6 +405,7 @@ public:
|
|||
encoder(const encoder& e);
|
||||
encoder(const encoder& e, char* memory);
|
||||
static size_t size(bool stereo);
|
||||
size_t size() const { return size(stereo); }
|
||||
encoder& operator=(const encoder& e);
|
||||
template<typename T> typename T::erettype ctl(const T& c) { return c(*this); }
|
||||
template<typename T> typename T::erettype ctl_quiet(const T& c)
|
||||
|
@ -383,6 +431,7 @@ public:
|
|||
decoder(const decoder& e);
|
||||
decoder(const decoder& e, char* memory);
|
||||
static size_t size(bool stereo);
|
||||
size_t size() const { return size(stereo); }
|
||||
decoder& operator=(const decoder& e);
|
||||
template<typename T> typename T::drettype ctl(const T& c) { return c(*this); }
|
||||
template<typename T> typename T::drettype ctl_quiet(const T& c)
|
||||
|
@ -421,6 +470,78 @@ private:
|
|||
bool user;
|
||||
};
|
||||
|
||||
class multistream_encoder
|
||||
{
|
||||
public:
|
||||
multistream_encoder(samplerate rate, unsigned channels, unsigned streams,
|
||||
unsigned coupled_streams, const unsigned char* mapping, application app, char* memory = NULL);
|
||||
static size_t size(unsigned streams, unsigned coupled_streams);
|
||||
size_t size() const { return size(streams, coupled); }
|
||||
multistream_encoder(const multistream_encoder& e);
|
||||
multistream_encoder(const multistream_encoder& e, char* memory);
|
||||
multistream_encoder& operator=(const multistream_encoder& e);
|
||||
~multistream_encoder();
|
||||
encoder& operator[](size_t idx);
|
||||
size_t encode(const int16_t* in, uint32_t inframes, unsigned char* out, uint32_t maxout);
|
||||
size_t encode(const float* in, uint32_t inframes, unsigned char* out, uint32_t maxout);
|
||||
template<typename T> typename T::erettype ctl(const T& c) { return c(*this); }
|
||||
template<typename T> typename T::erettype ctl_quiet(const T& c)
|
||||
{
|
||||
try { return c(*this); } catch(...) { return c.errordefault(); }
|
||||
}
|
||||
uint8_t get_channels() { return channels; }
|
||||
uint8_t get_streams() { return streams; }
|
||||
void* getmem() { return memory + offset; }
|
||||
private:
|
||||
void init_copy(const multistream_encoder& e, char* memory);
|
||||
char* substream(size_t idx);
|
||||
void set_params(uint8_t _channels, uint8_t _streams, uint8_t _coupled);
|
||||
char* memory;
|
||||
bool user;
|
||||
uint8_t channels;
|
||||
uint8_t streams;
|
||||
uint8_t coupled;
|
||||
size_t offset;
|
||||
size_t opussize;
|
||||
};
|
||||
|
||||
class multistream_decoder
|
||||
{
|
||||
public:
|
||||
multistream_decoder(samplerate rate, unsigned channels, unsigned streams,
|
||||
unsigned coupled_streams, const unsigned char* mapping, char* memory = NULL);
|
||||
static size_t size(unsigned streams, unsigned coupled_streams);
|
||||
size_t size() const { return size(streams, coupled); }
|
||||
multistream_decoder(const multistream_decoder& e);
|
||||
multistream_decoder(const multistream_decoder& e, char* memory);
|
||||
multistream_decoder& operator=(const multistream_decoder& e);
|
||||
~multistream_decoder();
|
||||
decoder& operator[](size_t idx);
|
||||
template<typename T> typename T::drettype ctl(const T& c) { return c(*this); }
|
||||
template<typename T> typename T::drettype ctl_quiet(const T& c)
|
||||
{
|
||||
try { return c(*this); } catch(...) { return c.errordefault(); }
|
||||
}
|
||||
size_t decode(const unsigned char* in, uint32_t insize, int16_t* out, uint32_t maxframes,
|
||||
bool decode_fec = false);
|
||||
size_t decode(const unsigned char* in, uint32_t insize, float* out, uint32_t maxframes,
|
||||
bool decode_fec = false);
|
||||
uint8_t get_channels() { return channels; }
|
||||
uint8_t get_streams() { return streams; }
|
||||
void* getmem() { return memory + offset; }
|
||||
private:
|
||||
void init_copy(const multistream_decoder& e, char* memory);
|
||||
char* substream(size_t idx);
|
||||
void set_params(uint8_t _channels, uint8_t _streams, uint8_t _coupled);
|
||||
char* memory;
|
||||
bool user;
|
||||
uint8_t channels;
|
||||
uint8_t streams;
|
||||
uint8_t coupled;
|
||||
size_t offset;
|
||||
size_t opussize;
|
||||
};
|
||||
|
||||
struct parsed_frame
|
||||
{
|
||||
const unsigned char* ptr;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "opus.hpp"
|
||||
#include <opus.h>
|
||||
#include <opus_defines.h>
|
||||
#include <opus_multistream.h>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
|
||||
|
@ -87,6 +88,13 @@ unimplemented::unimplemented()
|
|||
invalid_state::invalid_state()
|
||||
: std::runtime_error("Invalid state") {}
|
||||
|
||||
char* alignptr(char* ptr, size_t align)
|
||||
{
|
||||
while((intptr_t)ptr % align)
|
||||
ptr++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int32_t throwex(int32_t ret)
|
||||
{
|
||||
if(ret >= 0)
|
||||
|
@ -146,7 +154,8 @@ template<> gain get_ctlnum<gain>::errordefault() { return gain(0); }
|
|||
OpusEncoder* E(encoder& e) { return reinterpret_cast<OpusEncoder*>(e.getmem()); }
|
||||
OpusDecoder* D(decoder& d) { return reinterpret_cast<OpusDecoder*>(d.getmem()); }
|
||||
OpusRepacketizer* R(repacketizer& r) { return reinterpret_cast<OpusRepacketizer*>(r.getmem()); }
|
||||
|
||||
OpusMSEncoder* ME(multistream_encoder& e) { return reinterpret_cast<OpusMSEncoder*>(e.getmem()); }
|
||||
OpusMSDecoder* MD(multistream_decoder& d) { return reinterpret_cast<OpusMSDecoder*>(d.getmem()); }
|
||||
|
||||
template<typename T> T generic_ctl(encoder& e, int32_t ctl)
|
||||
{
|
||||
|
@ -172,14 +181,34 @@ template<typename T> T generic_ctl(decoder& d, int32_t ctl, T val)
|
|||
throwex(opus_decoder_ctl(D(d), ctl, val));
|
||||
}
|
||||
|
||||
template<typename T> T do_generic_get(encoder& e)
|
||||
template<typename T> T generic_ctl(multistream_encoder& e, int32_t ctl, T val)
|
||||
{
|
||||
return T(generic_ctl<int32_t>(e, get_ctlnum<T>::num));
|
||||
throwex(opus_multistream_encoder_ctl(ME(e), ctl, val));
|
||||
}
|
||||
|
||||
template<typename T> T do_generic_get(decoder& d)
|
||||
template<typename T> T generic_ctl(multistream_encoder& e, int32_t ctl)
|
||||
{
|
||||
return T(generic_ctl<int32_t>(d, get_ctlnum<T>::num));
|
||||
T val;
|
||||
throwex(opus_multistream_encoder_ctl(ME(e), ctl, &val));
|
||||
return val;
|
||||
}
|
||||
|
||||
template<typename T> T generic_ctl(multistream_decoder& d, int32_t ctl, T val)
|
||||
{
|
||||
throwex(opus_multistream_decoder_ctl(MD(d), ctl, val));
|
||||
}
|
||||
|
||||
template<typename T> T generic_ctl(multistream_decoder& d, int32_t ctl)
|
||||
{
|
||||
T val;
|
||||
throwex(opus_multistream_decoder_ctl(MD(d), ctl, &val));
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
template<typename T, typename U> T do_generic_get(U& e)
|
||||
{
|
||||
return T(generic_ctl<int32_t>(e, get_ctlnum<T>::num));
|
||||
}
|
||||
|
||||
template<typename T> T generic_eget<T>::operator()(encoder& e) const
|
||||
|
@ -187,11 +216,21 @@ template<typename T> T generic_eget<T>::operator()(encoder& e) const
|
|||
return do_generic_get<T>(e);
|
||||
}
|
||||
|
||||
template<typename T> T generic_meget<T>::operator()(multistream_encoder& e) const
|
||||
{
|
||||
return do_generic_get<T>(e);
|
||||
}
|
||||
|
||||
template<typename T> T generic_dget<T>::operator()(decoder& d) const
|
||||
{
|
||||
return do_generic_get<T>(d);
|
||||
}
|
||||
|
||||
template<typename T> T generic_mdget<T>::operator()(multistream_decoder& d) const
|
||||
{
|
||||
return do_generic_get<T>(d);
|
||||
}
|
||||
|
||||
template<typename T> T generic_get<T>::operator()(decoder& d) const
|
||||
{
|
||||
return do_generic_get<T>(d);
|
||||
|
@ -202,6 +241,16 @@ template<typename T> T generic_get<T>::operator()(encoder& e) const
|
|||
return do_generic_get<T>(e);
|
||||
}
|
||||
|
||||
template<typename T> T generic_mget<T>::operator()(multistream_encoder& e) const
|
||||
{
|
||||
return do_generic_get<T>(e);
|
||||
}
|
||||
|
||||
template<typename T> T generic_mget<T>::operator()(multistream_decoder& d) const
|
||||
{
|
||||
return do_generic_get<T>(d);
|
||||
}
|
||||
|
||||
template<typename T> T generic_eget<T>::errordefault() const
|
||||
{
|
||||
return get_ctlnum<T>::errordefault();
|
||||
|
@ -217,7 +266,6 @@ template<typename T> T generic_get<T>::errordefault() const
|
|||
return get_ctlnum<T>::errordefault();
|
||||
}
|
||||
|
||||
|
||||
samplerate samplerate::operator()(encoder& e) const
|
||||
{
|
||||
return samplerate(generic_ctl<int32_t>(e, OPUS_GET_SAMPLE_RATE_REQUEST));
|
||||
|
@ -228,35 +276,40 @@ void complexity::operator()(encoder& e) const
|
|||
generic_ctl(e, OPUS_SET_COMPLEXITY_REQUEST, c);
|
||||
}
|
||||
|
||||
generic_eget<complexity> complexity::get;
|
||||
generic_meget<complexity> complexity::get;
|
||||
|
||||
void bitrate::operator()(encoder& e) const
|
||||
{
|
||||
generic_ctl(e, OPUS_SET_BITRATE_REQUEST, b);
|
||||
}
|
||||
|
||||
generic_eget<bitrate> bitrate::get;
|
||||
void bitrate::operator()(multistream_encoder& e) const
|
||||
{
|
||||
generic_ctl(e, OPUS_SET_BITRATE_REQUEST, b);
|
||||
}
|
||||
|
||||
generic_meget<bitrate> bitrate::get;
|
||||
|
||||
void vbr::operator()(encoder& e) const
|
||||
{
|
||||
generic_ctl<int32_t>(e, OPUS_SET_VBR_REQUEST, (int32_t)(v ? 1 : 0));
|
||||
}
|
||||
|
||||
generic_eget<vbr> vbr::get;
|
||||
generic_meget<vbr> vbr::get;
|
||||
|
||||
void vbr_constraint::operator()(encoder& e) const
|
||||
{
|
||||
generic_ctl<int32_t>(e, OPUS_SET_VBR_CONSTRAINT_REQUEST, (int32_t)(c ? 1 : 0));
|
||||
}
|
||||
|
||||
generic_eget<vbr_constraint> vbr_constraint::get;
|
||||
generic_meget<vbr_constraint> vbr_constraint::get;
|
||||
|
||||
void force_channels::operator()(encoder& e) const
|
||||
{
|
||||
generic_ctl(e, OPUS_SET_FORCE_CHANNELS_REQUEST, f);
|
||||
}
|
||||
|
||||
generic_eget<force_channels> force_channels::get;
|
||||
generic_meget<force_channels> force_channels::get;
|
||||
|
||||
void max_bandwidth::operator()(encoder& e) const
|
||||
{
|
||||
|
@ -270,21 +323,21 @@ void bandwidth::operator()(encoder& e) const
|
|||
generic_ctl(e, OPUS_SET_BANDWIDTH_REQUEST, bw);
|
||||
}
|
||||
|
||||
generic_get<bandwidth> bandwidth::get;
|
||||
generic_mget<bandwidth> bandwidth::get;
|
||||
|
||||
void signal::operator()(encoder& e) const
|
||||
{
|
||||
generic_ctl(e, OPUS_SET_SIGNAL_REQUEST, s);
|
||||
}
|
||||
|
||||
generic_eget<signal> signal::get;
|
||||
generic_meget<signal> signal::get;
|
||||
|
||||
void application::operator()(encoder& e) const
|
||||
{
|
||||
generic_ctl(e, OPUS_SET_APPLICATION_REQUEST, app);
|
||||
}
|
||||
|
||||
generic_eget<application> application::get;
|
||||
generic_meget<application> application::get;
|
||||
|
||||
_lookahead _lookahead::operator()(encoder& e) const
|
||||
{
|
||||
|
@ -296,32 +349,32 @@ void fec::operator()(encoder& e) const
|
|||
generic_ctl<int32_t>(e, OPUS_SET_INBAND_FEC_REQUEST, (int32_t)(f ? 1 : 0));
|
||||
}
|
||||
|
||||
generic_eget<fec> fec::get;
|
||||
generic_meget<fec> fec::get;
|
||||
|
||||
void lossperc::operator()(encoder& e) const
|
||||
{
|
||||
generic_ctl(e, OPUS_SET_PACKET_LOSS_PERC_REQUEST, (int32_t)loss);
|
||||
}
|
||||
|
||||
generic_eget<lossperc> lossperc::get;
|
||||
generic_meget<lossperc> lossperc::get;
|
||||
|
||||
void dtx::operator()(encoder& e) const
|
||||
{
|
||||
generic_ctl<int32_t>(e, OPUS_SET_DTX_REQUEST, (int32_t)(d ? 1 : 0));
|
||||
}
|
||||
|
||||
generic_eget<dtx> dtx::get;
|
||||
generic_meget<dtx> dtx::get;
|
||||
|
||||
void lsbdepth::operator()(encoder& e) const
|
||||
{
|
||||
generic_ctl(e, OPUS_SET_LSB_DEPTH_REQUEST, (int32_t)depth);
|
||||
}
|
||||
|
||||
generic_eget<lsbdepth> lsbdepth::get;
|
||||
generic_meget<lsbdepth> lsbdepth::get;
|
||||
|
||||
_pktduration _pktduration::operator()(encoder& e) const
|
||||
_pktduration _pktduration::operator()(decoder& d) const
|
||||
{
|
||||
return _pktduration(generic_ctl<int32_t>(e, OPUS_GET_LAST_PACKET_DURATION_REQUEST));
|
||||
return _pktduration(generic_ctl<int32_t>(d, OPUS_GET_LAST_PACKET_DURATION_REQUEST));
|
||||
}
|
||||
|
||||
void _reset::operator()(decoder& d) const
|
||||
|
@ -359,7 +412,7 @@ void gain::operator()(decoder& d) const
|
|||
generic_ctl(d, OPUS_SET_GAIN_REQUEST, g);
|
||||
}
|
||||
|
||||
generic_dget<gain> gain::get;
|
||||
generic_mdget<gain> gain::get;
|
||||
|
||||
void set_control_int::operator()(encoder& e) const
|
||||
{
|
||||
|
@ -371,6 +424,16 @@ void set_control_int::operator()(decoder& d) const
|
|||
generic_ctl(d, ctl, val);
|
||||
}
|
||||
|
||||
void set_control_int::operator()(multistream_encoder& e) const
|
||||
{
|
||||
generic_ctl(e, ctl, val);
|
||||
}
|
||||
|
||||
void set_control_int::operator()(multistream_decoder& d) const
|
||||
{
|
||||
generic_ctl(d, ctl, val);
|
||||
}
|
||||
|
||||
int32_t get_control_int::operator()(encoder& e) const
|
||||
{
|
||||
return generic_ctl<int32_t>(e, ctl);
|
||||
|
@ -381,10 +444,23 @@ int32_t get_control_int::operator()(decoder& d) const
|
|||
return generic_ctl<int32_t>(d, ctl);
|
||||
}
|
||||
|
||||
int32_t get_control_int::operator()(multistream_encoder& e) const
|
||||
{
|
||||
return generic_ctl<int32_t>(e, ctl);
|
||||
}
|
||||
|
||||
int32_t get_control_int::operator()(multistream_decoder& d) const
|
||||
{
|
||||
return generic_ctl<int32_t>(d, ctl);
|
||||
}
|
||||
|
||||
void force_instantiate()
|
||||
{
|
||||
encoder e(samplerate::r48k, true, application::audio);
|
||||
decoder d(samplerate::r48k, true);
|
||||
multistream_encoder me(samplerate::r48k, 1, 1, 0, NULL, application::audio);
|
||||
multistream_decoder md(samplerate::r48k, 1, 1, 0, NULL);
|
||||
|
||||
complexity::get(e);
|
||||
bitrate::get(e);
|
||||
vbr::get(e);
|
||||
|
@ -400,6 +476,19 @@ void force_instantiate()
|
|||
dtx::get(e);
|
||||
lsbdepth::get(e);
|
||||
gain::get(d);
|
||||
bitrate::get(me);
|
||||
lsbdepth::get(me);
|
||||
vbr::get(me);
|
||||
vbr_constraint::get(me);
|
||||
application::get(me);
|
||||
bandwidth::get(me);
|
||||
bandwidth::get(md);
|
||||
complexity::get(me);
|
||||
lossperc::get(me);
|
||||
dtx::get(me);
|
||||
signal::get(me);
|
||||
fec::get(me);
|
||||
force_channels::get(me);
|
||||
|
||||
complexity::get.errordefault();
|
||||
bitrate::get.errordefault();
|
||||
|
@ -416,6 +505,8 @@ void force_instantiate()
|
|||
lsbdepth::get.errordefault();
|
||||
gain::get.errordefault();
|
||||
|
||||
d.ctl(opus::pktduration);
|
||||
//d.ctl_quiet(opus::pktduration);
|
||||
e.ctl_quiet(opus::reset);
|
||||
e.ctl_quiet(opus::finalrange);
|
||||
e.ctl_quiet(opus::signal::get);
|
||||
|
@ -446,7 +537,8 @@ encoder::encoder(samplerate rate, bool _stereo, application app, char* _memory)
|
|||
try {
|
||||
throwex(opus_encoder_init(E(*this), rate, _stereo ? 2 : 1, app));
|
||||
} catch(...) {
|
||||
delete[] reinterpret_cast<char*>(memory);
|
||||
if(!user)
|
||||
delete[] reinterpret_cast<char*>(memory);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -506,7 +598,8 @@ decoder::decoder(samplerate rate, bool _stereo, char* _memory)
|
|||
try {
|
||||
throwex(opus_decoder_init(D(*this), rate, _stereo ? 2 : 1));
|
||||
} catch(...) {
|
||||
delete[] reinterpret_cast<char*>(memory);
|
||||
if(!user)
|
||||
delete[] reinterpret_cast<char*>(memory);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
@ -627,6 +720,194 @@ unsigned repacketizer::get_nb_frames()
|
|||
return opus_repacketizer_get_nb_frames(R(*this));
|
||||
}
|
||||
|
||||
encoder& multistream_encoder::operator[](size_t idx)
|
||||
{
|
||||
if(idx > (size_t)streams)
|
||||
throw opus::bad_argument();
|
||||
return *reinterpret_cast<encoder*>(substream(idx));
|
||||
}
|
||||
|
||||
size_t multistream_encoder::size(unsigned streams, unsigned coupled_streams)
|
||||
{
|
||||
return alignof(encoder) + streams * sizeof(encoder) + opus_multistream_encoder_get_size(streams,
|
||||
coupled_streams);
|
||||
}
|
||||
|
||||
multistream_encoder::~multistream_encoder()
|
||||
{
|
||||
if(!user)
|
||||
delete memory;
|
||||
}
|
||||
|
||||
multistream_encoder::multistream_encoder(samplerate rate, unsigned _channels, unsigned _streams,
|
||||
unsigned coupled_streams, const unsigned char* mapping, application app, char* _memory)
|
||||
{
|
||||
user = (_memory != NULL);
|
||||
memory = _memory ? alignptr(_memory, alignof(encoder)) : new char[size(streams, coupled_streams)];
|
||||
set_params(_channels, _streams, coupled_streams);
|
||||
try {
|
||||
throwex(opus_multistream_encoder_init(ME(*this), rate, channels, _streams, coupled_streams, mapping,
|
||||
app));
|
||||
} catch(...) {
|
||||
if(!user)
|
||||
delete[] memory;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
multistream_encoder::multistream_encoder(const multistream_encoder& e)
|
||||
{
|
||||
init_copy(e, new char[e.size()]);
|
||||
user = false;
|
||||
}
|
||||
|
||||
multistream_encoder::multistream_encoder(const multistream_encoder& e, char* memory)
|
||||
{
|
||||
init_copy(e, memory);
|
||||
user = true;
|
||||
}
|
||||
|
||||
multistream_encoder& multistream_encoder::operator=(const multistream_encoder& e)
|
||||
{
|
||||
if(this == &e)
|
||||
return *this;
|
||||
if(streams != e.streams || coupled != e.coupled)
|
||||
throw std::runtime_error("Stream mismatch in assignment");
|
||||
memcpy(ME(*this), e.memory + e.offset, opussize);
|
||||
channels = e.channels;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void multistream_encoder::init_copy(const multistream_encoder& e, char* _memory)
|
||||
{
|
||||
user = (_memory != NULL);
|
||||
set_params(e.channels, e.streams, e.coupled);
|
||||
memory = _memory ? alignptr(_memory, alignof(encoder)) : new char[e.size()];
|
||||
memcpy(ME(*this), e.memory + e.offset, opussize);
|
||||
for(int32_t i = 0; i < streams; i++) {
|
||||
OpusEncoder* e;
|
||||
opus_multistream_encoder_ctl(ME(*this), OPUS_MULTISTREAM_GET_ENCODER_STATE(i, &e));
|
||||
new(substream(i)) encoder(e, i < coupled);
|
||||
}
|
||||
}
|
||||
|
||||
size_t multistream_encoder::encode(const int16_t* in, uint32_t inframes, unsigned char* out, uint32_t maxout)
|
||||
{
|
||||
return throwex(opus_multistream_encode(ME(*this), in, inframes, out, maxout));
|
||||
}
|
||||
|
||||
size_t multistream_encoder::encode(const float* in, uint32_t inframes, unsigned char* out, uint32_t maxout)
|
||||
{
|
||||
return throwex(opus_multistream_encode_float(ME(*this), in, inframes, out, maxout));
|
||||
}
|
||||
|
||||
char* multistream_encoder::substream(size_t idx)
|
||||
{
|
||||
return memory + idx * sizeof(encoder);
|
||||
}
|
||||
|
||||
void multistream_encoder::set_params(uint8_t _channels, uint8_t _streams, uint8_t _coupled)
|
||||
{
|
||||
channels = _channels;
|
||||
streams = _streams;
|
||||
coupled = _coupled;
|
||||
offset = _streams * sizeof(encoder);
|
||||
opussize = opus_multistream_encoder_get_size(_streams, _coupled);
|
||||
}
|
||||
|
||||
decoder& multistream_decoder::operator[](size_t idx)
|
||||
{
|
||||
if(idx > (size_t)streams)
|
||||
throw opus::bad_argument();
|
||||
return *reinterpret_cast<decoder*>(substream(idx));
|
||||
}
|
||||
|
||||
size_t multistream_decoder::size(unsigned streams, unsigned coupled_streams)
|
||||
{
|
||||
return streams * sizeof(decoder) + opus_multistream_decoder_get_size(streams,
|
||||
coupled_streams);
|
||||
}
|
||||
|
||||
multistream_decoder::multistream_decoder(samplerate rate, unsigned _channels, unsigned _streams,
|
||||
unsigned coupled_streams, const unsigned char* mapping, char* _memory)
|
||||
{
|
||||
user = (memory != NULL);
|
||||
memory = _memory ? alignptr(_memory, alignof(decoder)) : new char[size(streams, coupled_streams)];
|
||||
set_params(_channels, _streams, coupled_streams);
|
||||
try {
|
||||
throwex(opus_multistream_decoder_init(MD(*this), rate, channels, streams, coupled_streams, mapping));
|
||||
} catch(...) {
|
||||
if(!user)
|
||||
delete[] memory;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
multistream_decoder::multistream_decoder(const multistream_decoder& e)
|
||||
{
|
||||
init_copy(e, NULL);
|
||||
}
|
||||
|
||||
multistream_decoder::multistream_decoder(const multistream_decoder& e, char* memory)
|
||||
{
|
||||
init_copy(e, memory);
|
||||
}
|
||||
|
||||
multistream_decoder::~multistream_decoder()
|
||||
{
|
||||
if(!user)
|
||||
delete memory;
|
||||
}
|
||||
|
||||
multistream_decoder& multistream_decoder::operator=(const multistream_decoder& d)
|
||||
{
|
||||
if(this == &d)
|
||||
return *this;
|
||||
if(streams != d.streams || coupled != d.coupled)
|
||||
throw std::runtime_error("Stream mismatch in assignment");
|
||||
memcpy(MD(*this), d.memory + d.offset, opussize);
|
||||
channels = d.channels;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void multistream_decoder::init_copy(const multistream_decoder& e, char* _memory)
|
||||
{
|
||||
user = (_memory != NULL);
|
||||
set_params(e.channels, e.streams, e.coupled);
|
||||
memory = _memory ? alignptr(_memory, alignof(decoder)) : new char[e.size()];
|
||||
memcpy(MD(*this), e.memory + e.offset, opussize);
|
||||
for(int32_t i = 0; i < (size_t)streams; i++) {
|
||||
OpusDecoder* e;
|
||||
opus_multistream_decoder_ctl(MD(*this), OPUS_MULTISTREAM_GET_DECODER_STATE(i, &e));
|
||||
new(substream(i)) decoder(e, i < coupled);
|
||||
}
|
||||
}
|
||||
|
||||
size_t multistream_decoder::decode(const unsigned char* in, uint32_t insize, int16_t* out, uint32_t maxframes,
|
||||
bool decode_fec)
|
||||
{
|
||||
return throwex(opus_multistream_decode(MD(*this), in, insize, out, maxframes, decode_fec));
|
||||
}
|
||||
|
||||
size_t multistream_decoder::decode(const unsigned char* in, uint32_t insize, float* out, uint32_t maxframes,
|
||||
bool decode_fec)
|
||||
{
|
||||
return throwex(opus_multistream_decode_float(MD(*this), in, insize, out, maxframes, decode_fec));
|
||||
}
|
||||
|
||||
void multistream_decoder::set_params(uint8_t _channels, uint8_t _streams, uint8_t _coupled)
|
||||
{
|
||||
channels = _channels;
|
||||
streams = _streams;
|
||||
coupled = _coupled;
|
||||
offset = _streams * sizeof(encoder);
|
||||
opussize = opus_multistream_decoder_get_size(_streams, _coupled);
|
||||
}
|
||||
|
||||
char* multistream_decoder::substream(size_t idx)
|
||||
{
|
||||
return memory + idx * sizeof(encoder);
|
||||
}
|
||||
|
||||
uint32_t packet_get_nb_frames(const unsigned char* packet, size_t len)
|
||||
{
|
||||
return throwex(opus_packet_get_nb_frames(packet, len));
|
||||
|
|
Loading…
Add table
Reference in a new issue