diff --git a/src/engine/audio/Audio_Resampler.cpp b/src/engine/audio/Audio_Resampler.cpp index 8f38fb56..41299c09 100644 --- a/src/engine/audio/Audio_Resampler.cpp +++ b/src/engine/audio/Audio_Resampler.cpp @@ -18,9 +18,7 @@ namespace Audio SpeexResampler::SpeexResampler() - :mContext(NULL), mErrorCode(0), mSourceRate(0), mDestRate(0), mLastSample(0), mChannels(0) -{ -} +{} 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() { stop(); @@ -113,22 +116,22 @@ size_t SpeexResampler::processBuffer(const void* src, size_t sourceLength, size_ return outLen * sizeof(short) * mChannels; } -int SpeexResampler::sourceRate() +int SpeexResampler::sourceRate() const { return mSourceRate; } -int SpeexResampler::destRate() +int SpeexResampler::destRate() const { 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); } -size_t SpeexResampler::getSourceLength(size_t destLen) +size_t SpeexResampler::getSourceLength(size_t destLen) const { // Here we want to get 'destLen' number of samples return size_t(destLen * (float(mSourceRate) / mDestRate) + 0.5f); diff --git a/src/engine/audio/Audio_Resampler.h b/src/engine/audio/Audio_Resampler.h index 3d7af968..494a3842 100644 --- a/src/engine/audio/Audio_Resampler.h +++ b/src/engine/audio/Audio_Resampler.h @@ -24,23 +24,25 @@ namespace Audio void start(int channels, int sourceRate, int destRate); void stop(); + bool isOpened() const; + size_t processBuffer(const void* source, size_t sourceLength, size_t& sourceProcessed, void* dest, size_t destCapacity); - int sourceRate(); - int destRate(); - size_t getDestLength(size_t sourceLen); - size_t getSourceLength(size_t destLen); + int sourceRate() const; + int destRate() const; + size_t getDestLength(size_t sourceLen) const; + size_t getSourceLength(size_t destLen) const; // Returns instance + speex encoder size in bytes size_t getSize() const; protected: - void* mContext; - int mErrorCode; - int mSourceRate, - mDestRate, - mChannels; - short mLastSample; + void* mContext = nullptr; + int mErrorCode = 0; + int mSourceRate = 0, + mDestRate = 0, + mChannels = 0; + short mLastSample = 0; }; typedef SpeexResampler Resampler; diff --git a/src/engine/media/MT_AudioReceiver.cpp b/src/engine/media/MT_AudioReceiver.cpp index b5b074c3..6550012c 100644 --- a/src/engine/media/MT_AudioReceiver.cpp +++ b/src/engine/media/MT_AudioReceiver.cpp @@ -368,20 +368,10 @@ Receiver::~Receiver() AudioReceiver::AudioReceiver(const CodecList::Settings& settings, MT::Statistics &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 mCodecList.setSettings(settings); 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.setLow(0ms); mDtmfBuffer.setHigh(1ms); @@ -389,6 +379,12 @@ AudioReceiver::AudioReceiver(const CodecList::Settings& settings, MT::Statistics // Avoid collecting too much data 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) mDecodedDump = std::make_shared(); mDecodedDump->open("decoded.wav", 8000 /*G711*/, AUDIO_CHANNELS); @@ -906,6 +902,13 @@ void AudioReceiver::ensureDecodeBuffers() mConvertedFrame.resize(MT_MAX_DECODEBUFFER * 2); 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) diff --git a/src/libs/jrtplib/src/rtpipv4address.h b/src/libs/jrtplib/src/rtpipv4address.h index b61f49fd..527941a2 100644 --- a/src/libs/jrtplib/src/rtpipv4address.h +++ b/src/libs/jrtplib/src/rtpipv4address.h @@ -56,37 +56,37 @@ class RTPMemoryManager; class JRTPLIB_IMPORTEXPORT RTPIPv4Address : public RTPAddress { public: - /** 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); - - /** 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(); + /** 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); - /** 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; } + /** 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(); - /** 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); } + /** 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; } - /** 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; } + /** 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); } - /** Returns the IP address contained in this instance in host byte order. */ - uint32_t GetIP() const { return ip; } + /** 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; } - /** Returns the port number of this instance in host byte order. */ - uint16_t GetPort() const { return port; } + /** Returns the IP address contained in this instance in host byte order. */ + uint32_t GetIP() const { return ip; } - RTPAddress *CreateCopy(RTPMemoryManager *mgr) const; - bool IsSameAddress(const RTPAddress *addr) const; - bool IsFromSameHost(const RTPAddress *addr) const; + /** Returns the port number of this instance in host byte order. */ + uint16_t GetPort() const { return port; } + + RTPAddress *CreateCopy(RTPMemoryManager *mgr) const; + bool IsSameAddress(const RTPAddress *addr) const; + bool IsFromSameHost(const RTPAddress *addr) const; #ifdef RTPDEBUG - std::string GetAddressString() const; + std::string GetAddressString() const; #endif // RTPDEBUG private: - uint32_t ip; - uint16_t port; + uint32_t ip; + uint16_t port; }; } // end namespace diff --git a/src/libs/jrtplib/src/rtprawpacket.h b/src/libs/jrtplib/src/rtprawpacket.h index 10496144..d6eb2660 100644 --- a/src/libs/jrtplib/src/rtprawpacket.h +++ b/src/libs/jrtplib/src/rtprawpacket.h @@ -58,7 +58,7 @@ public: * 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. */ - 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(); /** Returns the pointer to the data which is contained in this packet. */ @@ -92,7 +92,7 @@ private: 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; packetdatalength = datalen; @@ -103,7 +103,7 @@ inline RTPRawPacket::RTPRawPacket(uint8_t *data,size_t datalen,RTPAddress *addre inline RTPRawPacket::~RTPRawPacket() { - if (packetdata) + if (packetdata) RTPDeleteByteArray(packetdata,GetMemoryManager()); if (senderaddress) RTPDelete(senderaddress,GetMemoryManager()); diff --git a/src/libs/resiprocate/resip/stack/Message.cxx b/src/libs/resiprocate/resip/stack/Message.cxx index 14dbcc70..c4decf77 100644 --- a/src/libs/resiprocate/resip/stack/Message.cxx +++ b/src/libs/resiprocate/resip/stack/Message.cxx @@ -9,8 +9,12 @@ using namespace resip; -Message::Message() : mTu(0) -{} +std::atomic Message::sInstanceCount{0}; + +Message::Message() : mTu(0) +{ + ++sInstanceCount; +} Message::Brief Message::brief() const diff --git a/src/libs/resiprocate/resip/stack/Message.hxx b/src/libs/resiprocate/resip/stack/Message.hxx index 95a6f614..d04f8568 100644 --- a/src/libs/resiprocate/resip/stack/Message.hxx +++ b/src/libs/resiprocate/resip/stack/Message.hxx @@ -7,6 +7,7 @@ #include "rutil/Data.hxx" #include +#include #include "rutil/resipfaststreams.hxx" namespace resip @@ -21,7 +22,11 @@ class Message { public: Message(); - virtual ~Message() {} + virtual ~Message() { --sInstanceCount; } + + /// Live instance count of all Message-derived objects (leak indicator). + static std::atomic sInstanceCount; + static long getInstanceCount() { return sInstanceCount.load(std::memory_order_relaxed); } /// facet for brief output to streams class Brief diff --git a/src/libs/resiprocate/resip/stack/SipMessage.cxx b/src/libs/resiprocate/resip/stack/SipMessage.cxx index 6a65baa9..b0910624 100644 --- a/src/libs/resiprocate/resip/stack/SipMessage.cxx +++ b/src/libs/resiprocate/resip/stack/SipMessage.cxx @@ -28,6 +28,8 @@ using namespace std; bool SipMessage::checkContentLength=true; +std::atomic SipMessage::sInstanceCount{0}; + SipMessage::SipMessage(const Tuple *receivedTransportTuple) : mIsDecorated(false), mIsBadAck200(false), @@ -51,6 +53,7 @@ SipMessage::SipMessage(const Tuple *receivedTransportTuple) // !bwc! TODO make this tunable mHeaders.reserve(16); clear(); + ++sInstanceCount; } SipMessage::SipMessage(const SipMessage& from) @@ -63,6 +66,7 @@ SipMessage::SipMessage(const SipMessage& from) mCreatedTime(Timer::getTimeMicroSec()) { init(from); + ++sInstanceCount; } Message* @@ -98,6 +102,7 @@ SipMessage::~SipMessage() } #endif freeMem(); + --sInstanceCount; } void diff --git a/src/libs/resiprocate/resip/stack/SipMessage.hxx b/src/libs/resiprocate/resip/stack/SipMessage.hxx index 69452e69..c8a10255 100644 --- a/src/libs/resiprocate/resip/stack/SipMessage.hxx +++ b/src/libs/resiprocate/resip/stack/SipMessage.hxx @@ -6,7 +6,8 @@ #include #include #include -#include +#include +#include #include "resip/stack/Contents.hxx" #include "resip/stack/Headers.hxx" @@ -154,6 +155,10 @@ class SipMessage : public TransactionMessage { public: RESIP_HeapCount(SipMessage); + + /// Live instance count of SipMessage objects (leak indicator). + static std::atomic sInstanceCount; + static long getInstanceCount() { return sInstanceCount.load(std::memory_order_relaxed); } #ifndef __SUNPRO_CC typedef std::list< std::pair, StlPoolAllocator, PoolBase > > UnknownHeaders; #else