diff options
Diffstat (limited to 'service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp')
-rw-r--r-- | service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp | 145 |
1 files changed, 100 insertions, 45 deletions
diff --git a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp index 55c2568b..4661ee0e 100644 --- a/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp +++ b/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp @@ -24,6 +24,9 @@ #include <AudioConfig.h> #include <stdlib.h> #include <algorithm> +#include <numeric> + +using namespace android::telephony::imsmedia; #define DEFAULT_PARAM (-1) #define DEFAULT_INACTIVITY_TIME_FOR_CALL_QUALITY (4) @@ -33,12 +36,17 @@ #define TIMER_INTERVAL (1000) // 1 sec #define STOP_TIMEOUT (1000) // 1 sec #define MESSAGE_PROCESSING_INTERVAL (20000) // 20 msec +#define MEDIA_DIRECTION_CONTAINS_RECEIVE(a) \ + ((a) == RtpConfig::MEDIA_DIRECTION_SEND_RECEIVE || \ + (a) == RtpConfig::MEDIA_DIRECTION_RECEIVE_ONLY) MediaQualityAnalyzer::MediaQualityAnalyzer() { mTimeStarted = 0; mCodecType = 0; mCodecAttribute = 0; + mIsRxRtpEnabled = false; + mIsRtcpEnabled = false; mCallback = nullptr; std::unique_ptr<RtcpXrEncoder> analyzer(new RtcpXrEncoder()); mRtcpXrEncoder = std::move(analyzer); @@ -66,10 +74,17 @@ MediaQualityAnalyzer::~MediaQualityAnalyzer() void MediaQualityAnalyzer::setConfig(AudioConfig* config) { + if (!isSameConfig(config)) + { + reset(); + } + + mIsRxRtpEnabled = MEDIA_DIRECTION_CONTAINS_RECEIVE(config->getMediaDirection()); mCodecType = config->getCodecType(); mCodecAttribute = config->getEvsParams().getEvsBandwidth(); - IMLOGD2("[setCodecType] type[%d], bandwidth[%d]", mCodecType, mCodecAttribute); + mCallQuality.setCodecType(convertAudioCodecType( + mCodecType, ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(mCodecAttribute))); if (mCodecType == AudioConfig::CODEC_AMR) { @@ -79,6 +94,20 @@ void MediaQualityAnalyzer::setConfig(AudioConfig* config) { mRtcpXrEncoder->setSamplingRate(16); } + + // Enable RTCP if both interval and direction is valid + bool isRtcpEnabled = (config->getRtcpConfig().getIntervalSec() > 0 && + config->getMediaDirection() != RtpConfig::MEDIA_DIRECTION_NO_FLOW); + + if (mIsRtcpEnabled != isRtcpEnabled) + { + mIsRtcpEnabled = isRtcpEnabled; + mCountRtcpInactivity = 0; + mNumRtcpPacketReceived = 0; + } + + IMLOGI4("[setConfig] codec type[%d], bandwidth[%d], rxRtp[%d], rtcp[%d]", mCodecType, + mCodecAttribute, mIsRxRtpEnabled, mIsRtcpEnabled); } void MediaQualityAnalyzer::setCallback(BaseSessionCallback* callback) @@ -111,16 +140,18 @@ void MediaQualityAnalyzer::setMediaQualityThreshold(const MediaQualityThreshold& bool MediaQualityAnalyzer::isSameConfig(AudioConfig* config) { return (mCodecType == config->getCodecType() && - mCodecAttribute == config->getEvsParams().getEvsBandwidth()); + mCodecAttribute == config->getEvsParams().getEvsBandwidth() && + mIsRxRtpEnabled == MEDIA_DIRECTION_CONTAINS_RECEIVE(config->getMediaDirection())); } void MediaQualityAnalyzer::start() { - IMLOGD0("[start]"); - mCallQuality.setCodecType(convertAudioCodecType( - mCodecType, ImsMediaAudioUtil::FindMaxEvsBandwidthFromRange(mCodecAttribute))); - mTimeStarted = ImsMediaTimer::GetTimeInMilliSeconds(); - StartThread(); + if (IsThreadStopped()) + { + IMLOGD0("[start]"); + mTimeStarted = ImsMediaTimer::GetTimeInMilliSeconds(); + StartThread(); + } } void MediaQualityAnalyzer::stop() @@ -155,12 +186,7 @@ void MediaQualityAnalyzer::collectInfo(const int32_t streamType, RtpPacket* pack } else if (streamType == kStreamRtpRx && packet != nullptr) { - if (mSSRC != DEFAULT_PARAM && mSSRC != packet->ssrc) - { - IMLOGW0("[collectInfo] ssrc changed"); - } - - // for call qualty report + // for call quality report mCallQuality.setNumRtpPacketsReceived(mCallQuality.getNumRtpPacketsReceived() + 1); mCallQualitySumRelativeJitter += packet->jitter; @@ -186,8 +212,8 @@ void MediaQualityAnalyzer::collectInfo(const int32_t streamType, RtpPacket* pack break; } - // for loss rate, jitter check - if (mSSRC == DEFAULT_PARAM) // stream is reset + // for jitter check + if (mSSRC != packet->ssrc) // stream is reset { mJitterRxPacket = std::abs(packet->jitter); // update rtcp-xr params @@ -396,7 +422,7 @@ void MediaQualityAnalyzer::processData(const int32_t timeCount) void MediaQualityAnalyzer::processMediaQuality() { // media quality rtp inactivity - if (mNumRxPacket == 0) + if (mNumRxPacket == 0 && mIsRxRtpEnabled) { mCountRtpInactivity += 1000; } @@ -408,7 +434,7 @@ void MediaQualityAnalyzer::processMediaQuality() } // media quality rtcp inactivity - if (mNumRtcpPacketReceived == 0) + if (mNumRtcpPacketReceived == 0 && mIsRtcpEnabled) { mCountRtcpInactivity += 1000; } @@ -424,7 +450,7 @@ void MediaQualityAnalyzer::processMediaQuality() if (mPacketLossDuration != 0 && !mListLostPacket.empty()) { - // calculate loss in duration + // counts received packets for the duration int32_t numReceivedPacketsInDuration = std::count_if(mListRxPacket.begin(), mListRxPacket.end(), [=](RtpPacket* packet) @@ -433,12 +459,21 @@ void MediaQualityAnalyzer::processMediaQuality() mPacketLossDuration); }); + // cumulates the number of lost packets for the duration + std::list<LostPacket*> listLostPacketInDuration; + std::copy_if(mListLostPacket.begin(), mListLostPacket.end(), + std::back_inserter(listLostPacketInDuration), + [=](LostPacket* packet) + { + return (ImsMediaTimer::GetTimeInMilliSeconds() - packet->markedTime <= + mPacketLossDuration); + }); + int32_t numLostPacketsInDuration = - std::count_if(mListLostPacket.begin(), mListLostPacket.end(), - [=](LostPacket* packet) + std::accumulate(begin(listLostPacketInDuration), end(listLostPacketInDuration), 0, + [=](int i, const LostPacket* packet) { - return (ImsMediaTimer::GetTimeInMilliSeconds() - packet->markedTime <= - mPacketLossDuration); + return packet->numLoss + i; }); if (numLostPacketsInDuration == 0 || numReceivedPacketsInDuration == 0) @@ -450,8 +485,8 @@ void MediaQualityAnalyzer::processMediaQuality() int32_t lossRate = numLostPacketsInDuration * 100 / (numReceivedPacketsInDuration + numLostPacketsInDuration); - IMLOGD3("[processData] mediaQualtyStatus lossRate[%d], received[%d], lost[%d]", - lossRate, numReceivedPacketsInDuration, numLostPacketsInDuration); + IMLOGD3("[processMediaQuality] lossRate[%d], received[%d], lost[%d]", lossRate, + numReceivedPacketsInDuration, numLostPacketsInDuration); mQualityStatus.setRtpPacketLossRate(lossRate); } } @@ -460,6 +495,27 @@ void MediaQualityAnalyzer::processMediaQuality() mQualityStatus.setRtpPacketLossRate(0); } + bool shouldNotify = false; + + // check jitter notification + if (!mJitterThreshold.empty() && mIsRxRtpEnabled) + { + if (mJitterChecker.checkNotifiable(mJitterThreshold, mQualityStatus.getRtpJitterMillis())) + { + shouldNotify = true; + } + } + + // check packet loss notification + if (!mPacketLossThreshold.empty() && mIsRxRtpEnabled) + { + if (mPacketLossChecker.checkNotifiable( + mPacketLossThreshold, mQualityStatus.getRtpPacketLossRate())) + { + shouldNotify = true; + } + } + IMLOGD_PACKET4(IM_PACKET_LOG_RTP, "[processMediaQuality] rtpInactivity[%d], rtcpInactivity[%d], lossRate[%d], " "jitter[%d]", @@ -474,7 +530,7 @@ void MediaQualityAnalyzer::processMediaQuality() return; } - if (!mCurrentRtpInactivityTimes.empty()) + if (!mCurrentRtpInactivityTimes.empty() && mIsRxRtpEnabled) { std::vector<int32_t>::iterator rtpIter = std::find_if(mCurrentRtpInactivityTimes.begin(), mCurrentRtpInactivityTimes.end(), @@ -492,32 +548,16 @@ void MediaQualityAnalyzer::processMediaQuality() } } - if (mRtcpInactivityTime != 0 && mCountRtcpInactivity == mRtcpInactivityTime) + if (mRtcpInactivityTime != 0 && mCountRtcpInactivity == mRtcpInactivityTime && mIsRtcpEnabled) { notifyMediaQualityStatus(); mCountRtcpInactivity = 0; return; } - // check jitter notification - if (!mJitterThreshold.empty()) + if (shouldNotify) { - if (mJitterChecker.checkNotifiable(mJitterThreshold, mQualityStatus.getRtpJitterMillis())) - { - notifyMediaQualityStatus(); - return; - } - } - - // check packet loss notification - if (!mPacketLossThreshold.empty()) - { - if (mPacketLossChecker.checkNotifiable( - mPacketLossThreshold, mQualityStatus.getRtpPacketLossRate())) - { - notifyMediaQualityStatus(); - return; - } + notifyMediaQualityStatus(); } } @@ -585,7 +625,11 @@ uint32_t MediaQualityAnalyzer::getTxPacketSize() uint32_t MediaQualityAnalyzer::getLostPacketSize() { - return mListLostPacket.size(); + return std::accumulate(begin(mListLostPacket), end(mListLostPacket), 0, + [](int i, const LostPacket* packet) + { + return packet->numLoss + i; + }); } void MediaQualityAnalyzer::SendEvent(uint32_t event, uint64_t paramA, uint64_t paramB) @@ -740,6 +784,17 @@ void MediaQualityAnalyzer::reset() mNumRxPacket = 0; mNumLostPacket = 0; mJitterRxPacket = 0.0; + + // rtp and rtcp inactivity + mCountRtpInactivity = 0; + mCountRtcpInactivity = 0; + mNumRtcpPacketReceived = 0; + + // reset the status + mQualityStatus = MediaQualityStatus(); + + mPacketLossChecker.initialize(mRtpHysteresisTime); + mJitterChecker.initialize(mRtpHysteresisTime); } void MediaQualityAnalyzer::clearPacketList(std::list<RtpPacket*>& list, const int32_t seq) |