Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
2fa4d0c3e6
|
|
@ -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()
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -87,4 +87,6 @@ struct MediaStreamId
|
|||
std::string getFinishDescription() const;
|
||||
};
|
||||
|
||||
std::ostream& operator << (std::ostream& output, const MediaStreamId& id);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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})
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; \
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue