- better internal statistics + memory performance optimization

This commit is contained in:
2026-06-18 12:28:19 +03:00
parent 2cb2a93d59
commit 1e020a7b5f
9 changed files with 83 additions and 56 deletions
+10 -7
View File
@@ -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);
+12 -10
View File
@@ -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;
+13 -10
View File
@@ -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)
+5 -1
View File
@@ -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
+6 -1
View File
@@ -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