- cleanups
This commit is contained in:
parent
3fa88ff9d4
commit
14b034e94c
|
|
@ -8,26 +8,46 @@ template <class T>
|
||||||
class SafeSingleton
|
class SafeSingleton
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
static std::atomic<T*> SharedInstance;
|
static std::atomic<T*> SharedInstance;
|
||||||
static std::mutex mMutex;
|
static std::mutex mMutex;
|
||||||
public:
|
public:
|
||||||
static T& instance()
|
static T& instance()
|
||||||
{
|
|
||||||
T* tmp = SharedInstance.load(std::memory_order_relaxed);
|
|
||||||
std::atomic_thread_fence(std::memory_order_acquire);
|
|
||||||
if (tmp == nullptr)
|
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mMutex);
|
T* tmp = SharedInstance.load(std::memory_order_relaxed);
|
||||||
tmp = SharedInstance.load(std::memory_order_relaxed);
|
std::atomic_thread_fence(std::memory_order_acquire);
|
||||||
if (tmp == nullptr)
|
if (tmp == nullptr)
|
||||||
{
|
{
|
||||||
tmp = new T();
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
std::atomic_thread_fence(std::memory_order_release);
|
tmp = SharedInstance.load(std::memory_order_relaxed);
|
||||||
SharedInstance.store(tmp, std::memory_order_relaxed);
|
if (tmp == nullptr)
|
||||||
|
{
|
||||||
|
tmp = new T();
|
||||||
|
std::atomic_thread_fence(std::memory_order_release);
|
||||||
|
SharedInstance.store(tmp, std::memory_order_relaxed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return *tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename X>
|
||||||
|
static T& precreate(X n)
|
||||||
|
{
|
||||||
|
T* tmp = SharedInstance.load(std::memory_order_relaxed);
|
||||||
|
std::atomic_thread_fence(std::memory_order_acquire);
|
||||||
|
if (tmp == nullptr)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
tmp = SharedInstance.load(std::memory_order_relaxed);
|
||||||
|
if (tmp == nullptr)
|
||||||
|
{
|
||||||
|
tmp = new T(n);
|
||||||
|
std::atomic_thread_fence(std::memory_order_release);
|
||||||
|
SharedInstance.store(tmp, std::memory_order_relaxed);
|
||||||
|
return *tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Singletone instance is created already");
|
||||||
}
|
}
|
||||||
return *tmp;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright(C) 2007-2018 VoIPobjects (voipobjects.com)
|
/* Copyright(C) 2007-2019 VoIPobjects (voipobjects.com)
|
||||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
@ -99,7 +99,8 @@ protected:
|
||||||
// - Handlers are ALWAYS executed in the Timer Queue worker thread.
|
// - Handlers are ALWAYS executed in the Timer Queue worker thread.
|
||||||
// - Handlers execution order is NOT guaranteed
|
// - Handlers execution order is NOT guaranteed
|
||||||
//
|
//
|
||||||
class TimerQueue {
|
class TimerQueue
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
TimerQueue();
|
TimerQueue();
|
||||||
~TimerQueue();
|
~TimerQueue();
|
||||||
|
|
@ -135,7 +136,8 @@ private:
|
||||||
bool m_finish = false;
|
bool m_finish = false;
|
||||||
uint64_t m_idcounter = 0;
|
uint64_t m_idcounter = 0;
|
||||||
|
|
||||||
struct WorkItem {
|
struct WorkItem
|
||||||
|
{
|
||||||
Clock::time_point end;
|
Clock::time_point end;
|
||||||
uint64_t id; // id==0 means it was cancelled
|
uint64_t id; // id==0 means it was cancelled
|
||||||
std::function<void(bool)> handler;
|
std::function<void(bool)> handler;
|
||||||
|
|
@ -145,7 +147,8 @@ private:
|
||||||
std::mutex m_mtx;
|
std::mutex m_mtx;
|
||||||
// Inheriting from priority_queue, so we can access the internal container
|
// Inheriting from priority_queue, so we can access the internal container
|
||||||
class Queue : public std::priority_queue<WorkItem, std::vector<WorkItem>,
|
class Queue : public std::priority_queue<WorkItem, std::vector<WorkItem>,
|
||||||
std::greater<WorkItem>> {
|
std::greater<WorkItem>>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<WorkItem>& getContainer();
|
std::vector<WorkItem>& getContainer();
|
||||||
} m_items;
|
} m_items;
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ int RtpBuffer::prebuffer()
|
||||||
int RtpBuffer::getCount() const
|
int RtpBuffer::getCount() const
|
||||||
{
|
{
|
||||||
Lock l(mGuard);
|
Lock l(mGuard);
|
||||||
return mPacketList.size();
|
return static_cast<int>(mPacketList.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SequenceSort(const RtpBuffer::Packet& p1, const RtpBuffer::Packet& p2)
|
bool SequenceSort(const RtpBuffer::Packet& p1, const RtpBuffer::Packet& p2)
|
||||||
|
|
@ -390,7 +390,7 @@ bool AudioReceiver::add(std::shared_ptr<jrtplib::RTPPacket> p, Codec** codec)
|
||||||
|
|
||||||
// Process jitter
|
// Process jitter
|
||||||
mJitterStats.process(p.get(), codecIter->second->samplerate());
|
mJitterStats.process(p.get(), codecIter->second->samplerate());
|
||||||
mStat.mJitter = (float)mJitterStats.get().getCurrent();
|
mStat.mJitter = static_cast<float>(mJitterStats.get().getCurrent());
|
||||||
|
|
||||||
// Check if packet is CNG
|
// Check if packet is CNG
|
||||||
if (payloadLength >= 1 && payloadLength <= 6 && (ptype == 0 || ptype == 8))
|
if (payloadLength >= 1 && payloadLength <= 6 && (ptype == 0 || ptype == 8))
|
||||||
|
|
@ -409,14 +409,14 @@ bool AudioReceiver::add(std::shared_ptr<jrtplib::RTPPacket> p, Codec** codec)
|
||||||
return mBuffer.add(p, timelen, codecIter->second->samplerate());
|
return mBuffer.add(p, timelen, codecIter->second->samplerate());
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioReceiver::processDecoded(Audio::DataWindow& output, DecodeOptions options)
|
void AudioReceiver::processDecoded(Audio::DataWindow& output, int options)
|
||||||
{
|
{
|
||||||
// Write to audio dump if requested
|
// Write to audio dump if requested
|
||||||
if (mDecodedDump && mDecodedLength)
|
if (mDecodedDump && mDecodedLength)
|
||||||
mDecodedDump->write(mDecodedFrame, mDecodedLength);
|
mDecodedDump->write(mDecodedFrame, mDecodedLength);
|
||||||
|
|
||||||
// Resample to target rate
|
// Resample to target rate
|
||||||
bool resample = !((int)options & (int)DecodeOptions::DontResample);
|
bool resample = !(options & DecodeOptions_DontResample);
|
||||||
makeMonoAndResample(resample ? mCodec->samplerate() : 0,
|
makeMonoAndResample(resample ? mCodec->samplerate() : 0,
|
||||||
mCodec->channels());
|
mCodec->channels());
|
||||||
|
|
||||||
|
|
@ -429,7 +429,7 @@ void AudioReceiver::processDecoded(Audio::DataWindow& output, DecodeOptions opti
|
||||||
output.add(mResampledFrame, mResampledLength);
|
output.add(mResampledFrame, mResampledLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioReceiver::getAudio(Audio::DataWindow& output, DecodeOptions options, int* rate)
|
bool AudioReceiver::getAudio(Audio::DataWindow& output, int options, int* rate)
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
|
|
@ -446,13 +446,14 @@ bool AudioReceiver::getAudio(Audio::DataWindow& output, DecodeOptions options, i
|
||||||
{
|
{
|
||||||
// Synthesize comfort noise. It will be done on AUDIO_SAMPLERATE rate directly to mResampledFrame buffer.
|
// Synthesize comfort noise. It will be done on AUDIO_SAMPLERATE rate directly to mResampledFrame buffer.
|
||||||
// Do not forget to send this noise to analysis
|
// Do not forget to send this noise to analysis
|
||||||
mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), mLastPacketTimeLength, (short*)mDecodedFrame, false);
|
mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), mLastPacketTimeLength,
|
||||||
|
reinterpret_cast<short*>(mDecodedFrame), false);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if (mCodec && mFrameCount && !mCodecSettings.mSkipDecode)
|
if (mCodec && mFrameCount && !mCodecSettings.mSkipDecode)
|
||||||
{
|
{
|
||||||
// Do PLC to mDecodedFrame/mDecodedLength
|
// Do PLC to mDecodedFrame/mDecodedLength
|
||||||
if ((int)options & (int)DecodeOptions::SkipDecode)
|
if (options & DecodeOptions_SkipDecode)
|
||||||
mDecodedLength = 0;
|
mDecodedLength = 0;
|
||||||
else
|
else
|
||||||
mDecodedLength = mCodec->plc(mFrameCount, mDecodedFrame, sizeof mDecodedFrame);
|
mDecodedLength = mCodec->plc(mFrameCount, mDecodedFrame, sizeof mDecodedFrame);
|
||||||
|
|
@ -481,7 +482,7 @@ bool AudioReceiver::getAudio(Audio::DataWindow& output, DecodeOptions options, i
|
||||||
{
|
{
|
||||||
assert(p);
|
assert(p);
|
||||||
// Check if previously CNG packet was detected. Emit CNG audio here if needed.
|
// Check if previously CNG packet was detected. Emit CNG audio here if needed.
|
||||||
if ((int)options & (int)DecodeOptions::FillCngGap && mCngPacket && mCodec)
|
if (options & DecodeOptions_FillCngGap && mCngPacket && mCodec)
|
||||||
{
|
{
|
||||||
// Fill CNG audio is server mode is present
|
// Fill CNG audio is server mode is present
|
||||||
int units = p->GetTimestamp() - mCngPacket->GetTimestamp();
|
int units = p->GetTimestamp() - mCngPacket->GetTimestamp();
|
||||||
|
|
@ -491,10 +492,11 @@ bool AudioReceiver::getAudio(Audio::DataWindow& output, DecodeOptions options, i
|
||||||
int frames100ms = milliseconds / 100;
|
int frames100ms = milliseconds / 100;
|
||||||
for (int frameIndex = 0; frameIndex < frames100ms; frameIndex++)
|
for (int frameIndex = 0; frameIndex < frames100ms; frameIndex++)
|
||||||
{
|
{
|
||||||
if ((int)options & (int)DecodeOptions::SkipDecode)
|
if (options & DecodeOptions_SkipDecode)
|
||||||
mDecodedLength = 0;
|
mDecodedLength = 0;
|
||||||
else
|
else
|
||||||
mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), 100, (short*)mDecodedFrame, false);
|
mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), 100,
|
||||||
|
reinterpret_cast<short*>(mDecodedFrame), false);
|
||||||
|
|
||||||
if (mDecodedLength)
|
if (mDecodedLength)
|
||||||
processDecoded(output, options);
|
processDecoded(output, options);
|
||||||
|
|
@ -503,10 +505,11 @@ bool AudioReceiver::getAudio(Audio::DataWindow& output, DecodeOptions options, i
|
||||||
int tail = milliseconds % 100;
|
int tail = milliseconds % 100;
|
||||||
if (tail)
|
if (tail)
|
||||||
{
|
{
|
||||||
if ((int)options & (int)DecodeOptions::SkipDecode)
|
if (options & DecodeOptions_SkipDecode)
|
||||||
mDecodedLength = 0;
|
mDecodedLength = 0;
|
||||||
else
|
else
|
||||||
mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), tail, (short*)mDecodedFrame, false);
|
mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), tail,
|
||||||
|
reinterpret_cast<short*>(mDecodedFrame), false);
|
||||||
|
|
||||||
if (mDecodedLength)
|
if (mDecodedLength)
|
||||||
processDecoded(output, options);
|
processDecoded(output, options);
|
||||||
|
|
@ -525,14 +528,15 @@ bool AudioReceiver::getAudio(Audio::DataWindow& output, DecodeOptions options, i
|
||||||
// Check if it is CNG packet
|
// Check if it is CNG packet
|
||||||
if ((p->GetPayloadType() == 0 || p->GetPayloadType() == 8) && p->GetPayloadLength() >= 1 && p->GetPayloadLength() <= 6)
|
if ((p->GetPayloadType() == 0 || p->GetPayloadType() == 8) && p->GetPayloadLength() >= 1 && p->GetPayloadLength() <= 6)
|
||||||
{
|
{
|
||||||
if ((int)options & (int)DecodeOptions::SkipDecode)
|
if (options & DecodeOptions_SkipDecode)
|
||||||
mDecodedLength = 0;
|
mDecodedLength = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mCngPacket = p;
|
mCngPacket = p;
|
||||||
mCngDecoder.decode3389(p->GetPayloadData(), p->GetPayloadLength());
|
mCngDecoder.decode3389(p->GetPayloadData(), p->GetPayloadLength());
|
||||||
// Emit CNG mLastPacketLength milliseconds
|
// Emit CNG mLastPacketLength milliseconds
|
||||||
mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), mLastPacketTimeLength, (short*)mDecodedFrame, true);
|
mDecodedLength = mCngDecoder.produce(mCodec->samplerate(), mLastPacketTimeLength,
|
||||||
|
(short*)mDecodedFrame, true);
|
||||||
if (mDecodedLength)
|
if (mDecodedLength)
|
||||||
processDecoded(output, options);
|
processDecoded(output, options);
|
||||||
}
|
}
|
||||||
|
|
@ -559,7 +563,7 @@ bool AudioReceiver::getAudio(Audio::DataWindow& output, DecodeOptions options, i
|
||||||
// Decode
|
// Decode
|
||||||
for (int i=0; i<mFrameCount && !mCodecSettings.mSkipDecode; i++)
|
for (int i=0; i<mFrameCount && !mCodecSettings.mSkipDecode; i++)
|
||||||
{
|
{
|
||||||
if ((int)options & (int)DecodeOptions::SkipDecode)
|
if (options & DecodeOptions_SkipDecode)
|
||||||
mDecodedLength = 0;
|
mDecodedLength = 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -725,7 +729,7 @@ int AudioReceiver::timelengthFor(jrtplib::RTPPacket& p)
|
||||||
PCodec codec = codecIter->second;
|
PCodec codec = codecIter->second;
|
||||||
if (codec)
|
if (codec)
|
||||||
{
|
{
|
||||||
int frameCount = p.GetPayloadLength() / codec->rtpLength();
|
int frameCount = static_cast<int>(p.GetPayloadLength() / codec->rtpLength());
|
||||||
if (p.GetPayloadType() == 9/*G729A silence*/ && p.GetPayloadLength() % codec->rtpLength())
|
if (p.GetPayloadType() == 9/*G729A silence*/ && p.GetPayloadLength() % codec->rtpLength())
|
||||||
frameCount++;
|
frameCount++;
|
||||||
|
|
||||||
|
|
@ -758,6 +762,6 @@ DtmfReceiver::~DtmfReceiver()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtmfReceiver::add(std::shared_ptr<RTPPacket> p)
|
void DtmfReceiver::add(std::shared_ptr<RTPPacket> /*p*/)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -113,15 +113,15 @@ namespace MT
|
||||||
bool add(std::shared_ptr<jrtplib::RTPPacket> p, Codec** codec = nullptr);
|
bool add(std::shared_ptr<jrtplib::RTPPacket> p, Codec** codec = nullptr);
|
||||||
|
|
||||||
// Returns false when there is no rtp data from jitter
|
// Returns false when there is no rtp data from jitter
|
||||||
enum class DecodeOptions
|
enum DecodeOptions
|
||||||
{
|
{
|
||||||
ResampleToMainRate = 0,
|
DecodeOptions_ResampleToMainRate = 0,
|
||||||
DontResample = 1,
|
DecodeOptions_DontResample = 1,
|
||||||
FillCngGap = 2,
|
DecodeOptions_FillCngGap = 2,
|
||||||
SkipDecode = 4
|
DecodeOptions_SkipDecode = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
bool getAudio(Audio::DataWindow& output, DecodeOptions options = DecodeOptions::ResampleToMainRate, int* rate = nullptr);
|
bool getAudio(Audio::DataWindow& output, int options = DecodeOptions_ResampleToMainRate, int* rate = nullptr);
|
||||||
|
|
||||||
// Looks for codec by payload type
|
// Looks for codec by payload type
|
||||||
Codec* findCodec(int payloadType);
|
Codec* findCodec(int payloadType);
|
||||||
|
|
@ -172,7 +172,7 @@ namespace MT
|
||||||
void makeMonoAndResample(int rate, int channels);
|
void makeMonoAndResample(int rate, int channels);
|
||||||
|
|
||||||
// Resamples, sends to analysis, writes to dump and queues to output decoded frames from mDecodedFrame
|
// Resamples, sends to analysis, writes to dump and queues to output decoded frames from mDecodedFrame
|
||||||
void processDecoded(Audio::DataWindow& output, DecodeOptions options);
|
void processDecoded(Audio::DataWindow& output, int options);
|
||||||
|
|
||||||
#if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER)
|
#if defined(USE_PVQA_LIBRARY) && !defined(PVQA_SERVER)
|
||||||
std::shared_ptr<SevanaPVQA> mPVQA;
|
std::shared_ptr<SevanaPVQA> mPVQA;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue