- better internal statistics + memory performance optimization
This commit is contained in:
@@ -18,9 +18,7 @@ namespace Audio
|
|||||||
|
|
||||||
|
|
||||||
SpeexResampler::SpeexResampler()
|
SpeexResampler::SpeexResampler()
|
||||||
:mContext(NULL), mErrorCode(0), mSourceRate(0), mDestRate(0), mLastSample(0), mChannels(0)
|
{}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpeexResampler::start(int channels, int sourceRate, int destRate)
|
void SpeexResampler::start(int channels, int sourceRate, int destRate)
|
||||||
{
|
{
|
||||||
@@ -51,6 +49,11 @@ void SpeexResampler::stop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SpeexResampler::isOpened() const
|
||||||
|
{
|
||||||
|
return mContext != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
SpeexResampler::~SpeexResampler()
|
SpeexResampler::~SpeexResampler()
|
||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
@@ -113,22 +116,22 @@ size_t SpeexResampler::processBuffer(const void* src, size_t sourceLength, size_
|
|||||||
return outLen * sizeof(short) * mChannels;
|
return outLen * sizeof(short) * mChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SpeexResampler::sourceRate()
|
int SpeexResampler::sourceRate() const
|
||||||
{
|
{
|
||||||
return mSourceRate;
|
return mSourceRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SpeexResampler::destRate()
|
int SpeexResampler::destRate() const
|
||||||
{
|
{
|
||||||
return mDestRate;
|
return mDestRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SpeexResampler::getDestLength(size_t sourceLen)
|
size_t SpeexResampler::getDestLength(size_t sourceLen) const
|
||||||
{
|
{
|
||||||
return size_t(sourceLen * (float(mDestRate) / mSourceRate) + 0.5f);
|
return size_t(sourceLen * (float(mDestRate) / mSourceRate) + 0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SpeexResampler::getSourceLength(size_t destLen)
|
size_t SpeexResampler::getSourceLength(size_t destLen) const
|
||||||
{
|
{
|
||||||
// Here we want to get 'destLen' number of samples
|
// Here we want to get 'destLen' number of samples
|
||||||
return size_t(destLen * (float(mSourceRate) / mDestRate) + 0.5f);
|
return size_t(destLen * (float(mSourceRate) / mDestRate) + 0.5f);
|
||||||
|
|||||||
@@ -24,23 +24,25 @@ namespace Audio
|
|||||||
|
|
||||||
void start(int channels, int sourceRate, int destRate);
|
void start(int channels, int sourceRate, int destRate);
|
||||||
void stop();
|
void stop();
|
||||||
|
bool isOpened() const;
|
||||||
|
|
||||||
size_t processBuffer(const void* source, size_t sourceLength, size_t& sourceProcessed,
|
size_t processBuffer(const void* source, size_t sourceLength, size_t& sourceProcessed,
|
||||||
void* dest, size_t destCapacity);
|
void* dest, size_t destCapacity);
|
||||||
int sourceRate();
|
int sourceRate() const;
|
||||||
int destRate();
|
int destRate() const;
|
||||||
size_t getDestLength(size_t sourceLen);
|
size_t getDestLength(size_t sourceLen) const;
|
||||||
size_t getSourceLength(size_t destLen);
|
size_t getSourceLength(size_t destLen) const;
|
||||||
|
|
||||||
// Returns instance + speex encoder size in bytes
|
// Returns instance + speex encoder size in bytes
|
||||||
size_t getSize() const;
|
size_t getSize() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void* mContext;
|
void* mContext = nullptr;
|
||||||
int mErrorCode;
|
int mErrorCode = 0;
|
||||||
int mSourceRate,
|
int mSourceRate = 0,
|
||||||
mDestRate,
|
mDestRate = 0,
|
||||||
mChannels;
|
mChannels = 0;
|
||||||
short mLastSample;
|
short mLastSample = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef SpeexResampler Resampler;
|
typedef SpeexResampler Resampler;
|
||||||
|
|||||||
@@ -368,20 +368,10 @@ Receiver::~Receiver()
|
|||||||
AudioReceiver::AudioReceiver(const CodecList::Settings& settings, MT::Statistics &stat)
|
AudioReceiver::AudioReceiver(const CodecList::Settings& settings, MT::Statistics &stat)
|
||||||
:Receiver(stat), mRtpBuffer(stat), mDtmfBuffer(stat), mCodecSettings(settings), mCodecList(settings), mDtmfReceiver(stat)
|
:Receiver(stat), mRtpBuffer(stat), mDtmfBuffer(stat), mCodecSettings(settings), mCodecList(settings), mDtmfReceiver(stat)
|
||||||
{
|
{
|
||||||
// Init resamplers
|
|
||||||
mResampler8.start(AUDIO_CHANNELS, 8000, AUDIO_SAMPLERATE);
|
|
||||||
mResampler16.start(AUDIO_CHANNELS, 16000, AUDIO_SAMPLERATE);
|
|
||||||
mResampler32.start(AUDIO_CHANNELS, 32000, AUDIO_SAMPLERATE);
|
|
||||||
mResampler48.start(AUDIO_CHANNELS, 48000, AUDIO_SAMPLERATE);
|
|
||||||
|
|
||||||
// Init codecs
|
// Init codecs
|
||||||
mCodecList.setSettings(settings);
|
mCodecList.setSettings(settings);
|
||||||
mCodecList.fillCodecMap(mCodecMap);
|
mCodecList.fillCodecMap(mCodecMap);
|
||||||
|
|
||||||
// 10 seconds is the maximum length of decoded audio in single step
|
|
||||||
// It is important - DTX may produce silence up to few seconds easily
|
|
||||||
mAvailable.setCapacity(AUDIO_SAMPLERATE * 10 * sizeof(short));
|
|
||||||
|
|
||||||
mDtmfBuffer.setPrebuffer(0ms);
|
mDtmfBuffer.setPrebuffer(0ms);
|
||||||
mDtmfBuffer.setLow(0ms);
|
mDtmfBuffer.setLow(0ms);
|
||||||
mDtmfBuffer.setHigh(1ms);
|
mDtmfBuffer.setHigh(1ms);
|
||||||
@@ -389,6 +379,12 @@ AudioReceiver::AudioReceiver(const CodecList::Settings& settings, MT::Statistics
|
|||||||
// Avoid collecting too much data
|
// Avoid collecting too much data
|
||||||
mRtpBuffer.setHigh(240ms);
|
mRtpBuffer.setHigh(240ms);
|
||||||
|
|
||||||
|
// Resamplers are lazy inside; there is no actual memory allocation
|
||||||
|
mResampler8.start(AUDIO_CHANNELS, 8000, AUDIO_SAMPLERATE);
|
||||||
|
mResampler16.start(AUDIO_CHANNELS, 16000, AUDIO_SAMPLERATE);
|
||||||
|
mResampler32.start(AUDIO_CHANNELS, 32000, AUDIO_SAMPLERATE);
|
||||||
|
mResampler48.start(AUDIO_CHANNELS, 48000, AUDIO_SAMPLERATE);
|
||||||
|
|
||||||
#if defined(DUMP_DECODED)
|
#if defined(DUMP_DECODED)
|
||||||
mDecodedDump = std::make_shared<Audio::WavFileWriter>();
|
mDecodedDump = std::make_shared<Audio::WavFileWriter>();
|
||||||
mDecodedDump->open("decoded.wav", 8000 /*G711*/, AUDIO_CHANNELS);
|
mDecodedDump->open("decoded.wav", 8000 /*G711*/, AUDIO_CHANNELS);
|
||||||
@@ -906,6 +902,13 @@ void AudioReceiver::ensureDecodeBuffers()
|
|||||||
mConvertedFrame.resize(MT_MAX_DECODEBUFFER * 2);
|
mConvertedFrame.resize(MT_MAX_DECODEBUFFER * 2);
|
||||||
mResampledFrame.resize(MT_MAX_DECODEBUFFER);
|
mResampledFrame.resize(MT_MAX_DECODEBUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!mAvailable.capacity())
|
||||||
|
{
|
||||||
|
// 10 seconds is the maximum length of decoded audio in single step
|
||||||
|
// It is important - DTX may produce silence up to few seconds easily
|
||||||
|
mAvailable.setCapacity(AUDIO_SAMPLERATE * 10 * sizeof(short));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioReceiver::makeMonoAndResample(int rate, int channels)
|
void AudioReceiver::makeMonoAndResample(int rate, int channels)
|
||||||
|
|||||||
@@ -56,37 +56,37 @@ class RTPMemoryManager;
|
|||||||
class JRTPLIB_IMPORTEXPORT RTPIPv4Address : public RTPAddress
|
class JRTPLIB_IMPORTEXPORT RTPIPv4Address : public RTPAddress
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Creates an instance with IP address \c ip and port number \c port (both are interpreted in host byte order). */
|
/** Creates an instance with IP address \c ip and port number \c port (both are interpreted in host byte order). */
|
||||||
RTPIPv4Address(uint32_t ip = 0, uint16_t port = 0);
|
RTPIPv4Address(uint32_t ip = 0, uint16_t port = 0);
|
||||||
|
|
||||||
/** Creates an instance with IP address \c ip and port number \c port (\c port is interpreted in host byte order). */
|
/** Creates an instance with IP address \c ip and port number \c port (\c port is interpreted in host byte order). */
|
||||||
RTPIPv4Address(const uint8_t ip[4],uint16_t port = 0);
|
RTPIPv4Address(const uint8_t ip[4],uint16_t port = 0);
|
||||||
~RTPIPv4Address();
|
~RTPIPv4Address();
|
||||||
|
|
||||||
/** Sets the IP address for this instance to \c ip which is assumed to be in host byte order. */
|
/** Sets the IP address for this instance to \c ip which is assumed to be in host byte order. */
|
||||||
void SetIP(uint32_t ip) { RTPIPv4Address::ip = ip; }
|
void SetIP(uint32_t ip) { RTPIPv4Address::ip = ip; }
|
||||||
|
|
||||||
/** Sets the IP address of this instance to \c ip. */
|
/** Sets the IP address of this instance to \c ip. */
|
||||||
void SetIP(const uint8_t ip[4]) { RTPIPv4Address::ip = (uint32_t)ip[3]; RTPIPv4Address::ip |= (((uint32_t)ip[2])<<8); RTPIPv4Address::ip |= (((uint32_t)ip[1])<<16); RTPIPv4Address::ip |= (((uint32_t)ip[0])<<24); }
|
void SetIP(const uint8_t ip[4]) { RTPIPv4Address::ip = (uint32_t)ip[3]; RTPIPv4Address::ip |= (((uint32_t)ip[2])<<8); RTPIPv4Address::ip |= (((uint32_t)ip[1])<<16); RTPIPv4Address::ip |= (((uint32_t)ip[0])<<24); }
|
||||||
|
|
||||||
/** Sets the port number for this instance to \c port which is interpreted in host byte order. */
|
/** Sets the port number for this instance to \c port which is interpreted in host byte order. */
|
||||||
void SetPort(uint16_t port) { RTPIPv4Address::port = port; }
|
void SetPort(uint16_t port) { RTPIPv4Address::port = port; }
|
||||||
|
|
||||||
/** Returns the IP address contained in this instance in host byte order. */
|
/** Returns the IP address contained in this instance in host byte order. */
|
||||||
uint32_t GetIP() const { return ip; }
|
uint32_t GetIP() const { return ip; }
|
||||||
|
|
||||||
/** Returns the port number of this instance in host byte order. */
|
/** Returns the port number of this instance in host byte order. */
|
||||||
uint16_t GetPort() const { return port; }
|
uint16_t GetPort() const { return port; }
|
||||||
|
|
||||||
RTPAddress *CreateCopy(RTPMemoryManager *mgr) const;
|
RTPAddress *CreateCopy(RTPMemoryManager *mgr) const;
|
||||||
bool IsSameAddress(const RTPAddress *addr) const;
|
bool IsSameAddress(const RTPAddress *addr) const;
|
||||||
bool IsFromSameHost(const RTPAddress *addr) const;
|
bool IsFromSameHost(const RTPAddress *addr) const;
|
||||||
#ifdef RTPDEBUG
|
#ifdef RTPDEBUG
|
||||||
std::string GetAddressString() const;
|
std::string GetAddressString() const;
|
||||||
#endif // RTPDEBUG
|
#endif // RTPDEBUG
|
||||||
private:
|
private:
|
||||||
uint32_t ip;
|
uint32_t ip;
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ public:
|
|||||||
* The flag which indicates whether this data is RTP or RTCP data is set to \c rtp. A memory
|
* The flag which indicates whether this data is RTP or RTCP data is set to \c rtp. A memory
|
||||||
* manager can be installed as well.
|
* manager can be installed as well.
|
||||||
*/
|
*/
|
||||||
RTPRawPacket(uint8_t *data,size_t datalen,RTPAddress *address,const RTPTime &recvtime,bool rtp,RTPMemoryManager *mgr = 0);
|
RTPRawPacket(uint8_t *data, size_t datalen, RTPAddress *address, const RTPTime &recvtime, bool rtp, RTPMemoryManager *mgr = 0);
|
||||||
~RTPRawPacket();
|
~RTPRawPacket();
|
||||||
|
|
||||||
/** Returns the pointer to the data which is contained in this packet. */
|
/** Returns the pointer to the data which is contained in this packet. */
|
||||||
@@ -92,7 +92,7 @@ private:
|
|||||||
bool isrtp;
|
bool isrtp;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline RTPRawPacket::RTPRawPacket(uint8_t *data,size_t datalen,RTPAddress *address, const RTPTime &recvtime,bool rtp,RTPMemoryManager *mgr):RTPMemoryObject(mgr),receivetime(recvtime)
|
inline RTPRawPacket::RTPRawPacket(uint8_t *data, size_t datalen, RTPAddress *address, const RTPTime &recvtime, bool rtp, RTPMemoryManager *mgr):RTPMemoryObject(mgr),receivetime(recvtime)
|
||||||
{
|
{
|
||||||
packetdata = data;
|
packetdata = data;
|
||||||
packetdatalength = datalen;
|
packetdatalength = datalen;
|
||||||
@@ -103,7 +103,7 @@ inline RTPRawPacket::RTPRawPacket(uint8_t *data,size_t datalen,RTPAddress *addre
|
|||||||
|
|
||||||
inline RTPRawPacket::~RTPRawPacket()
|
inline RTPRawPacket::~RTPRawPacket()
|
||||||
{
|
{
|
||||||
if (packetdata)
|
if (packetdata)
|
||||||
RTPDeleteByteArray(packetdata,GetMemoryManager());
|
RTPDeleteByteArray(packetdata,GetMemoryManager());
|
||||||
if (senderaddress)
|
if (senderaddress)
|
||||||
RTPDelete(senderaddress,GetMemoryManager());
|
RTPDelete(senderaddress,GetMemoryManager());
|
||||||
|
|||||||
@@ -9,8 +9,12 @@
|
|||||||
using namespace resip;
|
using namespace resip;
|
||||||
|
|
||||||
|
|
||||||
|
std::atomic<long> Message::sInstanceCount{0};
|
||||||
|
|
||||||
Message::Message() : mTu(0)
|
Message::Message() : mTu(0)
|
||||||
{}
|
{
|
||||||
|
++sInstanceCount;
|
||||||
|
}
|
||||||
|
|
||||||
Message::Brief
|
Message::Brief
|
||||||
Message::brief() const
|
Message::brief() const
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include "rutil/Data.hxx"
|
#include "rutil/Data.hxx"
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
|
#include <atomic>
|
||||||
#include "rutil/resipfaststreams.hxx"
|
#include "rutil/resipfaststreams.hxx"
|
||||||
|
|
||||||
namespace resip
|
namespace resip
|
||||||
@@ -21,7 +22,11 @@ class Message
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Message();
|
Message();
|
||||||
virtual ~Message() {}
|
virtual ~Message() { --sInstanceCount; }
|
||||||
|
|
||||||
|
/// Live instance count of all Message-derived objects (leak indicator).
|
||||||
|
static std::atomic<long> sInstanceCount;
|
||||||
|
static long getInstanceCount() { return sInstanceCount.load(std::memory_order_relaxed); }
|
||||||
|
|
||||||
/// facet for brief output to streams
|
/// facet for brief output to streams
|
||||||
class Brief
|
class Brief
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ using namespace std;
|
|||||||
|
|
||||||
bool SipMessage::checkContentLength=true;
|
bool SipMessage::checkContentLength=true;
|
||||||
|
|
||||||
|
std::atomic<long> SipMessage::sInstanceCount{0};
|
||||||
|
|
||||||
SipMessage::SipMessage(const Tuple *receivedTransportTuple)
|
SipMessage::SipMessage(const Tuple *receivedTransportTuple)
|
||||||
: mIsDecorated(false),
|
: mIsDecorated(false),
|
||||||
mIsBadAck200(false),
|
mIsBadAck200(false),
|
||||||
@@ -51,6 +53,7 @@ SipMessage::SipMessage(const Tuple *receivedTransportTuple)
|
|||||||
// !bwc! TODO make this tunable
|
// !bwc! TODO make this tunable
|
||||||
mHeaders.reserve(16);
|
mHeaders.reserve(16);
|
||||||
clear();
|
clear();
|
||||||
|
++sInstanceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
SipMessage::SipMessage(const SipMessage& from)
|
SipMessage::SipMessage(const SipMessage& from)
|
||||||
@@ -63,6 +66,7 @@ SipMessage::SipMessage(const SipMessage& from)
|
|||||||
mCreatedTime(Timer::getTimeMicroSec())
|
mCreatedTime(Timer::getTimeMicroSec())
|
||||||
{
|
{
|
||||||
init(from);
|
init(from);
|
||||||
|
++sInstanceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
Message*
|
Message*
|
||||||
@@ -98,6 +102,7 @@ SipMessage::~SipMessage()
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
freeMem();
|
freeMem();
|
||||||
|
--sInstanceCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include "resip/stack/Contents.hxx"
|
#include "resip/stack/Contents.hxx"
|
||||||
#include "resip/stack/Headers.hxx"
|
#include "resip/stack/Headers.hxx"
|
||||||
@@ -154,6 +155,10 @@ class SipMessage : public TransactionMessage
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
RESIP_HeapCount(SipMessage);
|
RESIP_HeapCount(SipMessage);
|
||||||
|
|
||||||
|
/// Live instance count of SipMessage objects (leak indicator).
|
||||||
|
static std::atomic<long> sInstanceCount;
|
||||||
|
static long getInstanceCount() { return sInstanceCount.load(std::memory_order_relaxed); }
|
||||||
#ifndef __SUNPRO_CC
|
#ifndef __SUNPRO_CC
|
||||||
typedef std::list< std::pair<Data, HeaderFieldValueList*>, StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase > > UnknownHeaders;
|
typedef std::list< std::pair<Data, HeaderFieldValueList*>, StlPoolAllocator<std::pair<Data, HeaderFieldValueList*>, PoolBase > > UnknownHeaders;
|
||||||
#else
|
#else
|
||||||
|
|||||||
Reference in New Issue
Block a user