summaryrefslogtreecommitdiff
path: root/service/src/com/android/telephony/imsmedia/lib/libimsmedia/core/audio/MediaQualityAnalyzer.cpp
diff options
context:
space:
mode:
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.cpp145
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)