- fixes from pvqa_pcap
This commit is contained in:
parent
bf2d513080
commit
4ba1ea7fa2
|
|
@ -46,13 +46,17 @@
|
||||||
|
|
||||||
#define MT_SAMPLERATE AUDIO_SAMPLERATE
|
#define MT_SAMPLERATE AUDIO_SAMPLERATE
|
||||||
|
|
||||||
#define MT_MAXAUDIOFRAME 1440
|
#define MT_MAXAUDIOFRAME 1440
|
||||||
#define MT_MAXRTPPACKET 1500
|
#define MT_MAXRTPPACKET 1500
|
||||||
#define MT_DTMF_END_PACKETS 3
|
#define MT_DTMF_END_PACKETS 3
|
||||||
|
|
||||||
#define RTP_BUFFER_HIGH 480
|
#define RTP_BUFFER_HIGH 0
|
||||||
#define RTP_BUFFER_LOW 10
|
#define RTP_BUFFER_LOW 0
|
||||||
#define RTP_BUFFER_PREBUFFER 320
|
#define RTP_BUFFER_PREBUFFER 0
|
||||||
|
|
||||||
|
// #define RTP_BUFFER_HIGH 160
|
||||||
|
// #define RTP_BUFFER_LOW 10
|
||||||
|
// #define RTP_BUFFER_PREBUFFER 160
|
||||||
#define RTP_DECODED_CAPACITY 2048
|
#define RTP_DECODED_CAPACITY 2048
|
||||||
|
|
||||||
#define DEFAULT_SUBSCRIPTION_TIME 1200
|
#define DEFAULT_SUBSCRIPTION_TIME 1200
|
||||||
|
|
|
||||||
|
|
@ -543,6 +543,7 @@ PCodec AmrWbCodec::CodecFactory::create()
|
||||||
return PCodec(new AmrWbCodec(mConfig));
|
return PCodec(new AmrWbCodec(mConfig));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AmrWbStatistics MT::GAmrWbStatistics;
|
||||||
|
|
||||||
AmrWbCodec::AmrWbCodec(const AmrCodecConfig& config)
|
AmrWbCodec::AmrWbCodec(const AmrCodecConfig& config)
|
||||||
:mEncoderCtx(nullptr), mDecoderCtx(nullptr), mConfig(config),
|
:mEncoderCtx(nullptr), mDecoderCtx(nullptr), mConfig(config),
|
||||||
|
|
@ -672,6 +673,7 @@ int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outp
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
{
|
{
|
||||||
|
GAmrWbStatistics.mNonParsed++;
|
||||||
ICELogDebug(<< "Failed to decode AMR payload");
|
ICELogDebug(<< "Failed to decode AMR payload");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -680,8 +682,10 @@ int AmrWbCodec::decode(const void* input, int inputBytes, void* output, int outp
|
||||||
|
|
||||||
// Check if packet is corrupted
|
// Check if packet is corrupted
|
||||||
if (ap.mDiscardPacket)
|
if (ap.mDiscardPacket)
|
||||||
|
{
|
||||||
|
GAmrWbStatistics.mDiscarded++;
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
// Check for output buffer capacity
|
// Check for output buffer capacity
|
||||||
if (outputCapacity < (int)ap.mFrames.size() * pcmLength())
|
if (outputCapacity < (int)ap.mFrames.size() * pcmLength())
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -14,16 +14,16 @@
|
||||||
|
|
||||||
namespace MT
|
namespace MT
|
||||||
{
|
{
|
||||||
struct AmrCodecConfig
|
struct AmrCodecConfig
|
||||||
{
|
{
|
||||||
bool mIuUP;
|
bool mIuUP;
|
||||||
bool mOctetAligned;
|
bool mOctetAligned;
|
||||||
int mPayloadType;
|
int mPayloadType;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AmrNbCodec : public Codec
|
class AmrNbCodec : public Codec
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void* mEncoderCtx;
|
void* mEncoderCtx;
|
||||||
void* mDecoderCtx;
|
void* mDecoderCtx;
|
||||||
AmrCodecConfig mConfig;
|
AmrCodecConfig mConfig;
|
||||||
|
|
@ -31,25 +31,25 @@ namespace MT
|
||||||
int mSwitchCounter;
|
int mSwitchCounter;
|
||||||
int mPreviousPacketLength;
|
int mPreviousPacketLength;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class CodecFactory: public Factory
|
class CodecFactory: public Factory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CodecFactory(const AmrCodecConfig& config);
|
CodecFactory(const AmrCodecConfig& config);
|
||||||
|
|
||||||
const char* name() override;
|
const char* name() override;
|
||||||
int samplerate() override;
|
int samplerate() override;
|
||||||
int payloadType() override;
|
int payloadType() override;
|
||||||
|
|
||||||
#ifdef USE_RESIP_INTEGRATION
|
#ifdef USE_RESIP_INTEGRATION
|
||||||
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||||
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||||
void create(CodecMap& codecs) override;
|
void create(CodecMap& codecs) override;
|
||||||
#endif
|
#endif
|
||||||
PCodec create() override;
|
PCodec create() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AmrCodecConfig mConfig;
|
AmrCodecConfig mConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
AmrNbCodec(const AmrCodecConfig& config);
|
AmrNbCodec(const AmrCodecConfig& config);
|
||||||
|
|
@ -64,11 +64,18 @@ namespace MT
|
||||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||||
int plc(int lostFrames, void* output, int outputCapacity) override;
|
int plc(int lostFrames, void* output, int outputCapacity) override;
|
||||||
int getSwitchCounter() const;
|
int getSwitchCounter() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AmrWbCodec : public Codec
|
struct AmrWbStatistics
|
||||||
{
|
{
|
||||||
protected:
|
int mDiscarded = 0;
|
||||||
|
int mNonParsed = 0;
|
||||||
|
};
|
||||||
|
extern AmrWbStatistics GAmrWbStatistics;
|
||||||
|
|
||||||
|
class AmrWbCodec : public Codec
|
||||||
|
{
|
||||||
|
protected:
|
||||||
void* mEncoderCtx;
|
void* mEncoderCtx;
|
||||||
void* mDecoderCtx;
|
void* mDecoderCtx;
|
||||||
AmrCodecConfig mConfig;
|
AmrCodecConfig mConfig;
|
||||||
|
|
@ -76,25 +83,25 @@ namespace MT
|
||||||
int mSwitchCounter;
|
int mSwitchCounter;
|
||||||
int mPreviousPacketLength;
|
int mPreviousPacketLength;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class CodecFactory: public Factory
|
class CodecFactory: public Factory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CodecFactory(const AmrCodecConfig& config);
|
CodecFactory(const AmrCodecConfig& config);
|
||||||
|
|
||||||
const char* name() override;
|
const char* name() override;
|
||||||
int samplerate() override;
|
int samplerate() override;
|
||||||
int payloadType() override;
|
int payloadType() override;
|
||||||
|
|
||||||
#ifdef USE_RESIP_INTEGRATION
|
#ifdef USE_RESIP_INTEGRATION
|
||||||
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||||
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||||
void create(CodecMap& codecs) override;
|
void create(CodecMap& codecs) override;
|
||||||
#endif
|
#endif
|
||||||
PCodec create() override;
|
PCodec create() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AmrCodecConfig mConfig;
|
AmrCodecConfig mConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
AmrWbCodec(const AmrCodecConfig& config);
|
AmrWbCodec(const AmrCodecConfig& config);
|
||||||
|
|
@ -109,35 +116,35 @@ namespace MT
|
||||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||||
int plc(int lostFrames, void* output, int outputCapacity) override;
|
int plc(int lostFrames, void* output, int outputCapacity) override;
|
||||||
int getSwitchCounter() const;
|
int getSwitchCounter() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GsmEfrCodec : public Codec
|
class GsmEfrCodec : public Codec
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
void* mEncoderCtx;
|
void* mEncoderCtx;
|
||||||
void* mDecoderCtx;
|
void* mDecoderCtx;
|
||||||
bool mIuUP;
|
bool mIuUP;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class GsmEfrFactory: public Factory
|
class GsmEfrFactory: public Factory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GsmEfrFactory(bool iuup, int ptype);
|
GsmEfrFactory(bool iuup, int ptype);
|
||||||
|
|
||||||
const char* name() override;
|
const char* name() override;
|
||||||
int samplerate() override;
|
int samplerate() override;
|
||||||
int payloadType() override;
|
int payloadType() override;
|
||||||
|
|
||||||
#ifdef USE_RESIP_INTEGRATION
|
#ifdef USE_RESIP_INTEGRATION
|
||||||
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
void updateSdp(resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||||
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
int processSdp(const resip::SdpContents::Session::Medium::CodecContainer& codecs, SdpDirection direction) override;
|
||||||
void create(CodecMap& codecs) override;
|
void create(CodecMap& codecs) override;
|
||||||
#endif
|
#endif
|
||||||
PCodec create() override;
|
PCodec create() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool mIuUP;
|
bool mIuUP;
|
||||||
int mPayloadType;
|
int mPayloadType;
|
||||||
};
|
};
|
||||||
|
|
||||||
GsmEfrCodec(bool iuup = false);
|
GsmEfrCodec(bool iuup = false);
|
||||||
|
|
@ -151,7 +158,7 @@ namespace MT
|
||||||
int encode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
int encode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||||
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
int decode(const void* input, int inputBytes, void* output, int outputCapacity) override;
|
||||||
int plc(int lostFrames, void* output, int outputCapacity) override;
|
int plc(int lostFrames, void* output, int outputCapacity) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of MT namespace
|
} // End of MT namespace
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ RtpBuffer::FetchResult RtpBuffer::fetch(ResultList& rl)
|
||||||
// See if there is enough information in buffer
|
// See if there is enough information in buffer
|
||||||
int total = findTimelength();
|
int total = findTimelength();
|
||||||
|
|
||||||
while (total > mHigh && mPacketList.size())
|
while (total > mHigh && mPacketList.size() && 0 != mHigh)
|
||||||
{
|
{
|
||||||
ICELogMedia( << "Dropping RTP packets from jitter buffer");
|
ICELogMedia( << "Dropping RTP packets from jitter buffer");
|
||||||
total -= mPacketList.front()->timelength();
|
total -= mPacketList.front()->timelength();
|
||||||
|
|
@ -356,11 +356,17 @@ void AudioReceiver::setCodecSettings(const CodecList::Settings& codecSettings)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mCodecSettings = codecSettings;
|
mCodecSettings = codecSettings;
|
||||||
mCodecMap.clear();
|
mCodecList.setSettings(mCodecSettings); // This builds factory list with proper payload types according to payload types in settings
|
||||||
mCodecList.setSettings(mCodecSettings);
|
|
||||||
|
// Rebuild codec map from factory list
|
||||||
mCodecList.fillCodecMap(mCodecMap);
|
mCodecList.fillCodecMap(mCodecMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CodecList::Settings& AudioReceiver::getCodecSettings()
|
||||||
|
{
|
||||||
|
return mCodecSettings;
|
||||||
|
}
|
||||||
|
|
||||||
size_t decode_packet(Codec& codec, RTPPacket& p, void* output_buffer, size_t output_capacity)
|
size_t decode_packet(Codec& codec, RTPPacket& p, void* output_buffer, size_t output_capacity)
|
||||||
{
|
{
|
||||||
// How much data was produced
|
// How much data was produced
|
||||||
|
|
@ -399,12 +405,15 @@ size_t decode_packet(Codec& codec, RTPPacket& p, void* output_buffer, size_t out
|
||||||
|
|
||||||
bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec)
|
bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec)
|
||||||
{
|
{
|
||||||
|
// Estimate time length
|
||||||
|
int time_length = 0, payloadLength = p->GetPayloadLength(), ptype = p->GetPayloadType();
|
||||||
|
|
||||||
// ICELogInfo(<< "Adding packet No " << p->GetSequenceNumber());
|
// ICELogInfo(<< "Adding packet No " << p->GetSequenceNumber());
|
||||||
// Increase codec counter
|
// Increase codec counter
|
||||||
mStat.mCodecCount[p->GetPayloadType()]++;
|
mStat.mCodecCount[ptype]++;
|
||||||
|
|
||||||
// Check if codec can be handled
|
// Check if codec can be handled
|
||||||
CodecMap::iterator codecIter = mCodecMap.find(p->GetPayloadType());
|
CodecMap::iterator codecIter = mCodecMap.find(ptype);
|
||||||
if (codecIter == mCodecMap.end())
|
if (codecIter == mCodecMap.end())
|
||||||
{
|
{
|
||||||
ICELogMedia(<< "Cannot find codec in available codecs");
|
ICELogMedia(<< "Cannot find codec in available codecs");
|
||||||
|
|
@ -427,8 +436,6 @@ bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** co
|
||||||
if (mStat.mCodecName.empty())
|
if (mStat.mCodecName.empty())
|
||||||
mStat.mCodecName = codecIter->second->name();
|
mStat.mCodecName = codecIter->second->name();
|
||||||
|
|
||||||
// Estimate time length
|
|
||||||
int time_length = 0, payloadLength = p->GetPayloadLength(), ptype = p->GetPayloadType();
|
|
||||||
|
|
||||||
if (!codecIter->second->rtpLength())
|
if (!codecIter->second->rtpLength())
|
||||||
time_length = codecIter->second->frameTime();
|
time_length = codecIter->second->frameTime();
|
||||||
|
|
@ -462,8 +469,11 @@ bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** co
|
||||||
{
|
{
|
||||||
// Move data to packet buffer
|
// Move data to packet buffer
|
||||||
size_t available = decode_packet(**codec, *p, mDecodedFrame, sizeof mDecodedFrame);
|
size_t available = decode_packet(**codec, *p, mDecodedFrame, sizeof mDecodedFrame);
|
||||||
packet->pcm().resize(available / 2);
|
if (available > 0)
|
||||||
memcpy(packet->pcm().data(), mDecodedFrame, available / 2);
|
{
|
||||||
|
packet->pcm().resize(available / 2);
|
||||||
|
memcpy(packet->pcm().data(), mDecodedFrame, available / 2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@ namespace MT
|
||||||
|
|
||||||
// Update codec settings
|
// Update codec settings
|
||||||
void setCodecSettings(const CodecList::Settings& codecSettings);
|
void setCodecSettings(const CodecList::Settings& codecSettings);
|
||||||
|
CodecList::Settings& getCodecSettings();
|
||||||
// Returns false when packet is rejected as illegal. codec parameter will show codec which will be used for decoding.
|
// Returns false when packet is rejected as illegal. codec parameter will show codec which will be used for decoding.
|
||||||
// Lifetime of pointer to codec is limited by lifetime of AudioReceiver (it is container).
|
// Lifetime of pointer to codec is limited by lifetime of AudioReceiver (it is container).
|
||||||
bool add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec = nullptr);
|
bool add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec = nullptr);
|
||||||
|
|
|
||||||
|
|
@ -25,33 +25,95 @@ using namespace MT;
|
||||||
|
|
||||||
using strx = strx;
|
using strx = strx;
|
||||||
|
|
||||||
// ---------------- EvsSpec ---------------
|
|
||||||
|
bool CodecList::Settings::contains(int ptype) const
|
||||||
|
{
|
||||||
|
if (ptype >= 0 && ptype < 96)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mAmrNbOctetPayloadType.contains(ptype))
|
||||||
|
return true;
|
||||||
|
if (mAmrNbPayloadType.contains(ptype))
|
||||||
|
return true;
|
||||||
|
if (mAmrWbOctetPayloadType.contains(ptype))
|
||||||
|
return true;
|
||||||
|
if (mAmrWbPayloadType.contains(ptype))
|
||||||
|
return true;
|
||||||
|
for (const auto& s: mOpusSpec)
|
||||||
|
if (s.mPayloadType == ptype)
|
||||||
|
return true;
|
||||||
|
for (const auto& s: mEvsSpec)
|
||||||
|
if (s.mPayloadType == ptype)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mIsac16KPayloadType == ptype || mIsac32KPayloadType == ptype)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mIlbc20PayloadType == ptype || mIlbc30PayloadType == ptype)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (mGsmEfrPayloadType == ptype || mGsmFrPayloadType == ptype || mGsmHrPayloadType == ptype)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string CodecList::Settings::toString() const
|
std::string CodecList::Settings::toString() const
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "wrap IuUP: " << mWrapIuUP << std::endl
|
// oss << "wrap IuUP: " << mWrapIuUP << std::endl
|
||||||
<< "skip decode: " << mSkipDecode << std::endl;
|
// << "skip decode: " << mSkipDecode << std::endl;
|
||||||
for (int ptype: mAmrWbPayloadType)
|
|
||||||
oss << "AMR WB ptype: " << ptype << std::endl;
|
|
||||||
for (int ptype: mAmrWbOctetPayloadType)
|
|
||||||
oss << "AMR WB octet-aligned ptype: " << ptype << std::endl;
|
|
||||||
for (int ptype: mAmrNbPayloadType)
|
|
||||||
oss << "AMR NB ptype: " << ptype << std::endl;
|
|
||||||
for (int ptype: mAmrNbOctetPayloadType)
|
|
||||||
oss << "AMR NB octet-aligned ptype:" << ptype << std::endl;
|
|
||||||
|
|
||||||
oss << "ISAC 16Khz ptype: " << mIsac16KPayloadType << std::endl
|
if (!mAmrWbPayloadType.empty())
|
||||||
<< "ISAC 32Khz ptype: " << mIsac32KPayloadType << std::endl
|
{
|
||||||
<< "iLBC 20ms ptype: " << mIlbc20PayloadType << std::endl
|
oss << "AMR WB ptype: ";
|
||||||
<< "iLBC 30ms ptype: " << mIlbc30PayloadType << std::endl
|
for (int ptype: mAmrWbPayloadType)
|
||||||
<< "GSM FR ptype: " << mGsmFrPayloadType << ", GSM FR plength: " << mGsmFrPayloadLength << std::endl
|
oss << ptype << " ";
|
||||||
<< "GSM HR ptype: " << mGsmHrPayloadType << std::endl
|
}
|
||||||
<< "GSM EFR ptype: " << mGsmEfrPayloadType << std::endl;
|
if (!mAmrWbOctetPayloadType.empty())
|
||||||
|
{
|
||||||
|
oss << "AMR WB octet ptype: ";
|
||||||
|
for (int ptype: mAmrWbOctetPayloadType)
|
||||||
|
oss << ptype << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mAmrNbPayloadType.empty())
|
||||||
|
{
|
||||||
|
oss << "AMR ptype: ";
|
||||||
|
for (int ptype: mAmrNbPayloadType)
|
||||||
|
oss << ptype << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mAmrNbOctetPayloadType.empty())
|
||||||
|
{
|
||||||
|
oss << "AMR octet ptype: ";
|
||||||
|
for (int ptype: mAmrNbOctetPayloadType)
|
||||||
|
oss << ptype << " ";
|
||||||
|
}
|
||||||
|
if (mIsac16KPayloadType != -1)
|
||||||
|
oss << "ISAC 16Khz ptype: " << mIsac16KPayloadType << " ";
|
||||||
|
|
||||||
|
if (mIsac32KPayloadType != -1)
|
||||||
|
oss << "ISAC 32Khz ptype: " << mIsac32KPayloadType << " ";
|
||||||
|
|
||||||
|
if (mIlbc20PayloadType != -1)
|
||||||
|
oss << "iLBC 20ms ptype: " << mIlbc20PayloadType << " ";
|
||||||
|
|
||||||
|
if (mIlbc30PayloadType != -1)
|
||||||
|
oss << "iLBC 30ms ptype: " << mIlbc30PayloadType << " ";
|
||||||
|
|
||||||
|
if (mGsmFrPayloadType != -1)
|
||||||
|
oss << "GSM FR ptype: " << mGsmFrPayloadType << ", GSM FR plength: " << mGsmFrPayloadLength << " ";
|
||||||
|
|
||||||
|
if (mGsmHrPayloadType != -1)
|
||||||
|
oss << "GSM HR ptype: " << mGsmHrPayloadType << " ";
|
||||||
|
|
||||||
|
if (mGsmEfrPayloadType != -1)
|
||||||
|
oss << "GSM EFR ptype: " << mGsmEfrPayloadType << " ";
|
||||||
|
|
||||||
for (auto& spec: mEvsSpec)
|
for (auto& spec: mEvsSpec)
|
||||||
{
|
{
|
||||||
oss << "EVS ptype: " << spec.mPayloadType << ", bw: " << spec.mBandwidth << ", enc: " << (spec.mEncodingType == EvsSpec::Encoding_MIME ? "mime" : "g192") << std::endl;
|
oss << "EVS ptype: " << spec.mPayloadType << ", bw: " << spec.mBandwidth << ", enc: " << (spec.mEncodingType == EvsSpec::Encoding_MIME ? "mime" : "g192") << " ";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& spec: mOpusSpec)
|
for (auto& spec: mOpusSpec)
|
||||||
|
|
@ -100,24 +162,24 @@ CodecList::Settings::EvsSpec CodecList::Settings::EvsSpec::parse(const std::stri
|
||||||
if (encoding_type == "mime")
|
if (encoding_type == "mime")
|
||||||
result.mEncodingType = Encoding_MIME;
|
result.mEncodingType = Encoding_MIME;
|
||||||
else
|
else
|
||||||
if (encoding_type == "g192")
|
if (encoding_type == "g192")
|
||||||
result.mEncodingType = Encoding_G192;
|
result.mEncodingType = Encoding_G192;
|
||||||
else
|
else
|
||||||
throw std::logic_error("Bad EVS codec encoding type");
|
throw std::logic_error("Bad EVS codec encoding type");
|
||||||
|
|
||||||
// Bandwidth
|
// Bandwidth
|
||||||
std::string& bandwidth = parts.back();
|
std::string& bandwidth = parts.back();
|
||||||
if (bandwidth == "nb" || bandwidth == "NB")
|
if (bandwidth == "nb" || bandwidth == "NB")
|
||||||
result.mBandwidth = Bandwidth_NB;
|
result.mBandwidth = Bandwidth_NB;
|
||||||
else
|
else
|
||||||
if (bandwidth == "wb" || bandwidth == "WB")
|
if (bandwidth == "wb" || bandwidth == "WB")
|
||||||
result.mBandwidth = Bandwidth_WB;
|
result.mBandwidth = Bandwidth_WB;
|
||||||
else
|
else
|
||||||
if (bandwidth == "swb" || bandwidth == "SWB")
|
if (bandwidth == "swb" || bandwidth == "SWB")
|
||||||
result.mBandwidth = Bandwidth_SWB;
|
result.mBandwidth = Bandwidth_SWB;
|
||||||
else
|
else
|
||||||
if (bandwidth == "fb" || bandwidth == "FB")
|
if (bandwidth == "fb" || bandwidth == "FB")
|
||||||
result.mBandwidth = Bandwidth_FB;
|
result.mBandwidth = Bandwidth_FB;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -145,6 +207,21 @@ CodecList::Settings::OpusSpec CodecList::Settings::OpusSpec::parse(const std::st
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_RESIP_INTEGRATION)
|
#if defined(USE_RESIP_INTEGRATION)
|
||||||
|
static int findOctetMode(const char* line)
|
||||||
|
{
|
||||||
|
const char* param_name = "octet-align=";
|
||||||
|
auto p = strstr(line, param_name);
|
||||||
|
if (!p)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
p += strlen(param_name);
|
||||||
|
char int_buf[8] = {0};
|
||||||
|
int int_buf_offset = 0;
|
||||||
|
while (*p && isdigit(*p) && int_buf_offset < sizeof(int_buf))
|
||||||
|
int_buf[int_buf_offset++] = *p++;
|
||||||
|
return atoi(int_buf);
|
||||||
|
}
|
||||||
|
|
||||||
CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>& codeclist)
|
CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>& codeclist)
|
||||||
{
|
{
|
||||||
CodecList::Settings r{DefaultSettings};
|
CodecList::Settings r{DefaultSettings};
|
||||||
|
|
@ -155,15 +232,44 @@ CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>&
|
||||||
int samplerate = c.getRate();
|
int samplerate = c.getRate();
|
||||||
int ptype = c.payloadType();
|
int ptype = c.payloadType();
|
||||||
|
|
||||||
|
auto enc_params = c.encodingParameters(); // This must channels number for Opus codec
|
||||||
|
auto params = c.parameters();
|
||||||
|
|
||||||
// Dynamic payload type codecs only - ISAC / iLBC / Speex / etc.
|
// Dynamic payload type codecs only - ISAC / iLBC / Speex / etc.
|
||||||
if (codec_name == "OPUS")
|
if (codec_name == "OPUS")
|
||||||
{
|
{
|
||||||
// Check the parameters
|
// Check the parameters
|
||||||
auto enc_params = c.encodingParameters(); // This must channels number for Opus codec
|
|
||||||
auto params = c.parameters();
|
|
||||||
int channels = strx::toInt(enc_params.c_str(), 1);
|
int channels = strx::toInt(enc_params.c_str(), 1);
|
||||||
r.mOpusSpec.push_back({ptype, samplerate, channels});
|
r.mOpusSpec.push_back({ptype, samplerate, channels});
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
if (codec_name == "AMR-WB")
|
||||||
|
{
|
||||||
|
int octet_mode = findOctetMode(params.c_str());
|
||||||
|
if (octet_mode != -1)
|
||||||
|
{
|
||||||
|
if (octet_mode == 0)
|
||||||
|
r.mAmrWbPayloadType.insert(ptype);
|
||||||
|
else
|
||||||
|
if (octet_mode == 1)
|
||||||
|
r.mAmrWbOctetPayloadType.insert(ptype);
|
||||||
|
}
|
||||||
|
// std::cout << "AMR-WB parameters: " << params.c_str() << ", found octet-mode: " << octet_mode << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (codec_name == "AMR")
|
||||||
|
{
|
||||||
|
int octet_mode = findOctetMode(params.c_str());
|
||||||
|
if (octet_mode != -1)
|
||||||
|
{
|
||||||
|
if (octet_mode == 0)
|
||||||
|
r.mAmrWbPayloadType.insert(ptype);
|
||||||
|
else
|
||||||
|
if (octet_mode == 1)
|
||||||
|
r.mAmrWbOctetPayloadType.insert(ptype);
|
||||||
|
}
|
||||||
|
// std::cout << "AMR parameters: " << params.c_str() << ", found octet-mode: " << octet_mode << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
@ -173,7 +279,7 @@ CodecList::Settings CodecList::Settings::parseSdp(const std::list<resip::Codec>&
|
||||||
bool CodecList::Settings::operator == (const Settings& rhs) const
|
bool CodecList::Settings::operator == (const Settings& rhs) const
|
||||||
{
|
{
|
||||||
if (std::tie(mWrapIuUP, mSkipDecode, mIsac16KPayloadType, mIsac32KPayloadType, mIlbc20PayloadType, mIlbc30PayloadType, mGsmFrPayloadType, mGsmFrPayloadLength, mGsmEfrPayloadType, mGsmHrPayloadType) !=
|
if (std::tie(mWrapIuUP, mSkipDecode, mIsac16KPayloadType, mIsac32KPayloadType, mIlbc20PayloadType, mIlbc30PayloadType, mGsmFrPayloadType, mGsmFrPayloadLength, mGsmEfrPayloadType, mGsmHrPayloadType) !=
|
||||||
std::tie(rhs.mWrapIuUP, rhs.mSkipDecode, rhs.mIsac16KPayloadType, rhs.mIsac32KPayloadType, rhs.mIlbc20PayloadType, rhs.mIlbc30PayloadType, rhs.mGsmFrPayloadType, rhs.mGsmFrPayloadLength, rhs.mGsmEfrPayloadType, rhs.mGsmHrPayloadType))
|
std::tie(rhs.mWrapIuUP, rhs.mSkipDecode, rhs.mIsac16KPayloadType, rhs.mIsac32KPayloadType, rhs.mIlbc20PayloadType, rhs.mIlbc30PayloadType, rhs.mGsmFrPayloadType, rhs.mGsmFrPayloadLength, rhs.mGsmEfrPayloadType, rhs.mGsmHrPayloadType))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mAmrNbOctetPayloadType != rhs.mAmrNbOctetPayloadType)
|
if (mAmrNbOctetPayloadType != rhs.mAmrNbOctetPayloadType)
|
||||||
|
|
@ -211,108 +317,99 @@ bool CodecList::Settings::operator == (const Settings& rhs) const
|
||||||
CodecList::Settings CodecList::Settings::DefaultSettings;
|
CodecList::Settings CodecList::Settings::DefaultSettings;
|
||||||
|
|
||||||
CodecList::CodecList(const Settings& settings)
|
CodecList::CodecList(const Settings& settings)
|
||||||
:mSettings(settings)
|
:mSettings(settings)
|
||||||
{
|
{
|
||||||
init(mSettings);
|
init(mSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodecList::init(const Settings& settings)
|
void CodecList::init(const Settings& settings)
|
||||||
{
|
{
|
||||||
for (auto f: mFactoryList)
|
mFactoryList.clear();
|
||||||
delete f;
|
mSettings = settings;
|
||||||
mFactoryList.clear();
|
|
||||||
|
|
||||||
#if defined(USE_OPUS_CODEC)
|
#if defined(USE_OPUS_CODEC)
|
||||||
if (settings.mOpusSpec.empty())
|
|
||||||
{
|
|
||||||
mFactoryList.push_back(new OpusCodec::OpusFactory(48000, 2, MT_OPUS_CODEC_PT));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (auto spec: settings.mOpusSpec)
|
for (auto spec: settings.mOpusSpec)
|
||||||
{
|
{
|
||||||
mFactoryList.push_back(new OpusCodec::OpusFactory(spec.mRate, spec.mChannels, spec.mPayloadType));
|
mFactoryList.push_back(std::make_shared<OpusCodec::OpusFactory>(spec.mRate, spec.mChannels, spec.mPayloadType));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(TARGET_ANDROID) && !defined(TARGET_OPENWRT) && !defined(TARGET_RPI)
|
#if !defined(TARGET_ANDROID) && !defined(TARGET_OPENWRT) && !defined(TARGET_RPI)
|
||||||
#if defined(USE_AMR_CODEC)
|
#if defined(USE_AMR_CODEC)
|
||||||
for (int pt: mSettings.mAmrWbPayloadType)
|
for (int pt: mSettings.mAmrWbPayloadType)
|
||||||
mFactoryList.push_back(new AmrWbCodec::CodecFactory({mSettings.mWrapIuUP, false, pt}));
|
mFactoryList.push_back(std::make_shared<AmrWbCodec::CodecFactory>(AmrCodecConfig{mSettings.mWrapIuUP, false, pt}));
|
||||||
for (int pt: mSettings.mAmrWbOctetPayloadType)
|
for (int pt: mSettings.mAmrWbOctetPayloadType)
|
||||||
mFactoryList.push_back(new AmrWbCodec::CodecFactory({mSettings.mWrapIuUP, true, pt}));
|
mFactoryList.push_back(std::make_shared<AmrWbCodec::CodecFactory>(AmrCodecConfig{mSettings.mWrapIuUP, true, pt}));
|
||||||
|
|
||||||
for (int pt: mSettings.mAmrNbPayloadType)
|
for (int pt: mSettings.mAmrNbPayloadType)
|
||||||
mFactoryList.push_back(new AmrNbCodec::CodecFactory({mSettings.mWrapIuUP, false, pt}));
|
mFactoryList.push_back(std::make_shared<AmrNbCodec::CodecFactory>(AmrCodecConfig{mSettings.mWrapIuUP, false, pt}));
|
||||||
for (int pt: mSettings.mAmrNbOctetPayloadType)
|
for (int pt: mSettings.mAmrNbOctetPayloadType)
|
||||||
mFactoryList.push_back(new AmrNbCodec::CodecFactory({mSettings.mWrapIuUP, true, pt}));
|
mFactoryList.push_back(std::make_shared<AmrNbCodec::CodecFactory>(AmrCodecConfig{mSettings.mWrapIuUP, true, pt}));
|
||||||
|
|
||||||
mFactoryList.push_back(new GsmEfrCodec::GsmEfrFactory(mSettings.mWrapIuUP, mSettings.mGsmEfrPayloadType));
|
if (mSettings.mGsmEfrPayloadType != -1)
|
||||||
|
mFactoryList.push_back(std::make_shared<GsmEfrCodec::GsmEfrFactory>(mSettings.mWrapIuUP, mSettings.mGsmEfrPayloadType));
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
// mFactoryList.push_back(new IsacCodec::IsacFactory16K(mSettings.mIsac16KPayloadType));
|
mFactoryList.push_back(std::make_shared<G711Codec::AlawFactory>());
|
||||||
// mFactoryList.push_back(new IlbcCodec::IlbcFactory(mSettings.mIlbc20PayloadType, mSettings.mIlbc30PayloadType));
|
mFactoryList.push_back(std::make_shared<G711Codec::UlawFactory>());
|
||||||
mFactoryList.push_back(new G711Codec::AlawFactory());
|
|
||||||
mFactoryList.push_back(new G711Codec::UlawFactory());
|
|
||||||
|
|
||||||
mFactoryList.push_back(new GsmCodec::GsmFactory(mSettings.mGsmFrPayloadLength == 32 ? GsmCodec::Type::Bytes_32 : GsmCodec::Type::Bytes_33, mSettings.mGsmFrPayloadType));
|
if (mSettings.mGsmFrPayloadType != -1)
|
||||||
mFactoryList.push_back(new G722Codec::G722Factory());
|
mFactoryList.push_back(std::make_shared<GsmCodec::GsmFactory>(mSettings.mGsmFrPayloadLength == 32 ? GsmCodec::Type::Bytes_32 : GsmCodec::Type::Bytes_33, mSettings.mGsmFrPayloadType));
|
||||||
mFactoryList.push_back(new G729Codec::G729Factory());
|
mFactoryList.push_back(std::make_shared<G722Codec::G722Factory>());
|
||||||
|
mFactoryList.push_back(std::make_shared<G729Codec::G729Factory>());
|
||||||
#ifndef TARGET_ANDROID
|
#ifndef TARGET_ANDROID
|
||||||
mFactoryList.push_back(new GsmHrCodec::GsmHrFactory(mSettings.mGsmHrPayloadType));
|
if (mSettings.mGsmHrPayloadType != -1)
|
||||||
|
mFactoryList.push_back(std::make_shared<GsmHrCodec::GsmHrFactory>(mSettings.mGsmHrPayloadType));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(TARGET_ANDROID) && defined(USE_EVS_CODEC)
|
#if !defined(TARGET_ANDROID) && defined(USE_EVS_CODEC)
|
||||||
for (auto& spec: settings.mEvsSpec)
|
for (auto& spec: settings.mEvsSpec)
|
||||||
{
|
{
|
||||||
EVSCodec::StreamParameters evs_params;
|
EVSCodec::StreamParameters evs_params;
|
||||||
evs_params.mime = spec.mEncodingType == Settings::EvsSpec::Encoding_MIME;
|
evs_params.mime = spec.mEncodingType == Settings::EvsSpec::Encoding_MIME;
|
||||||
evs_params.bw = (int)spec.mBandwidth;
|
evs_params.bw = (int)spec.mBandwidth;
|
||||||
evs_params.ptime = 20;
|
evs_params.ptime = 20;
|
||||||
evs_params.ptype = spec.mPayloadType;
|
evs_params.ptype = spec.mPayloadType;
|
||||||
|
|
||||||
mFactoryList.push_back(new EVSCodec::EVSFactory(evs_params));
|
mFactoryList.push_back(std::make_shared<EVSCodec::EVSFactory>(evs_params));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
CodecList::~CodecList()
|
CodecList::~CodecList()
|
||||||
{
|
{
|
||||||
for (auto f: mFactoryList)
|
mFactoryList.clear();
|
||||||
delete f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CodecList::count() const
|
int CodecList::count() const
|
||||||
{
|
{
|
||||||
return static_cast<int>(mFactoryList.size());
|
return static_cast<int>(mFactoryList.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Codec::Factory& CodecList::codecAt(int index) const
|
Codec::Factory& CodecList::codecAt(int index) const
|
||||||
{
|
{
|
||||||
return *mFactoryList[static_cast<size_t>(index)];
|
return *mFactoryList[static_cast<size_t>(index)];
|
||||||
}
|
}
|
||||||
|
|
||||||
int CodecList::findCodec(const std::string &name) const
|
int CodecList::findCodec(const std::string &name) const
|
||||||
{
|
{
|
||||||
for (int i=0; i<count(); i++)
|
for (int i=0; i<count(); i++)
|
||||||
{
|
{
|
||||||
if (codecAt(i).name() == name)
|
if (codecAt(i).name() == name)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodecList::fillCodecMap(CodecMap& cm)
|
void CodecList::fillCodecMap(CodecMap& cm)
|
||||||
{
|
{
|
||||||
cm.clear();
|
cm.clear();
|
||||||
for (auto& factory: mFactoryList)
|
for (auto& factory: mFactoryList)
|
||||||
{
|
{
|
||||||
// Create codec here. Although they are not needed right now - they can be needed to find codec's info.
|
// Create codec here. Although they are not needed right now - they can be needed to find codec's info.
|
||||||
PCodec c = factory->create();
|
PCodec c = factory->create();
|
||||||
cm.insert({factory->payloadType(), c});
|
cm.insert({factory->payloadType(), c});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CodecListPriority::CodecListPriority()
|
CodecListPriority::CodecListPriority()
|
||||||
|
|
@ -327,55 +424,55 @@ CodecListPriority::~CodecListPriority()
|
||||||
|
|
||||||
bool CodecListPriority::isNegativePriority(const CodecListPriority::Item& item)
|
bool CodecListPriority::isNegativePriority(const CodecListPriority::Item& item)
|
||||||
{
|
{
|
||||||
return item.mPriority < 0;
|
return item.mPriority < 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CodecListPriority::compare(const Item& item1, const Item& item2)
|
bool CodecListPriority::compare(const Item& item1, const Item& item2)
|
||||||
{
|
{
|
||||||
return item1.mPriority < item2.mPriority;
|
return item1.mPriority < item2.mPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodecListPriority::setupFrom(PVariantMap vmap)
|
void CodecListPriority::setupFrom(PVariantMap vmap)
|
||||||
{
|
{
|
||||||
CodecList::Settings settings;
|
CodecList::Settings settings;
|
||||||
CodecList cl(settings);
|
CodecList cl(settings);
|
||||||
//mPriorityList.resize(cl.count());
|
//mPriorityList.resize(cl.count());
|
||||||
bool emptyVmap = vmap ? vmap->empty() : true;
|
bool emptyVmap = vmap ? vmap->empty() : true;
|
||||||
|
|
||||||
if (emptyVmap)
|
if (emptyVmap)
|
||||||
{
|
|
||||||
for (int i=0; i<cl.count(); i++)
|
|
||||||
{
|
{
|
||||||
Item item;
|
for (int i=0; i<cl.count(); i++)
|
||||||
item.mCodecIndex = i;
|
{
|
||||||
item.mPriority = i;
|
Item item;
|
||||||
mPriorityList.push_back(item);
|
item.mCodecIndex = i;
|
||||||
|
item.mPriority = i;
|
||||||
|
mPriorityList.push_back(item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int i=0; i<cl.count(); i++)
|
|
||||||
{
|
{
|
||||||
Item item;
|
for (int i=0; i<cl.count(); i++)
|
||||||
item.mCodecIndex = i;
|
{
|
||||||
item.mPriority = vmap->exists(i) ? vmap->at(i).asInt() : 1000; // Non listed codecs will get lower priority
|
Item item;
|
||||||
mPriorityList.push_back(item);
|
item.mCodecIndex = i;
|
||||||
|
item.mPriority = vmap->exists(i) ? vmap->at(i).asInt() : 1000; // Non listed codecs will get lower priority
|
||||||
|
mPriorityList.push_back(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove -1 records
|
||||||
|
mPriorityList.erase(std::remove_if(mPriorityList.begin(), mPriorityList.end(), isNegativePriority), mPriorityList.end());
|
||||||
|
|
||||||
|
// Sort by priority
|
||||||
|
std::sort(mPriorityList.begin(), mPriorityList.end(), compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove -1 records
|
|
||||||
mPriorityList.erase(std::remove_if(mPriorityList.begin(), mPriorityList.end(), isNegativePriority), mPriorityList.end());
|
|
||||||
|
|
||||||
// Sort by priority
|
|
||||||
std::sort(mPriorityList.begin(), mPriorityList.end(), compare);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CodecListPriority::count(const CodecList & /*cl*/) const
|
int CodecListPriority::count(const CodecList & /*cl*/) const
|
||||||
{
|
{
|
||||||
return static_cast<int>(mPriorityList.size());
|
return static_cast<int>(mPriorityList.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Codec::Factory& CodecListPriority::codecAt(const CodecList& cl, int index) const
|
Codec::Factory& CodecListPriority::codecAt(const CodecList& cl, int index) const
|
||||||
{
|
{
|
||||||
return cl.codecAt(mPriorityList[static_cast<size_t>(index)].mCodecIndex);
|
return cl.codecAt(mPriorityList[static_cast<size_t>(index)].mCodecIndex);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ public:
|
||||||
int mIsac32KPayloadType = -1;
|
int mIsac32KPayloadType = -1;
|
||||||
int mIlbc20PayloadType = -1;
|
int mIlbc20PayloadType = -1;
|
||||||
int mIlbc30PayloadType = -1;
|
int mIlbc30PayloadType = -1;
|
||||||
int mGsmFrPayloadType = 3; // GSM is codec with fixed payload type. But sometimes it has to be overwritten.
|
int mGsmFrPayloadType = -1; // GSM is codec with fixed payload type. But sometimes it has to be overwritten.
|
||||||
int mGsmFrPayloadLength = 33; // Expected GSM payload length
|
int mGsmFrPayloadLength = 33; // Expected GSM payload length
|
||||||
int mGsmHrPayloadType = -1;
|
int mGsmHrPayloadType = -1;
|
||||||
int mGsmEfrPayloadType = -1;
|
int mGsmEfrPayloadType = -1;
|
||||||
|
|
@ -96,6 +96,9 @@ public:
|
||||||
};
|
};
|
||||||
std::vector<OpusSpec> mOpusSpec;
|
std::vector<OpusSpec> mOpusSpec;
|
||||||
|
|
||||||
|
// Payload type
|
||||||
|
bool contains(int ptype) const;
|
||||||
|
|
||||||
// Textual representation - used in logging
|
// Textual representation - used in logging
|
||||||
std::string toString() const;
|
std::string toString() const;
|
||||||
void clear();
|
void clear();
|
||||||
|
|
@ -110,7 +113,9 @@ public:
|
||||||
|
|
||||||
CodecList(const Settings& settings);
|
CodecList(const Settings& settings);
|
||||||
~CodecList();
|
~CodecList();
|
||||||
void setSettings(const Settings& settings) { init(settings); }
|
void setSettings(const Settings& settings) {
|
||||||
|
init(settings);
|
||||||
|
}
|
||||||
|
|
||||||
int count() const;
|
int count() const;
|
||||||
Codec::Factory& codecAt(int index) const;
|
Codec::Factory& codecAt(int index) const;
|
||||||
|
|
@ -119,7 +124,7 @@ public:
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef std::vector<Codec::Factory*> FactoryList;
|
typedef std::vector<std::shared_ptr<Codec::Factory>> FactoryList;
|
||||||
FactoryList mFactoryList;
|
FactoryList mFactoryList;
|
||||||
Settings mSettings;
|
Settings mSettings;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue