Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmytro Bogovych 2022-02-14 22:18:55 +02:00
commit 2fa4d0c3e6
27 changed files with 203 additions and 171 deletions

View File

@ -60,7 +60,9 @@ set (rtphone_engine engine)
set (USE_AMR_CODEC OFF CACHE BOOL "Use AMR codec. Requires libraries.")
set (USE_EVS_CODEC OFF CACHE BOOL "Use EVS codec." )
set (USE_OPUS_CODEC OFF CACHE BOOL "Use Opus codec." )
set (USE_SEVANA_LIB OFF CACHE BOOL "Build with Sevana libraries" )
set (USE_PVQA_LIB OFF CACHE BOOL "Build with Sevana PVQA library" )
set (USE_AQUA_LIB OFF CACHE BOOL "Build with Sevana AQuA library" )
set (USE_MUSL OFF CACHE BOOL "Build with MUSL library" )
# PIC code by default
set (CMAKE_POSITION_INDEPENDENT_CODE ON)
@ -81,13 +83,25 @@ if (CMAKE_SYSTEM MATCHES "Linux*")
add_definitions (-DTARGET_LINUX)
endif()
if (CMAKE_SYSTEM MATCHES "Darwin*")
add_definitions (-DTARGET_OSX)
endif()
if (USE_SEVANA_LIB)
message("Use Sevana libraries")
add_definitions( -DUSE_AQUA_LIBRARY -DUSE_PVQA_LIBRARY)
if (USE_MUSL)
add_definitions(-DTARGET_MUSL)
endif()
if (USE_AQUA_LIB)
message("Use AQuA library")
add_definitions( -DUSE_AQUA_LIBRARY )
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libs/pvqa/include)
endif()
if (USE_PVQA_LIBRARY)
message("Use PVQA libraries")
add_definitions( -DUSE_PVQA_LIBRARY )
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/libs/pvqa/include)
endif()

View File

@ -4,6 +4,7 @@
#include "helper/HL_StreamState.h"
#include "helper/HL_VariantMap.h"
#include "helper/HL_CsvReader.h"
#include "helper/HL_Base64.h"
#include <fstream>
#if defined(USE_PVQA_LIBRARY)
@ -208,10 +209,13 @@ void AgentImpl::processStart(JsonCpp::Value& /*request*/, JsonCpp::Value &answer
PVariantMap priorityConfig = std::make_shared<VariantMap>();
MT::CodecList& cl = mTerminal->codeclist();
for (int i=0; i<cl.count(); i++)
if (cl.codecAt(i).payloadType() < 96)
priorityConfig->at(i) = i;
// Disable dynamic payload codec types - commented for now
/*if (cl.codecAt(i).payloadType() < 96)
priorityConfig->at(i) = i;
else
priorityConfig->at(i) = -1;
priorityConfig->at(i) = -1;*/
config()[CONFIG_CODEC_PRIORITY] = priorityConfig;
@ -332,17 +336,20 @@ void AgentImpl::processStartSession(JsonCpp::Value& request, JsonCpp::Value& ans
std::string path_faults = request["path_faults"].asString();
sevana::aqua::config config = {
{ "avlp", "off" },
{ "decor", "off" },
{ "mprio", "off" },
{ "miter", "1" },
{ "enorm", "off" },
{ "voip", "on" },
{ "g711", "on" },
{ "spfrcor", "on" },
{ "grad", "off" },
{ "ratem", "%%m" },
{ "trim", "a 2" },
{"avlp", "off"},
{"smtnrm", "off"},
{"decor", "off"},
{"mprio", "off"},
{"npnt", "auto"},
{"voip", "on"},
{"enorm", "rms"},
{"g711", "off"},
{"spfrcor", "on"},
{"grad", "off"},
{"tmc", "on"},
{"miter", "1"},
{ "ratem", "%m" },
{ "trim", "a 10" },
{ "output", "json" },
{ "fau", path_faults},
{ "specp", "32"}
@ -528,6 +535,9 @@ void AgentImpl::processGetMediaStats(JsonCpp::Value& request, JsonCpp::Value& an
#endif
if (result.exists(SessionInfo_PacketLoss))
answer["rtp_lost"] = result[SessionInfo_LostRtp].asInt();
if (result.exists(SessionInfo_DroppedRtp))
answer["rtp_dropped"] = result[SessionInfo_DroppedRtp].asInt();
if (result.exists(SessionInfo_SentRtp))
answer["rtp_sent"] = result[SessionInfo_SentRtp].asInt();
if (result.exists(SessionInfo_ReceivedRtp))
@ -549,6 +559,8 @@ void AgentImpl::processGetMediaStats(JsonCpp::Value& request, JsonCpp::Value& an
if (includeAqua)
{
answer["incoming_audio"] = mAquaIncoming.hexstring();
answer["incoming_audio_samplerate"] = AUDIO_SAMPLERATE;
answer["incoming_audio_channels"] = AUDIO_CHANNELS;
ICELogInfo(<< "Running AQuA analyzer.");
ByteBuffer referenceAudio;
@ -593,6 +605,12 @@ void AgentImpl::processGetMediaStats(JsonCpp::Value& request, JsonCpp::Value& an
}
answer["aqua_mos"] = r.mMos;
answer["aqua_report"] = r.mFaultsText;
/*std::string aqua_audio_text;
if (Base64::Encode(std::string(reinterpret_cast<const char*>(mAquaIncoming.data()), mAquaIncoming.size()), &aqua_audio_text))
{
answer["aqua_audio"] = aqua_audio_text;
}*/
if (r.mErrorCode) {
answer["aqua_error_code"] = r.mErrorCode;
answer["aqua_error_message"] = r.mErrorMessage;

View File

@ -154,7 +154,7 @@ int ChannelConverter::stereoToMono(const void *source, int sourceLength, void *d
int ChannelConverter::monoToStereo(const void *source, int sourceLength, void *dest, int destLength)
{
assert(destLength == sourceLength * 2);
assert (destLength == sourceLength * 2);
const short* input = (const short*)source;
short* output = (short*)dest;
// Convert starting from the end of buffer to allow inplace conversion

View File

@ -17,7 +17,7 @@
#define AUDIO_CHANNELS 1
// Samplerate must be 8 / 16 / 24 / 32 / 48 KHz
#define AUDIO_SAMPLERATE 8000
#define AUDIO_SAMPLERATE 16000
#define AUDIO_MIC_BUFFER_COUNT 16
#define AUDIO_MIC_BUFFER_LENGTH 10
#define AUDIO_MIC_BUFFER_SIZE (AUDIO_MIC_BUFFER_LENGTH * AUDIO_SAMPLERATE / 1000 * 2 * AUDIO_CHANNELS)
@ -84,7 +84,7 @@
// OPUS codec defines
// #define USE_OPUS_CODEC
#define MT_OPUS_CODEC_PT -1
#define MT_OPUS_CODEC_PT 106
// ILBC codec defines
#define MT_ILBC20_PAYLOADTYPE -1

View File

@ -26,7 +26,7 @@ AudioProvider::AudioProvider(UserAgent& agent, MT::Terminal& terminal)
if (mUserAgent.config().exists(CONFIG_CODEC_PRIORITY))
mCodecPriority.setupFrom(mUserAgent.config()[CONFIG_CODEC_PRIORITY].asVMap());
mSrtpSuite = SRTP_NONE;
setState((int)StreamState::SipRecv | (int)StreamState::SipSend | (int)StreamState::Receiving | (int)StreamState::Sending);
setStateImpl((int)StreamState::SipRecv | (int)StreamState::SipSend | (int)StreamState::Receiving | (int)StreamState::Sending);
}
AudioProvider::~AudioProvider()
@ -182,6 +182,7 @@ void AudioProvider::sessionEstablished(int conntype)
{
RemoteCodec& rc = mAvailableCodecs.front();
mActiveStream->setTransmittingCodec(*rc.mFactory, rc.mRemotePayloadType);
auto codec = dynamic_cast<MT::AudioStream*>(mActiveStream.get())->transmittingCodec();
dynamic_cast<MT::AudioStream*>(mActiveStream.get())->setTelephoneCodec(mRemoteTelephoneCodec);
}
}
@ -271,11 +272,10 @@ bool AudioProvider::processSdpOffer(const resip::SdpContents::Session::Medium& m
return true;
}
void AudioProvider::setState(unsigned state)
{
mState = state;
if (mActiveStream)
mActiveStream->setState(state);
setStateImpl(state);
}
unsigned AudioProvider::state()
@ -381,3 +381,10 @@ void AudioProvider::setupMirror(bool enable)
if (mActiveStream)
mActiveStream->setupMirror(enable);
}
void AudioProvider::setStateImpl(unsigned int state) {
mState = state;
if (mActiveStream)
mActiveStream->setState(state);
}

View File

@ -43,31 +43,32 @@ public:
void sendData(PDatagramSocket s, InternetAddress& destination, const void* dataBuffer, unsigned int datasize);
// Updates SDP offer
void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction);
void updateSdpOffer(resip::SdpContents::Session::Medium& sdp, SdpDirection direction) override;
// Called by user agent when session is deleted.
void sessionDeleted();
void sessionDeleted() override;
// Called by user agent when session is terminated.
void sessionTerminated();
void sessionTerminated() override;
// Called by user agent when session is started.
void sessionEstablished(int conntype);
void sessionEstablished(int conntype) override;
// Called by user agent to save media socket for this provider
void setSocket(const RtpPair<PDatagramSocket>& p4, const RtpPair<PDatagramSocket>& p6);
void setSocket(const RtpPair<PDatagramSocket>& p4, const RtpPair<PDatagramSocket>& p6) override;
// Called by user agent to get media socket for this provider
RtpPair<PDatagramSocket>& socket(int family);
RtpPair<PDatagramSocket>& socket(int family) override;
// Called by user agent to process media stream description from remote peer.
// Returns true if description is processed succesfully. Otherwise method returns false.
// myAnswer sets if the answer will be sent after.
bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection);
bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) override;
void setState(unsigned state);
unsigned state();
MT::Statistics getStatistics();
void setState(unsigned state) override;
unsigned state() override;
MT::Statistics getStatistics() override;
MT::PStream activeStream();
void readFile(const Audio::PWavFileReader& stream, MT::Stream::MediaDirection direction);
@ -112,6 +113,10 @@ protected:
std::string createCryptoAttribute(SrtpSuite suite);
SrtpSuite processCryptoAttribute(const resip::Data& value, ByteBuffer& key);
void findRfc2833(const resip::SdpContents::Session::Medium::CodecContainer& codecs);
// Implements setState() logic. This allows to be called from constructor (it is not virtual function)
void setStateImpl(unsigned state);
};
#endif

View File

@ -478,6 +478,7 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info)
info[SessionInfo_ReceivedRtp] = static_cast<int>(stat.mReceivedRtp);
info[SessionInfo_ReceivedRtcp] = static_cast<int>(stat.mReceivedRtcp);
info[SessionInfo_LostRtp] = static_cast<int>(stat.mPacketLoss);
info[SessionInfo_DroppedRtp] = static_cast<int>(stat.mPacketDropped);
info[SessionInfo_SentRtp] = static_cast<int>(stat.mSentRtp);
info[SessionInfo_SentRtcp] = static_cast<int>(stat.mSentRtcp);
if (stat.mFirstRtpTime)
@ -726,7 +727,7 @@ void Session::buildSdp(resip::SdpContents &sdp, SdpDirection sdpDirection)
if (mUserAgent->mConfig[CONFIG_MULTIPLEXING].asBool())
media.addAttribute("rtcp-mux");
// Ask provider about specific information
// Ask provider about specific information - codecs are filled here
provider.updateSdpOffer(media, sdpDirection);
// Add ICE information

View File

@ -66,12 +66,13 @@ enum SessionInfo
SessionInfo_ReceivedRtp,
SessionInfo_ReceivedRtcp,
SessionInfo_LostRtp,
SessionInfo_DroppedRtp,
SessionInfo_Duration,
SessionInfo_Jitter,
SessionInfo_Rtt,
SessionInfo_BitrateSwitchCounter, // It is for AMR codecs only
SessionInfo_RemotePeer,
SessionInfo_SSRC
SessionInfo_SSRC,
};

View File

@ -245,3 +245,8 @@ std::string MediaStreamId::getFinishDescription() const
return oss.str();
}
std::ostream& operator << (std::ostream& output, const MediaStreamId& id)
{
return (output << id.toString());
}

View File

@ -87,4 +87,6 @@ struct MediaStreamId
std::string getFinishDescription() const;
};
std::ostream& operator << (std::ostream& output, const MediaStreamId& id);
#endif

View File

@ -119,7 +119,7 @@ std::string StringHelper::toHex(unsigned int value)
std::string StringHelper::toHex(const void *ptr)
{
std::ostringstream oss;
oss << std::hex << ptr;
oss << std::fixed << std::setw(8) << std::setfill('0') << std::hex << ptr;
return oss.str();
}

View File

@ -11,7 +11,8 @@ set (CMAKE_POSITION_INDEPENDENT_CODE ON)
set (USE_AMR_CODEC OFF CACHE BOOL "Use AMR codec. Requires libraries.")
set (USE_EVS_CODEC OFF CACHE BOOL "Use EVS codec." )
set (USE_OPUS_CODEC OFF CACHE BOOL "Use Opus codec." )
set (USE_SEVANA_LIB OFF CACHE BOOL "Build with Sevana libraries" )
set (USE_PVQA_LIB OFF CACHE BOOL "Build with Sevana PVQA library" )
set (USE_AQUA_LIB OFF CACHE BOOL "Build with Sevana AQuA library" )
set (SOURCES
MT_Statistics.cpp

View File

@ -402,6 +402,7 @@ PCodec OpusCodec::OpusFactory::create()
result->applyParams(mParams);
PCodec c(result);
mCodecList.push_back(c);
return c;
}
@ -534,7 +535,7 @@ int OpusCodec::plc(int lostFrames, void* output, int outputCapacity)
#define ILBC_CODEC_NAME "ILBC"
IlbcCodec::IlbcCodec(int packetTime)
:mPacketTime(packetTime)
:mPacketTime(packetTime), mEncoderCtx(nullptr), mDecoderCtx(nullptr)
{
WebRtcIlbcfix_EncoderCreate(&mEncoderCtx);
WebRtcIlbcfix_DecoderCreate(&mDecoderCtx);

View File

@ -12,6 +12,7 @@
#include "../helper/HL_Log.h"
#include "../audio/Audio_Interface.h"
#include "../audio/Audio_Resampler.h"
#include <cmath>
#if !defined(TARGET_ANDROID) && !defined(TARGET_OPENWRT) && !defined(TARGET_WIN) && !defined(TARGET_RPI) && defined(USE_AMR_CODEC)
# include "MT_AmrCodec.h"
@ -26,7 +27,7 @@
using namespace MT;
// ----------------- RtpBuffer::Packet --------------
RtpBuffer::Packet::Packet(std::shared_ptr<RTPPacket> packet, int timelength, int rate)
RtpBuffer::Packet::Packet(const std::shared_ptr<RTPPacket>& packet, int timelength, int rate)
:mRtp(packet), mTimelength(timelength), mRate(rate)
{
}
@ -120,9 +121,8 @@ bool RtpBuffer::add(std::shared_ptr<jrtplib::RTPPacket> packet, int timelength,
// New sequence number
unsigned newSeqno = packet->GetExtendedSequenceNumber();
for (PacketList::iterator iter = mPacketList.begin(); iter != mPacketList.end(); iter++)
for (Packet& p: mPacketList)
{
Packet& p = *iter;
unsigned seqno = p.rtp()->GetExtendedSequenceNumber();
if (seqno == newSeqno)
@ -138,6 +138,7 @@ bool RtpBuffer::add(std::shared_ptr<jrtplib::RTPPacket> packet, int timelength,
minno = seqno;
}
// Get amount of available audio (in milliseconds) in jitter buffer
int available = findTimelength();
if (newSeqno > minno || (available < mHigh))
@ -188,6 +189,9 @@ RtpBuffer::FetchResult RtpBuffer::fetch(ResultList& rl)
// Erase from packet list
mPacketList.erase(mPacketList.begin());
// Increase number in statistics
mStat.mPacketDropped++;
}
if (total < mLow)
@ -351,7 +355,7 @@ AudioReceiver::~AudioReceiver()
}
bool AudioReceiver::add(std::shared_ptr<jrtplib::RTPPacket> p, Codec** codec)
bool AudioReceiver::add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec)
{
// Increase codec counter
mStat.mCodecCount[p->GetPayloadType()]++;
@ -373,20 +377,20 @@ bool AudioReceiver::add(std::shared_ptr<jrtplib::RTPPacket> p, Codec** codec)
codecIter->second = mCodecList.codecAt(codecIndex).create();
}
// Return pointer to codec if needed
// Return pointer to codec if needed.get()
if (codec)
*codec = codecIter->second.get();
if (mStat.mCodecName.empty())
mStat.mCodecName = codecIter->second.get()->name();
mStat.mCodecName = codecIter->second->name();
// Estimate time length
int timelen = 0, payloadLength = p->GetPayloadLength(), ptype = p->GetPayloadType();
int time_length = 0, payloadLength = p->GetPayloadLength(), ptype = p->GetPayloadType();
if (!codecIter->second->rtpLength())
timelen = codecIter->second->frameTime();
time_length = codecIter->second->frameTime();
else
timelen = int(double(payloadLength) / codecIter->second->rtpLength() * codecIter->second->frameTime() + 0.5);
time_length = lround(double(payloadLength) / codecIter->second->rtpLength() * codecIter->second->frameTime());
// Process jitter
mJitterStats.process(p.get(), codecIter->second->samplerate());
@ -394,19 +398,19 @@ bool AudioReceiver::add(std::shared_ptr<jrtplib::RTPPacket> p, Codec** codec)
// Check if packet is CNG
if (payloadLength >= 1 && payloadLength <= 6 && (ptype == 0 || ptype == 8))
timelen = mLastPacketTimeLength ? mLastPacketTimeLength : 20;
time_length = mLastPacketTimeLength ? mLastPacketTimeLength : 20;
else
// Check if packet is too short from time length side
if (timelen < 2)
if (time_length < 2)
{
// It will cause statistics to report about bad RTP packet
// I have to replay last packet payload here to avoid report about lost packet
mBuffer.add(p, timelen, codecIter->second->samplerate());
mBuffer.add(p, time_length, codecIter->second->samplerate());
return false;
}
// Queue packet to buffer
return mBuffer.add(p, timelen, codecIter->second->samplerate());
return mBuffer.add(p, time_length, codecIter->second->samplerate());
}
void AudioReceiver::processDecoded(Audio::DataWindow& output, int options)

View File

@ -45,7 +45,7 @@ namespace MT
class Packet
{
public:
Packet(std::shared_ptr<RTPPacket> packet, int timelen, int rate);
Packet(const std::shared_ptr<RTPPacket>& packet, int timelen, int rate);
std::shared_ptr<RTPPacket> rtp() const;
int timelength() const;
int rate() const;
@ -109,7 +109,7 @@ namespace MT
// 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).
bool add(std::shared_ptr<jrtplib::RTPPacket> p, Codec** codec = nullptr);
bool add(const std::shared_ptr<jrtplib::RTPPacket>& p, Codec** codec = nullptr);
// Returns false when there is no rtp data from jitter
enum DecodeOptions
@ -178,6 +178,7 @@ namespace MT
void initPvqa();
void updatePvqa(const void* data, int size);
float calculatePvqaMos(int rate, std::string& report);
std::shared_ptr<Audio::DataWindow> mPvqaBuffer;
#endif

View File

@ -110,6 +110,7 @@ void AudioStream::setDestination(const RtpPair<InternetAddress>& dest)
void AudioStream::setTransmittingCodec(Codec::Factory& factory, int payloadType)
{
ICELogInfo(<< "Selected codec " << factory.name() << "/" << factory.samplerate() << " for transmitting");
Lock l(mMutex);
mTransmittingCodec = factory.create();
mTransmittingPayloadType = payloadType;
@ -145,8 +146,10 @@ void AudioStream::addData(const void* buffer, int bytes)
{
Lock l(mMutex);
codec = mTransmittingCodec.get();
if (!codec)
if (nullptr == codec) {
// ICELogDebug(<< "No transmitting codec selected.");
return;
}
}
// Resample
@ -202,7 +205,7 @@ void AudioStream::addData(const void* buffer, int bytes)
int packetTime = mPacketTime ? mPacketTime : codec->frameTime();
// Make stereo version if required
for (int i=0; i<mCapturedAudio.filled() / mTransmittingCodec->pcmLength(); i++)
for (int i=0; i<mCapturedAudio.filled() / codec->pcmLength(); i++)
{
if (mSendingDump)
mSendingDump->write((const char*)mCapturedAudio.data() + codec->pcmLength() * i, codec->pcmLength());
@ -230,7 +233,8 @@ void AudioStream::addData(const void* buffer, int bytes)
}
}
}
mCapturedAudio.erase(processed);
if (processed > 0)
mCapturedAudio.erase(processed);
}
void AudioStream::copyDataTo(Audio::Mixer& mixer, int needed)

View File

@ -64,7 +64,7 @@ namespace MT
Audio::DataWindow mStereoCapturedAudio;
char mIncomingPcmBuffer[AUDIO_MIC_BUFFER_SIZE]; // Temporary buffer to allow reading from file
char mResampleBuffer[AUDIO_MIC_BUFFER_SIZE*8]; // Temporary buffer to hold data
char mStereoBuffer[AUDIO_MIC_BUFFER_SIZE*8]; // Temporary buffer to hold data converted to stereo
char mStereoBuffer[AUDIO_MIC_BUFFER_SIZE*16]; // Temporary buffer to hold data converted to stereo
PCodec mTransmittingCodec; // Current encoding codec
int mTransmittingPayloadType; // Payload type to mark outgoing packets
int mPacketTime; // Required packet time

View File

@ -96,7 +96,7 @@ CodecList::CodecList(const Settings& settings)
:mSettings(settings)
{
//mFactoryList.push_back(new OpusCodec::OpusFactory(16000, 1));
#if !defined(TARGET_ANDROID) && 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));
@ -126,8 +126,8 @@ CodecList::CodecList(const Settings& settings)
#endif
#endif
//mFactoryList.push_back(new IsacCodec::IsacFactory16K(mSettings.mIsac16KPayloadType));
//mFactoryList.push_back(new IlbcCodec::IlbcFactory(mSettings.mIlbc20PayloadType, mSettings.mIlbc30PayloadType));
mFactoryList.push_back(new IsacCodec::IsacFactory16K(mSettings.mIsac16KPayloadType));
mFactoryList.push_back(new IlbcCodec::IlbcFactory(mSettings.mIlbc20PayloadType, mSettings.mIlbc30PayloadType));
mFactoryList.push_back(new G711Codec::AlawFactory());
mFactoryList.push_back(new G711Codec::UlawFactory());
@ -231,7 +231,7 @@ void CodecListPriority::setupFrom(PVariantMap vmap)
{
Item item;
item.mCodecIndex = i;
item.mPriority = vmap->exists(i) ? vmap->at(i).asInt() : -1;
item.mPriority = vmap->exists(i) ? vmap->at(i).asInt() : 1000; // Non listed codecs will get lower priority
mPriorityList.push_back(item);
}

View File

@ -40,7 +40,7 @@ void JitterStatistics::process(jrtplib::RTPPacket* packet, int rate)
int64_t delta = receiveDelta - timestampDelta;
// Update max delta in milliseconds
double delta_in_seconds = fabs(double(delta) / rate);
float delta_in_seconds = float(fabs(double(delta) / rate));
if (delta_in_seconds > mMaxDelta)
mMaxDelta = delta_in_seconds;
@ -56,7 +56,7 @@ void JitterStatistics::process(jrtplib::RTPPacket* packet, int rate)
mReceiveTimestamp = timestamp;
// And mJitter are in seconds again
mJitter.process(mLastJitter.value() / rate);
mJitter.process(mLastJitter.value() / float(rate));
}
}
@ -67,7 +67,7 @@ void JitterStatistics::process(jrtplib::RTPPacket* packet, int rate)
Statistics::Statistics()
:mReceived(0), mSent(0), mReceivedRtp(0), mSentRtp(0),
mReceivedRtcp(0), mSentRtcp(0), mDuplicatedRtp(0), mOldRtp(0), mIllegalRtp(0),
mPacketLoss(0), mJitter(0.0), mAudioTime(0), mSsrc(0)
mPacketLoss(0), mJitter(0.0), mAudioTime(0), mSsrc(0), mPacketDropped(0)
{
mBitrateSwitchCounter = 0;
memset(mLoss, 0, sizeof mLoss);
@ -94,64 +94,11 @@ void Statistics::reset()
mIllegalRtp = 0;
mJitter = 0.0;
mAudioTime = 0;
mPacketDropped = 0;
memset(mLoss, 0, sizeof mLoss);
}
/*
double calculate_mos_g711(double ppl, double burstr, int version) {
double r;
double bpl = 8.47627; //mos = -4.23836 + 0.29873 * r - 0.00416744 * r * r + 0.0000209855 * r * r * r;
double mos;
if(ppl == 0 or burstr == 0) {
return 4.5;
}
if(ppl > 0.5) {
return 1;
}
switch(version) {
case 1:
case 2:
default:
// this mos is calculated for G.711 and PLC
bpl = 17.2647;
r = 93.2062077233 - 95.0 * (ppl*100/(ppl*100/burstr + bpl));
mos = 2.06405 + 0.031738 * r - 0.000356641 * r * r + 2.93143 * pow(10,-6) * r * r * r;
if(mos < 1)
return 1;
if(mos > 4.5)
return 4.5;
}
return mos;
}
double calculate_mos(double ppl, double burstr, int codec, unsigned int received) {
if(codec == PAYLOAD_G729) {
if(opt_mos_g729) {
if(received < 100) {
return 3.92;
}
return (double)mos_g729((long double)ppl, (long double)burstr);
} else {
if(received < 100) {
return 4.5;
}
return calculate_mos_g711(ppl, burstr, 2);
}
} else {
if(received < 100) {
return 4.5;
}
return calculate_mos_g711(ppl, burstr, 2);
}
}
*/
void Statistics::calculateBurstr(double* burstr, double* lossr) const
{
int lost = 0;
@ -230,8 +177,10 @@ Statistics& Statistics::operator += (const Statistics& src)
mDuplicatedRtp += src.mDuplicatedRtp;
mOldRtp += src.mOldRtp;
mPacketLoss += src.mPacketLoss;
mPacketDropped += src.mPacketDropped;
mAudioTime += src.mAudioTime;
for (auto codecStat: src.mCodecCount)
{
if (mCodecCount.find(codecStat.first) == mCodecCount.end())
@ -277,6 +226,8 @@ Statistics& Statistics::operator -= (const Statistics& src)
mDuplicatedRtp -= src.mDuplicatedRtp;
mOldRtp -= src.mOldRtp;
mPacketLoss -= src.mPacketLoss;
mPacketDropped -= src.mPacketDropped;
mAudioTime -= src.mAudioTime;
for (auto codecStat: src.mCodecCount)
{
@ -291,9 +242,10 @@ Statistics& Statistics::operator -= (const Statistics& src)
std::string Statistics::toShortString() const
{
std::ostringstream oss;
oss << "Received: " << mReceivedRtp
<< ", lost: " << mPacketLoss
<< ", sent: " << mSentRtp;
oss << "Received: " << mReceivedRtp
<< ", lost: " << mPacketLoss
<< ", dropped: " << mPacketDropped
<< ", sent: " << mSentRtp;
return oss.str();
}

View File

@ -130,7 +130,9 @@ public:
mDuplicatedRtp, // Number of received duplicated rtp packets
mOldRtp, // Number of late rtp packets
mPacketLoss, // Number of lost packets
mPacketDropped, // Number of dropped packets (due to time unsync when playing)
mIllegalRtp; // Number of rtp packets with bad payload type
int mLoss[128]; // Every item is number of loss of corresping length
size_t mAudioTime; // Decoded/found time in milliseconds
uint16_t mSsrc; // Last known SSRC ID in a RTP stream

View File

@ -34,6 +34,10 @@ set (ICE_STACK_SOURCES ICEAddress.cpp
ICETime.cpp
ICETransactionList.cpp)
if (TARGET_MUSL)
add_definitions(-DTARGET_MUSL)
endif()
add_definitions(-DUSE_NATIVE_SMARTPTR -D_WINSOCK_DEPRECATED_NO_WARNINGS)
add_library(ice_stack ${ICE_STACK_SOURCES})

View File

@ -24,6 +24,7 @@
# include <ws2tcpip.h>
#else
# include <netinet/in.h>
# if /*defined(TARGET_LINUX) || */ defined(TARGET_ANDROID)
# include <linux/in6.h>
# endif
@ -426,7 +427,7 @@ std::string NetworkAddress::ip() const
{
assert(mInitialized == true);
char resultbuf[128], ip6[128]; resultbuf[0] = 0;
char resultbuf[131], ip6[128]; resultbuf[0] = 0;
#ifdef TARGET_WIN
DWORD resultsize = sizeof(resultbuf);
@ -467,7 +468,7 @@ unsigned char* NetworkAddress::ipBytes() const
return (unsigned char*)mAddr6.sin6_addr.u.Byte;
#elif defined(TARGET_OSX) || defined(TARGET_IOS)
return (unsigned char*)&mAddr6.sin6_addr.__u6_addr.__u6_addr8;
#elif defined(TARGET_OPENWRT)
#elif defined(TARGET_OPENWRT) || defined(TARGET_MUSL)
return (unsigned char*)&mAddr6.sin6_addr.__in6_union.__s6_addr;
#elif defined(TARGET_LINUX)
return (unsigned char*)&mAddr6.sin6_addr.__in6_u.__u6_addr8;

View File

@ -41,6 +41,9 @@ LogLevel LogLevelHelper::parse(const std::string& t)
else
if (t == "special")
return LL_SPECIAL;
else
if (t == "media")
return LL_MEDIA;
throw std::runtime_error("Bad log param string value.");
}

View File

@ -164,12 +164,14 @@ extern Logger GLogger;
#define ICELogError(args_) ICELog(LL_ERROR, LOG_SUBSYSTEM, args_)
#define ICELogSpecial(args_) ICELog(LL_SPECIAL, LOG_SUBSYSTEM, args_)
/*
#define ICELogCritical2(args_) ICELog(LogLevel_Critical, LogSubsystem.c_str(), args_)
#define ICELogInfo2(args_) ICELog(LogLevel_Info, LogSubsystem.c_str(), args_)
#define ICELogDebug2(args_) ICELog(LogLevel_Debug, LogSubsystem.c_str(), args_)
#define ICELogMedia2(args_) ICELog(LogLevel_Media, LogSubsystem.c_str(), args_)
#define ICELogError2(args_) ICELog(LogLevel_Error, LogSubsystem.c_str(), args_)
#define ICELogSpecial2(args_) ICELog(LogLevel_Special, LogSubsystem.c_str(), args_)
*/
#define DEFINE_LOGGING(subsystem) \
static std::string LogSubsystem = subsystem; \

View File

@ -443,7 +443,7 @@ void NetworkHelper::NetworkToHost(const in6_addr& addr6, uint32_t* output)
output[i] = ntohl(((uint32_t*)addr6.u.Byte[0])[i]);
#elif defined(TARGET_IOS) || defined(TARGET_OSX)
output[i] = ntohl(addr6.__u6_addr.__u6_addr32[i]);
#elif defined(TARGET_OPENWRT)
#elif defined(TARGET_OPENWRT) || defined(TARGET_MUSL)
output[i] = ntohl(addr6.__in6_union.__s6_addr32[i]);
#elif defined(TARGET_LINUX)
output[i] = ntohl(addr6.__in6_u.__u6_addr32[i]);
@ -459,7 +459,7 @@ void NetworkHelper::HostToNetwork(const uint32_t* input, in6_addr& output)
((uint32_t*)&output.u.Byte[0])[i] = htonl(input[i]);
#elif defined(TARGET_OSX) || defined(TARGET_IOS)
output.__u6_addr.__u6_addr32[i] = htonl(input[i]);
#elif defined(TARGET_OPENWRT)
#elif defined(TARGET_OPENWRT) || defined(TARGET_MUSL)
output.__in6_union.__s6_addr32[i] = htonl(input[i]);
#elif defined(TARGET_LINUX)
output.__in6_u.__u6_addr32[i] = htonl(input[i]);

View File

@ -70,7 +70,11 @@ RecursiveMutex::RecursiveMutex()
#ifndef WIN32
int rc = pthread_mutexattr_init(&mMutexAttr);
#if defined(__linux__)
#if defined(PTHREAD_MUTEX_RECURSIVE_NP)
pthread_mutexattr_settype(&mMutexAttr, PTHREAD_MUTEX_RECURSIVE_NP);
#else
pthread_mutexattr_settype(&mMutexAttr, PTHREAD_MUTEX_RECURSIVE);
#endif
#else
pthread_mutexattr_settype(&mMutexAttr, PTHREAD_MUTEX_RECURSIVE);
#endif