Fixed timestamps in AMR when transcoding from non-20ms packetization.
Added setting for initial AMR mode. git-svn-id: http://voip.null.ro/svn/yate@5278 acf43c95-373e-0410-b603-e72c3f656dc1
This commit is contained in:
parent
9fe101f4cd
commit
43c94fe9cd
|
@ -0,0 +1,10 @@
|
||||||
|
[general]
|
||||||
|
; Initial settings for each created codec
|
||||||
|
|
||||||
|
; mode: int: AMR mode to use by default
|
||||||
|
; Allowed values are 0-7 or the following keywords (not real numbers!)
|
||||||
|
; 4.75, 5.15, 5.90, 6.70, 7.40, 7.95, 10.2, 12.2
|
||||||
|
;mode=12.2
|
||||||
|
|
||||||
|
; discontinuous: bool: Use DTX (Discontinuous Transmission) frames
|
||||||
|
;discontinuous=no
|
|
@ -56,12 +56,19 @@ namespace { // anonymous
|
||||||
// Maximum number of frames we are willing to decode in a packet
|
// Maximum number of frames we are willing to decode in a packet
|
||||||
#define MAX_PKT_FRAMES 4
|
#define MAX_PKT_FRAMES 4
|
||||||
|
|
||||||
|
// Discontinuous Transmission (DTX)
|
||||||
|
static bool s_discontinuous = false;
|
||||||
|
|
||||||
|
// Default mode
|
||||||
|
static Mode s_mode = MR122;
|
||||||
|
|
||||||
|
|
||||||
class AmrPlugin : public Plugin, public TranslatorFactory
|
class AmrPlugin : public Plugin, public TranslatorFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AmrPlugin();
|
AmrPlugin();
|
||||||
~AmrPlugin();
|
~AmrPlugin();
|
||||||
virtual void initialize() {}
|
virtual void initialize();
|
||||||
virtual bool isBusy() const;
|
virtual bool isBusy() const;
|
||||||
virtual DataTranslator* create(const DataFormat& sFormat, const DataFormat& dFormat);
|
virtual DataTranslator* create(const DataFormat& sFormat, const DataFormat& dFormat);
|
||||||
virtual const TranslatorCaps* getCapabilities() const;
|
virtual const TranslatorCaps* getCapabilities() const;
|
||||||
|
@ -70,7 +77,7 @@ public:
|
||||||
class AmrTrans : public DataTranslator
|
class AmrTrans : public DataTranslator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AmrTrans(const char* sFormat, const char* dFormat, void* amrState, bool octetAlign = false);
|
AmrTrans(const char* sFormat, const char* dFormat, void* amrState, bool octetAlign, bool encoding);
|
||||||
virtual ~AmrTrans();
|
virtual ~AmrTrans();
|
||||||
virtual unsigned long Consume(const DataBlock& data, unsigned long tStamp, unsigned long flags);
|
virtual unsigned long Consume(const DataBlock& data, unsigned long tStamp, unsigned long flags);
|
||||||
inline bool valid() const
|
inline bool valid() const
|
||||||
|
@ -82,6 +89,7 @@ protected:
|
||||||
virtual bool pushData(unsigned long& tStamp) = 0;
|
virtual bool pushData(unsigned long& tStamp) = 0;
|
||||||
void* m_amrState;
|
void* m_amrState;
|
||||||
DataBlock m_data;
|
DataBlock m_data;
|
||||||
|
bool m_encoding;
|
||||||
bool m_showError;
|
bool m_showError;
|
||||||
bool m_octetAlign;
|
bool m_octetAlign;
|
||||||
Mode m_cmr;
|
Mode m_cmr;
|
||||||
|
@ -92,10 +100,11 @@ class AmrEncoder : public AmrTrans
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline AmrEncoder(const char* sFormat, const char* dFormat, bool octetAlign, bool discont = false)
|
inline AmrEncoder(const char* sFormat, const char* dFormat, bool octetAlign, bool discont = false)
|
||||||
: AmrTrans(sFormat,dFormat,::Encoder_Interface_init(discont ? 1 : 0),octetAlign),
|
: AmrTrans(sFormat,dFormat,::Encoder_Interface_init(discont ? 1 : 0),octetAlign,true),
|
||||||
m_mode(MR122)
|
m_mode(s_mode)
|
||||||
{ }
|
{ }
|
||||||
virtual ~AmrEncoder();
|
virtual ~AmrEncoder();
|
||||||
|
virtual bool control(NamedList& params);
|
||||||
protected:
|
protected:
|
||||||
virtual bool pushData(unsigned long& tStamp);
|
virtual bool pushData(unsigned long& tStamp);
|
||||||
Mode m_mode;
|
Mode m_mode;
|
||||||
|
@ -106,7 +115,7 @@ class AmrDecoder : public AmrTrans
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
inline AmrDecoder(const char* sFormat, const char* dFormat, bool octetAlign)
|
inline AmrDecoder(const char* sFormat, const char* dFormat, bool octetAlign)
|
||||||
: AmrTrans(sFormat,dFormat,::Decoder_Interface_init(),octetAlign)
|
: AmrTrans(sFormat,dFormat,::Decoder_Interface_init(),octetAlign,false)
|
||||||
{ }
|
{ }
|
||||||
virtual ~AmrDecoder();
|
virtual ~AmrDecoder();
|
||||||
protected:
|
protected:
|
||||||
|
@ -130,8 +139,18 @@ static int modeBits[16] = {
|
||||||
-1, -1, -1, -1, -1, -1, 0
|
-1, -1, -1, -1, -1, -1, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Discontinuous Transmission (DTX)
|
// Table for bitrate to mode conversion
|
||||||
bool s_discontinuous = false;
|
static const TokenDict s_modes[] = {
|
||||||
|
{ "4.75", MR475 },
|
||||||
|
{ "5.15", MR515 },
|
||||||
|
{ "5.90", MR59 },
|
||||||
|
{ "6.70", MR67 },
|
||||||
|
{ "7.40", MR74 },
|
||||||
|
{ "7.95", MR795 },
|
||||||
|
{ "10.2", MR102 },
|
||||||
|
{ "12.2", MR122 },
|
||||||
|
{ 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
// Helper function, gets a number of bits and advances pointer, return -1 for error
|
// Helper function, gets a number of bits and advances pointer, return -1 for error
|
||||||
static int getBits(unsigned const char*& ptr, int& len, int& bpos, unsigned char bits)
|
static int getBits(unsigned const char*& ptr, int& len, int& bpos, unsigned char bits)
|
||||||
|
@ -159,13 +178,13 @@ static int getBits(unsigned const char*& ptr, int& len, int& bpos, unsigned char
|
||||||
|
|
||||||
|
|
||||||
// Arbitrary type transcoder constructor
|
// Arbitrary type transcoder constructor
|
||||||
AmrTrans::AmrTrans(const char* sFormat, const char* dFormat, void* amrState, bool octetAlign)
|
AmrTrans::AmrTrans(const char* sFormat, const char* dFormat, void* amrState, bool octetAlign, bool encoding)
|
||||||
: DataTranslator(sFormat,dFormat),
|
: DataTranslator(sFormat,dFormat),
|
||||||
m_amrState(amrState), m_showError(true),
|
m_amrState(amrState), m_encoding(encoding), m_showError(true),
|
||||||
m_octetAlign(octetAlign), m_cmr(MR122)
|
m_octetAlign(octetAlign), m_cmr(s_mode)
|
||||||
{
|
{
|
||||||
Debug(MODNAME,DebugAll,"AmrTrans::AmrTrans('%s','%s',%p,%s) [%p]",
|
Debug(MODNAME,DebugAll,"AmrTrans::AmrTrans('%s','%s',%p,%s,%s) [%p]",
|
||||||
sFormat,dFormat,amrState,String::boolText(octetAlign),this);
|
sFormat,dFormat,amrState,String::boolText(octetAlign),String::boolText(encoding),this);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,9 +204,9 @@ unsigned long AmrTrans::Consume(const DataBlock& data, unsigned long tStamp, uns
|
||||||
if (data.null() && (flags & DataSilent))
|
if (data.null() && (flags & DataSilent))
|
||||||
return getTransSource()->Forward(data,tStamp,flags);
|
return getTransSource()->Forward(data,tStamp,flags);
|
||||||
ref();
|
ref();
|
||||||
|
if (m_encoding && (tStamp != invalidStamp()) && !m_data.null())
|
||||||
|
tStamp -= (m_data.length() / 2);
|
||||||
m_data += data;
|
m_data += data;
|
||||||
if (!tStamp)
|
|
||||||
tStamp = timeStamp() + SAMPLES_FRAME;
|
|
||||||
while (pushData(tStamp))
|
while (pushData(tStamp))
|
||||||
;
|
;
|
||||||
deref();
|
deref();
|
||||||
|
@ -261,6 +280,23 @@ bool AmrEncoder::pushData(unsigned long& tStamp)
|
||||||
return (0 != m_data.length());
|
return (0 != m_data.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Execute control operations
|
||||||
|
bool AmrEncoder::control(NamedList& params)
|
||||||
|
{
|
||||||
|
bool ok = false;
|
||||||
|
int mode = params[YSTRING("mode")].toInteger(s_modes,-1);
|
||||||
|
if (mode >= MR475 && mode <= MR122) {
|
||||||
|
m_mode = (Mode)mode;
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
mode = params[YSTRING("cmr")].toInteger(s_modes,-1);
|
||||||
|
if (mode >= MR475 && mode <= MR122) {
|
||||||
|
m_cmr = (Mode)mode;
|
||||||
|
ok = true;
|
||||||
|
}
|
||||||
|
return AmrTrans::control(params) || ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Decoder cleanup
|
// Decoder cleanup
|
||||||
AmrDecoder::~AmrDecoder()
|
AmrDecoder::~AmrDecoder()
|
||||||
|
@ -405,6 +441,16 @@ const TranslatorCaps* AmrPlugin::getCapabilities() const
|
||||||
return caps;
|
return caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AmrPlugin::initialize()
|
||||||
|
{
|
||||||
|
Output("Initializing module AMR-NB");
|
||||||
|
Configuration cfg(Engine::configFile("amrnbcodec"));
|
||||||
|
int mode = cfg.getIntValue("general","mode",s_modes,MR122);
|
||||||
|
if (mode >= MR475 && mode <= MR122)
|
||||||
|
s_mode = (Mode)mode;
|
||||||
|
s_discontinuous = cfg.getBoolValue("general","discontinuous",false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
INIT_PLUGIN(AmrPlugin);
|
INIT_PLUGIN(AmrPlugin);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue