diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a5f41f86..229bcf51 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,7 +1,7 @@ project(rtphone) cmake_minimum_required(VERSION 3.0) - + macro(configure_msvc_runtime) if(MSVC) # Default to statically-linked runtime. @@ -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() diff --git a/src/engine/agent/Agent_Impl.cpp b/src/engine/agent/Agent_Impl.cpp index 3bd8091b..e52e9819 100644 --- a/src/engine/agent/Agent_Impl.cpp +++ b/src/engine/agent/Agent_Impl.cpp @@ -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 #if defined(USE_PVQA_LIBRARY) @@ -208,10 +209,13 @@ void AgentImpl::processStart(JsonCpp::Value& /*request*/, JsonCpp::Value &answer PVariantMap priorityConfig = std::make_shared(); MT::CodecList& cl = mTerminal->codeclist(); for (int i=0; iat(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(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; @@ -951,4 +969,4 @@ void AgentImpl::closeAqua(int sessionId) mAquaMap.erase(aquaIter); } } -#endif \ No newline at end of file +#endif diff --git a/src/engine/audio/Audio_Resampler.cpp b/src/engine/audio/Audio_Resampler.cpp index 59a7f474..6794a33b 100644 --- a/src/engine/audio/Audio_Resampler.cpp +++ b/src/engine/audio/Audio_Resampler.cpp @@ -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 diff --git a/src/engine/config.h b/src/engine/config.h index a187f262..b1390648 100644 --- a/src/engine/config.h +++ b/src/engine/config.h @@ -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 diff --git a/src/engine/endpoint/EP_AudioProvider.cpp b/src/engine/endpoint/EP_AudioProvider.cpp index cfbb3793..334dc624 100644 --- a/src/engine/endpoint/EP_AudioProvider.cpp +++ b/src/engine/endpoint/EP_AudioProvider.cpp @@ -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(mActiveStream.get())->transmittingCodec(); dynamic_cast(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); + +} \ No newline at end of file diff --git a/src/engine/endpoint/EP_AudioProvider.h b/src/engine/endpoint/EP_AudioProvider.h index 5baddea3..b5968cbd 100644 --- a/src/engine/endpoint/EP_AudioProvider.h +++ b/src/engine/endpoint/EP_AudioProvider.h @@ -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& p4, const RtpPair& p6); + void setSocket(const RtpPair& p4, const RtpPair& p6) override; // Called by user agent to get media socket for this provider - RtpPair& socket(int family); + RtpPair& 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); - - void setState(unsigned state); - unsigned state(); - MT::Statistics getStatistics(); + bool processSdpOffer(const resip::SdpContents::Session::Medium& media, SdpDirection sdpDirection) override; + + + 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 diff --git a/src/engine/endpoint/EP_Session.cpp b/src/engine/endpoint/EP_Session.cpp index aa53ad57..af8792bc 100644 --- a/src/engine/endpoint/EP_Session.cpp +++ b/src/engine/endpoint/EP_Session.cpp @@ -478,6 +478,7 @@ void Session::getSessionInfo(Session::InfoOptions options, VariantMap& info) info[SessionInfo_ReceivedRtp] = static_cast(stat.mReceivedRtp); info[SessionInfo_ReceivedRtcp] = static_cast(stat.mReceivedRtcp); info[SessionInfo_LostRtp] = static_cast(stat.mPacketLoss); + info[SessionInfo_DroppedRtp] = static_cast(stat.mPacketDropped); info[SessionInfo_SentRtp] = static_cast(stat.mSentRtp); info[SessionInfo_SentRtcp] = static_cast(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 diff --git a/src/engine/endpoint/EP_Session.h b/src/engine/endpoint/EP_Session.h index e2f4d00a..0a45ecf2 100644 --- a/src/engine/endpoint/EP_Session.h +++ b/src/engine/endpoint/EP_Session.h @@ -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, }; diff --git a/src/engine/helper/HL_Rtp.cpp b/src/engine/helper/HL_Rtp.cpp index c4af449e..b7594daf 100644 --- a/src/engine/helper/HL_Rtp.cpp +++ b/src/engine/helper/HL_Rtp.cpp @@ -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()); +} + diff --git a/src/engine/helper/HL_Rtp.h b/src/engine/helper/HL_Rtp.h index 0e34b42c..9d6c81d9 100644 --- a/src/engine/helper/HL_Rtp.h +++ b/src/engine/helper/HL_Rtp.h @@ -87,4 +87,6 @@ struct MediaStreamId std::string getFinishDescription() const; }; +std::ostream& operator << (std::ostream& output, const MediaStreamId& id); + #endif diff --git a/src/engine/helper/HL_String.cpp b/src/engine/helper/HL_String.cpp index 6f43f663..dd0f0472 100644 --- a/src/engine/helper/HL_String.cpp +++ b/src/engine/helper/HL_String.cpp @@ -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(); } diff --git a/src/engine/media/CMakeLists.txt b/src/engine/media/CMakeLists.txt index 3ecd61c3..967e5bf4 100644 --- a/src/engine/media/CMakeLists.txt +++ b/src/engine/media/CMakeLists.txt @@ -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 diff --git a/src/engine/media/MT_AudioCodec.cpp b/src/engine/media/MT_AudioCodec.cpp index 0fd46d70..bb1ba00a 100644 --- a/src/engine/media/MT_AudioCodec.cpp +++ b/src/engine/media/MT_AudioCodec.cpp @@ -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); diff --git a/src/engine/media/MT_AudioReceiver.cpp b/src/engine/media/MT_AudioReceiver.cpp index 5b749f28..a40c63df 100644 --- a/src/engine/media/MT_AudioReceiver.cpp +++ b/src/engine/media/MT_AudioReceiver.cpp @@ -12,6 +12,7 @@ #include "../helper/HL_Log.h" #include "../audio/Audio_Interface.h" #include "../audio/Audio_Resampler.h" +#include #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 packet, int timelength, int rate) +RtpBuffer::Packet::Packet(const std::shared_ptr& packet, int timelength, int rate) :mRtp(packet), mTimelength(timelength), mRate(rate) { } @@ -120,9 +121,8 @@ bool RtpBuffer::add(std::shared_ptr 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 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 p, Codec** codec) +bool AudioReceiver::add(const std::shared_ptr& p, Codec** codec) { // Increase codec counter mStat.mCodecCount[p->GetPayloadType()]++; @@ -373,20 +377,20 @@ bool AudioReceiver::add(std::shared_ptr 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 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) diff --git a/src/engine/media/MT_AudioReceiver.h b/src/engine/media/MT_AudioReceiver.h index 730935d4..1f1cece3 100644 --- a/src/engine/media/MT_AudioReceiver.h +++ b/src/engine/media/MT_AudioReceiver.h @@ -45,7 +45,7 @@ namespace MT class Packet { public: - Packet(std::shared_ptr packet, int timelen, int rate); + Packet(const std::shared_ptr& packet, int timelen, int rate); std::shared_ptr 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 p, Codec** codec = nullptr); + bool add(const std::shared_ptr& 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 mPvqaBuffer; #endif diff --git a/src/engine/media/MT_AudioStream.cpp b/src/engine/media/MT_AudioStream.cpp index e6561463..3f14e31a 100644 --- a/src/engine/media/MT_AudioStream.cpp +++ b/src/engine/media/MT_AudioStream.cpp @@ -110,6 +110,7 @@ void AudioStream::setDestination(const RtpPair& 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; ipcmLength(); i++) + for (int i=0; ipcmLength(); 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) diff --git a/src/engine/media/MT_AudioStream.h b/src/engine/media/MT_AudioStream.h index 32b22e03..bb6a7eea 100644 --- a/src/engine/media/MT_AudioStream.h +++ b/src/engine/media/MT_AudioStream.h @@ -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 diff --git a/src/engine/media/MT_CodecList.cpp b/src/engine/media/MT_CodecList.cpp index 8f6d9d5c..e9adcc70 100644 --- a/src/engine/media/MT_CodecList.cpp +++ b/src/engine/media/MT_CodecList.cpp @@ -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); } diff --git a/src/engine/media/MT_Statistics.cpp b/src/engine/media/MT_Statistics.cpp index ae2a1dd6..aa0c3c9d 100644 --- a/src/engine/media/MT_Statistics.cpp +++ b/src/engine/media/MT_Statistics.cpp @@ -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(); } diff --git a/src/engine/media/MT_Statistics.h b/src/engine/media/MT_Statistics.h index c8ea709c..e7d10f08 100644 --- a/src/engine/media/MT_Statistics.h +++ b/src/engine/media/MT_Statistics.h @@ -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 diff --git a/src/engine/media/MT_Stream.h b/src/engine/media/MT_Stream.h index 0e136d6a..e517de9f 100644 --- a/src/engine/media/MT_Stream.h +++ b/src/engine/media/MT_Stream.h @@ -52,7 +52,7 @@ namespace MT virtual void setDestination(const RtpPair& dest); - virtual void setTransmittingCodec(Codec::Factory& factory, int payloadType) = 0; + virtual void setTransmittingCodec(Codec::Factory& factory, int payloadType) = 0; virtual void dataArrived(PDatagramSocket s, const void* buffer, int length, InternetAddress& source) = 0; diff --git a/src/libs/ice/CMakeLists.txt b/src/libs/ice/CMakeLists.txt index 9e37b3d1..c53b85b1 100644 --- a/src/libs/ice/CMakeLists.txt +++ b/src/libs/ice/CMakeLists.txt @@ -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}) diff --git a/src/libs/ice/ICEAddress.cpp b/src/libs/ice/ICEAddress.cpp index 56cb3b6a..f8633f69 100644 --- a/src/libs/ice/ICEAddress.cpp +++ b/src/libs/ice/ICEAddress.cpp @@ -24,6 +24,7 @@ # include #else # include + # if /*defined(TARGET_LINUX) || */ defined(TARGET_ANDROID) # include # 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); @@ -464,15 +465,15 @@ unsigned char* NetworkAddress::ipBytes() const #endif case AF_INET6: #ifdef TARGET_WIN - 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) - return (unsigned char*)&mAddr6.sin6_addr.__in6_union.__s6_addr; -#elif defined(TARGET_LINUX) - return (unsigned char*)&mAddr6.sin6_addr.__in6_u.__u6_addr8; -#elif defined(TARGET_ANDROID) - return (unsigned char*)&mAddr6.sin6_addr.in6_u.u6_addr8; + 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) || 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; +#elif defined(TARGET_ANDROID) + return (unsigned char*)&mAddr6.sin6_addr.in6_u.u6_addr8; #endif } assert(0); diff --git a/src/libs/ice/ICELog.cpp b/src/libs/ice/ICELog.cpp index 34dc5114..0e8a36a8 100644 --- a/src/libs/ice/ICELog.cpp +++ b/src/libs/ice/ICELog.cpp @@ -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."); } diff --git a/src/libs/ice/ICELog.h b/src/libs/ice/ICELog.h index 15d90bb8..6e120fa4 100644 --- a/src/libs/ice/ICELog.h +++ b/src/libs/ice/ICELog.h @@ -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; \ diff --git a/src/libs/ice/ICENetworkHelper.cpp b/src/libs/ice/ICENetworkHelper.cpp index 6674ba3a..398ab365 100644 --- a/src/libs/ice/ICENetworkHelper.cpp +++ b/src/libs/ice/ICENetworkHelper.cpp @@ -434,40 +434,40 @@ bool NetworkHelper::hasIPv6() const if (item.family() == AF_INET6 && (item.isLAN() || item.isPublic())) return true; return false; -} - -void NetworkHelper::NetworkToHost(const in6_addr& addr6, uint32_t* output) -{ - for (int i=0; i<4; i++) -#if defined(TARGET_WIN) - 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) - output[i] = ntohl(addr6.__in6_union.__s6_addr32[i]); -#elif defined(TARGET_LINUX) - output[i] = ntohl(addr6.__in6_u.__u6_addr32[i]); -#elif defined(TARGET_ANDROID) - output[i] = ntohl(addr6.in6_u.u6_addr32[i]); -#endif -} - -void NetworkHelper::HostToNetwork(const uint32_t* input, in6_addr& output) -{ - for (int i=0; i<4; i++) -#if defined(TARGET_WIN) - ((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) - output.__in6_union.__s6_addr32[i] = htonl(input[i]); -#elif defined(TARGET_LINUX) - output.__in6_u.__u6_addr32[i] = htonl(input[i]); -#elif defined(TARGET_ANDROID) - output.in6_u.u6_addr32[i] = htonl(input[i]); -#endif -} - +} + +void NetworkHelper::NetworkToHost(const in6_addr& addr6, uint32_t* output) +{ + for (int i=0; i<4; i++) +#if defined(TARGET_WIN) + 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) || 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]); +#elif defined(TARGET_ANDROID) + output[i] = ntohl(addr6.in6_u.u6_addr32[i]); +#endif +} + +void NetworkHelper::HostToNetwork(const uint32_t* input, in6_addr& output) +{ + for (int i=0; i<4; i++) +#if defined(TARGET_WIN) + ((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) || 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]); +#elif defined(TARGET_ANDROID) + output.in6_u.u6_addr32[i] = htonl(input[i]); +#endif +} + NetworkHelper* NetworkHelper::mInstance = NULL; Mutex NetworkHelper::mGuard; diff --git a/src/libs/resiprocate/rutil/RecursiveMutex.cxx b/src/libs/resiprocate/rutil/RecursiveMutex.cxx index 9906f452..2fa0a06b 100644 --- a/src/libs/resiprocate/rutil/RecursiveMutex.cxx +++ b/src/libs/resiprocate/rutil/RecursiveMutex.cxx @@ -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