mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 1348657 - implement framesEncoded, pliCount, nackCount and firCount for webrtc stats r=jib,smaug
MozReview-Commit-ID: E873mbcrlLL --HG-- extra : rebase_source : ca6f5d7ab0490948aaed1ae793ed5906149b7236
This commit is contained in:
parent
92eea71fe1
commit
af67a2fb4c
@ -14,24 +14,24 @@ var statsExpectedByType = {
|
||||
"inbound-rtp": {
|
||||
expected: ["id", "timestamp", "type", "ssrc", "isRemote", "mediaType",
|
||||
"packetsReceived", "packetsLost", "bytesReceived", "jitter",],
|
||||
optional: ["mozRtt", "remoteId",],
|
||||
optional: ["mozRtt", "remoteId", "nackCount",],
|
||||
videoOnly: ["discardedPackets", "framerateStdDev", "framerateMean",
|
||||
"bitrateMean", "bitrateStdDev",],
|
||||
"bitrateMean", "bitrateStdDev", "firCount", "pliCount",],
|
||||
unimplemented: ["mediaTrackId", "transportId", "codecId", "framesDecoded",
|
||||
"packetsDiscarded", "associateStatsId", "firCount", "pliCount",
|
||||
"nackCount", "sliCount", "qpSum", "packetsRepaired", "fractionLost",
|
||||
"packetsDiscarded", "associateStatsId",
|
||||
"sliCount", "qpSum", "packetsRepaired", "fractionLost",
|
||||
"burstPacketsLost", "burstLossCount", "burstDiscardCount",
|
||||
"gapDiscardRate", "gapLossRate",],
|
||||
},
|
||||
"outbound-rtp": {
|
||||
expected: ["id", "timestamp", "type", "ssrc", "isRemote", "mediaType",
|
||||
"packetsSent", "bytesSent", "remoteId",],
|
||||
optional: ["remoteId",],
|
||||
optional: ["remoteId", "nackCount",],
|
||||
videoOnly: ["droppedFrames", "bitrateMean", "bitrateStdDev",
|
||||
"framerateMean", "framerateStdDev",],
|
||||
"framerateMean", "framerateStdDev", "framesEncoded", "firCount",
|
||||
"pliCount",],
|
||||
unimplemented: ["mediaTrackId", "transportId", "codecId",
|
||||
"framesEncoded", "firCount", "pliCount", "nackCount", "sliCount",
|
||||
"qpSum", "roundTripTime", "targetBitrate",],
|
||||
"sliCount", "qpSum", "roundTripTime", "targetBitrate",],
|
||||
},
|
||||
"codec": { skip: true },
|
||||
"peer-connection": { skip: true },
|
||||
@ -136,6 +136,22 @@ var pedanticChecks = report => {
|
||||
"remote object has local object as it's own remote object.");
|
||||
}
|
||||
|
||||
// nackCount
|
||||
if (!stat.inner.isRemote) {
|
||||
ok(stat.nackCount >= 0, stat.type + ".nackCount is sane.");
|
||||
}
|
||||
|
||||
if (!stat.inner.isRemote && stat.inner.mediaType == "video") {
|
||||
// firCount
|
||||
ok(stat.firCount >= 0 && stat.firCount < 100,
|
||||
stat.type + ".firCount is a sane number for a short test. value="
|
||||
+ stat.firCount);
|
||||
|
||||
// pliCount
|
||||
ok(stat.pliCount >= 0 && stat.pliCount < 100,
|
||||
stat.type + ".pliCount is a sane number for a short test. value="
|
||||
+ stat.pliCount);
|
||||
}
|
||||
}
|
||||
|
||||
if (stat.type == "inbound-rtp") {
|
||||
@ -194,7 +210,7 @@ var pedanticChecks = report => {
|
||||
// Local video only stats
|
||||
//
|
||||
if (stat.inner.isRemote || stat.inner.mediaType != "video") {
|
||||
expectations.videoOnly.forEach(field => {
|
||||
expectations.localVideoOnly.forEach(field => {
|
||||
if (stat.inner.isRemote) {
|
||||
ok(stat[field] === undefined, stat.type + " does not have field "
|
||||
+ field + " when isRemote is true");
|
||||
@ -204,8 +220,8 @@ var pedanticChecks = report => {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
expectations.videoOnly.forEach(field => {
|
||||
ok(stat[field] !== undefined, stat.type + " has field " + field
|
||||
expectations.localVideoOnly.forEach(field => {
|
||||
ok(stat.inner[field] !== undefined, stat.type + " has field " + field
|
||||
+ " when mediaType is video");
|
||||
});
|
||||
// discardedPackets
|
||||
@ -272,7 +288,7 @@ var pedanticChecks = report => {
|
||||
// Local video only stats
|
||||
//
|
||||
if (stat.inner.isRemote || stat.inner.mediaType != "video") {
|
||||
expectations.videoOnly.forEach(field => {
|
||||
expectations.localVideoOnly.forEach(field => {
|
||||
if (stat.inner.isRemote) {
|
||||
ok(stat[field] === undefined, stat.type + " does not have field "
|
||||
+ field + " when isRemote is true");
|
||||
@ -282,9 +298,9 @@ var pedanticChecks = report => {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
expectations.videoOnly.forEach(field => {
|
||||
ok(stat[field] !== undefined, stat.type + " has field " + field
|
||||
+ " when mediaType is video");
|
||||
expectations.localVideoOnly.forEach(field => {
|
||||
ok(stat.inner[field] !== undefined, stat.type + " has field " + field
|
||||
+ " when mediaType is video and isRemote is false");
|
||||
});
|
||||
|
||||
// bitrateMean
|
||||
@ -323,7 +339,11 @@ var pedanticChecks = report => {
|
||||
ok(stat.droppedFrames >= 0,
|
||||
stat.type + ".droppedFrames is not negative. value="
|
||||
+ stat.droppedFrames);
|
||||
}
|
||||
|
||||
// framesEncoded
|
||||
ok(stat.framesEncoded >= 0 && stat.framesEncoded < 100000, stat.type
|
||||
+ ".framesEncoded is a sane number for a short test. value="
|
||||
+ stat.framesEncoded);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -381,6 +381,10 @@ struct ParamTraits<mozilla::dom::RTCOutboundRTPStreamStats>
|
||||
WriteParam(aMsg, aParam.mDroppedFrames);
|
||||
WriteParam(aMsg, aParam.mPacketsSent);
|
||||
WriteParam(aMsg, aParam.mTargetBitrate);
|
||||
WriteParam(aMsg, aParam.mFramesEncoded);
|
||||
WriteParam(aMsg, aParam.mFirCount);
|
||||
WriteParam(aMsg, aParam.mNackCount);
|
||||
WriteParam(aMsg, aParam.mPliCount);
|
||||
WriteRTCRTPStreamStats(aMsg, aParam);
|
||||
WriteRTCStats(aMsg, aParam);
|
||||
}
|
||||
@ -391,6 +395,10 @@ struct ParamTraits<mozilla::dom::RTCOutboundRTPStreamStats>
|
||||
!ReadParam(aMsg, aIter, &(aResult->mDroppedFrames)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mPacketsSent)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mTargetBitrate)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mFramesEncoded)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mFirCount)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mNackCount)) ||
|
||||
!ReadParam(aMsg, aIter, &(aResult->mPliCount)) ||
|
||||
!ReadRTCRTPStreamStats(aMsg, aIter, aResult) ||
|
||||
!ReadRTCStats(aMsg, aIter, aResult)) {
|
||||
return false;
|
||||
|
@ -34,11 +34,17 @@ dictionary RTCRTPStreamStats : RTCStats {
|
||||
DOMString transportId;
|
||||
DOMString codecId;
|
||||
|
||||
// Video encoder/decoder measurements (absent for rtcp)
|
||||
// Video encoder/decoder measurements, not present in RTCP case
|
||||
double bitrateMean;
|
||||
double bitrateStdDev;
|
||||
double framerateMean;
|
||||
double framerateStdDev;
|
||||
|
||||
// Local only measurements, RTCP related but not communicated via RTCP. Not
|
||||
// present in RTCP case.
|
||||
unsigned long firCount;
|
||||
unsigned long pliCount;
|
||||
unsigned long nackCount;
|
||||
};
|
||||
|
||||
dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats {
|
||||
@ -50,7 +56,7 @@ dictionary RTCInboundRTPStreamStats : RTCRTPStreamStats {
|
||||
long mozJitterBufferDelay;
|
||||
long mozRtt;
|
||||
|
||||
// Video decoder measurement (absent in rtcp case)
|
||||
// Video decoder measurement, not present in RTCP case
|
||||
unsigned long discardedPackets;
|
||||
};
|
||||
|
||||
@ -59,8 +65,9 @@ dictionary RTCOutboundRTPStreamStats : RTCRTPStreamStats {
|
||||
unsigned long long bytesSent;
|
||||
double targetBitrate; // config encoder bitrate target of this SSRC in bits/s
|
||||
|
||||
// Video encoder measurement (absent in rtcp case)
|
||||
// Video encoder measurements, not present in RTCP case
|
||||
unsigned long droppedFrames;
|
||||
unsigned long framesEncoded;
|
||||
};
|
||||
|
||||
dictionary RTCMediaStreamTrackStats : RTCStats {
|
||||
|
@ -165,6 +165,12 @@ bool WebrtcAudioConduit::SetLocalCNAME(const char* cname)
|
||||
return !mPtrRTP->SetRTCP_CNAME(mChannel, temp);
|
||||
}
|
||||
|
||||
bool WebrtcAudioConduit::GetPacketTypeStats(
|
||||
webrtc::RtcpPacketTypeCounter* aPacketCounts)
|
||||
{
|
||||
return !mPtrVoERTP_RTCP->GetRTCPPacketTypeCounters(mChannel, *aPacketCounts);
|
||||
}
|
||||
|
||||
bool WebrtcAudioConduit::GetAVStats(int32_t* jitterBufferDelayMs,
|
||||
int32_t* playoutBufferDelayMs,
|
||||
int32_t* avSyncOffsetMs) {
|
||||
|
@ -201,11 +201,16 @@ public:
|
||||
}
|
||||
bool GetRemoteSSRC(unsigned int* ssrc) override;
|
||||
bool SetLocalCNAME(const char* cname) override;
|
||||
|
||||
bool
|
||||
GetPacketTypeStats(webrtc::RtcpPacketTypeCounter* aPacketCounts) override;
|
||||
|
||||
bool GetVideoEncoderStats(double* framerateMean,
|
||||
double* framerateStdDev,
|
||||
double* bitrateMean,
|
||||
double* bitrateStdDev,
|
||||
uint32_t* droppedFrames) override
|
||||
uint32_t* droppedFrames,
|
||||
uint32_t* framesEncoded) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -251,11 +251,16 @@ public:
|
||||
/**
|
||||
* Functions returning stats needed by w3c stats model.
|
||||
*/
|
||||
|
||||
virtual bool
|
||||
GetPacketTypeStats(webrtc::RtcpPacketTypeCounter* aPacketCounts) = 0;
|
||||
|
||||
virtual bool GetVideoEncoderStats(double* framerateMean,
|
||||
double* framerateStdDev,
|
||||
double* bitrateMean,
|
||||
double* bitrateStdDev,
|
||||
uint32_t* droppedFrames) = 0;
|
||||
uint32_t* droppedFrames,
|
||||
uint32_t* framesEncoded) = 0;
|
||||
virtual bool GetVideoDecoderStats(double* framerateMean,
|
||||
double* framerateStdDev,
|
||||
double* bitrateMean,
|
||||
|
@ -120,12 +120,15 @@ WebrtcVideoConduit::SendStreamStatistics::Update(
|
||||
if (!aStats.substreams.empty()) {
|
||||
const webrtc::FrameCounts& fc =
|
||||
aStats.substreams.begin()->second.frame_counts;
|
||||
CSFLogVerbose(logTag, "%s: framerate: %u, bitrate: %u, dropped frames delta: %u",
|
||||
__FUNCTION__, aStats.encode_frame_rate, aStats.media_bitrate_bps,
|
||||
(mSentFrames - (fc.key_frames + fc.delta_frames)) - mDroppedFrames);
|
||||
mDroppedFrames = mSentFrames - (fc.key_frames + fc.delta_frames);
|
||||
mFramesEncoded = fc.key_frames + fc.delta_frames;
|
||||
CSFLogVerbose(logTag,
|
||||
"%s: framerate: %u, bitrate: %u, dropped frames delta: %u",
|
||||
__FUNCTION__, aStats.encode_frame_rate,
|
||||
aStats.media_bitrate_bps,
|
||||
mFramesDeliveredToEncoder - mFramesEncoded - mDroppedFrames);
|
||||
mDroppedFrames = mFramesDeliveredToEncoder - mFramesEncoded;
|
||||
} else {
|
||||
CSFLogVerbose(logTag, "%s aStats.substreams is empty", __FUNCTION__);
|
||||
CSFLogVerbose(logTag, "%s stats.substreams is empty", __FUNCTION__);
|
||||
}
|
||||
};
|
||||
|
||||
@ -211,11 +214,21 @@ WebrtcVideoConduit::WebrtcVideoConduit(RefPtr<WebRtcCallWrapper> aCall)
|
||||
CSFLogDebug(logTag, "StreamStats polling scheduled for VideoConduit: %p", aClosure);
|
||||
auto self = static_cast<WebrtcVideoConduit*>(aClosure);
|
||||
MutexAutoLock lock(self->mCodecMutex);
|
||||
MOZ_ASSERT(!self->mEngineTransmitting || !self->mEngineReceiving,
|
||||
"Video conduit is not both receiving and transmitting");
|
||||
if (self->mEngineTransmitting && self->mSendStream) {
|
||||
self->mSendStreamStats.Update(self->mSendStream->GetStats());
|
||||
const auto& stats = self->mSendStream->GetStats();
|
||||
self->mSendStreamStats.Update(stats);
|
||||
if (stats.substreams.empty()) {
|
||||
return;
|
||||
}
|
||||
self->mPacketCounts =
|
||||
stats.substreams.begin()->second.rtcp_packet_type_counts;
|
||||
}
|
||||
if (self->mEngineReceiving && self->mRecvStream) {
|
||||
self->mRecvStreamStats.Update(self->mRecvStream->GetStats());
|
||||
const auto& stats = self->mRecvStream->GetStats();
|
||||
self->mRecvStreamStats.Update(stats);
|
||||
self->mPacketCounts = stats.rtcp_packet_type_counts;
|
||||
}
|
||||
};
|
||||
mVideoStatsTimer->InitWithFuncCallback(
|
||||
@ -746,12 +759,27 @@ WebrtcVideoConduit::GetRemoteSSRC(unsigned int* ssrc)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebrtcVideoConduit::GetPacketTypeStats(
|
||||
webrtc::RtcpPacketTypeCounter* aPacketCounts)
|
||||
{
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
if ((!mEngineTransmitting || !mSendStream) // Not transmitting
|
||||
&& (!mEngineReceiving || !mRecvStream)) // And not receiving
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*aPacketCounts = mPacketCounts;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebrtcVideoConduit::GetVideoEncoderStats(double* framerateMean,
|
||||
double* framerateStdDev,
|
||||
double* bitrateMean,
|
||||
double* bitrateStdDev,
|
||||
uint32_t* droppedFrames)
|
||||
uint32_t* droppedFrames,
|
||||
uint32_t* framesEncoded)
|
||||
{
|
||||
{
|
||||
MutexAutoLock lock(mCodecMutex);
|
||||
@ -761,6 +789,7 @@ WebrtcVideoConduit::GetVideoEncoderStats(double* framerateMean,
|
||||
mSendStreamStats.GetVideoStreamStats(*framerateMean, *framerateStdDev,
|
||||
*bitrateMean, *bitrateStdDev);
|
||||
mSendStreamStats.DroppedFrames(*droppedFrames);
|
||||
*framesEncoded = mSendStreamStats.FramesEncoded();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1774,7 +1803,7 @@ WebrtcVideoConduit::SendVideoFrame(webrtc::VideoFrame& frame)
|
||||
}
|
||||
}
|
||||
|
||||
mSendStreamStats.SentFrame();
|
||||
mSendStreamStats.FrameDeliveredToEncoder();
|
||||
CSFLogDebug(logTag, "%s Inserted a frame", __FUNCTION__);
|
||||
return kMediaConduitNoError;
|
||||
}
|
||||
|
@ -297,15 +297,19 @@ public:
|
||||
|
||||
std::vector<unsigned int> GetLocalSSRCs() const override;
|
||||
bool SetLocalSSRCs(const std::vector<unsigned int> & ssrcs) override;
|
||||
|
||||
bool GetRemoteSSRC(unsigned int* ssrc) override;
|
||||
bool SetRemoteSSRC(unsigned int ssrc) override;
|
||||
bool SetLocalCNAME(const char* cname) override;
|
||||
|
||||
bool
|
||||
GetPacketTypeStats(webrtc::RtcpPacketTypeCounter* aPacketCounts) override;
|
||||
|
||||
bool GetVideoEncoderStats(double* framerateMean,
|
||||
double* framerateStdDev,
|
||||
double* bitrateMean,
|
||||
double* bitrateStdDev,
|
||||
uint32_t* droppedFrames) override;
|
||||
uint32_t* droppedFrames,
|
||||
uint32_t* framesEncoded) override;
|
||||
bool GetVideoDecoderStats(double* framerateMean,
|
||||
double* framerateStdDev,
|
||||
double* bitrateMean,
|
||||
@ -360,16 +364,21 @@ private:
|
||||
* @param aOutDroppedFrames: the number of dropped frames
|
||||
*/
|
||||
void DroppedFrames(uint32_t& aOutDroppedFrames) const;
|
||||
/**
|
||||
* Returns the number of frames that have been encoded so far
|
||||
*/
|
||||
uint32_t FramesEncoded() const {
|
||||
return mFramesEncoded;
|
||||
}
|
||||
void Update(const webrtc::VideoSendStream::Stats& aStats);
|
||||
/**
|
||||
* Call once for every frame delivered for encoding
|
||||
*/
|
||||
void SentFrame() {
|
||||
++mSentFrames;
|
||||
}
|
||||
void FrameDeliveredToEncoder() { ++mFramesDeliveredToEncoder; }
|
||||
private:
|
||||
uint32_t mDroppedFrames = 0;
|
||||
mozilla::Atomic<int32_t> mSentFrames;
|
||||
uint32_t mFramesEncoded = 0;
|
||||
mozilla::Atomic<int32_t> mFramesDeliveredToEncoder;
|
||||
};
|
||||
|
||||
/** Statistics for receiving streams
|
||||
@ -457,12 +466,14 @@ private:
|
||||
//Local database of currently applied receive codecs
|
||||
nsTArray<UniquePtr<VideoCodecConfig>> mRecvCodecList;
|
||||
|
||||
// protects mCurSendCodecConfig, mInReconfig,mVideoSend/RecvStreamStats, mSend/RecvStreams
|
||||
// protects mCurSendCodecConfig, mInReconfig,mVideoSend/RecvStreamStats, mSend/RecvStreams, mPacketCounts
|
||||
Mutex mCodecMutex;
|
||||
nsAutoPtr<VideoCodecConfig> mCurSendCodecConfig;
|
||||
bool mInReconfig;
|
||||
SendStreamStatistics mSendStreamStats;
|
||||
ReceiveStreamStatistics mRecvStreamStats;
|
||||
webrtc::RtcpPacketTypeCounter mPacketCounts;
|
||||
|
||||
// Must call webrtc::Call::DestroyVideoReceive/SendStream to delete these:
|
||||
webrtc::VideoReceiveStream* mRecvStream;
|
||||
webrtc::VideoSendStream* mSendStream;
|
||||
|
@ -3660,6 +3660,17 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) {
|
||||
s.mPacketsSent.Construct(mp.rtp_packets_sent());
|
||||
s.mBytesSent.Construct(mp.rtp_bytes_sent());
|
||||
|
||||
// Fill in packet type statistics
|
||||
webrtc::RtcpPacketTypeCounter counters;
|
||||
if (mp.Conduit()->GetPacketTypeStats(&counters)) {
|
||||
s.mNackCount.Construct(counters.nack_packets);
|
||||
// Fill in video only packet type stats
|
||||
if (!isAudio) {
|
||||
s.mFirCount.Construct(counters.fir_packets);
|
||||
s.mPliCount.Construct(counters.pli_packets);
|
||||
}
|
||||
}
|
||||
|
||||
// Lastly, fill in video encoder stats if this is video
|
||||
if (!isAudio) {
|
||||
double framerateMean;
|
||||
@ -3667,16 +3678,19 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) {
|
||||
double bitrateMean;
|
||||
double bitrateStdDev;
|
||||
uint32_t droppedFrames;
|
||||
uint32_t framesEncoded;
|
||||
if (mp.Conduit()->GetVideoEncoderStats(&framerateMean,
|
||||
&framerateStdDev,
|
||||
&bitrateMean,
|
||||
&bitrateStdDev,
|
||||
&droppedFrames)) {
|
||||
&droppedFrames,
|
||||
&framesEncoded)) {
|
||||
s.mFramerateMean.Construct(framerateMean);
|
||||
s.mFramerateStdDev.Construct(framerateStdDev);
|
||||
s.mBitrateMean.Construct(bitrateMean);
|
||||
s.mBitrateStdDev.Construct(bitrateStdDev);
|
||||
s.mDroppedFrames.Construct(droppedFrames);
|
||||
s.mFramesEncoded.Construct(framesEncoded);
|
||||
}
|
||||
}
|
||||
query->report->mOutboundRTPStreamStats.Value().AppendElement(s,
|
||||
@ -3748,6 +3762,16 @@ PeerConnectionImpl::ExecuteStatsQuery_s(RTCStatsQuery *query) {
|
||||
s.mMozAvSyncDelay.Construct(avSyncDelta);
|
||||
}
|
||||
}
|
||||
// Fill in packet type statistics
|
||||
webrtc::RtcpPacketTypeCounter counters;
|
||||
if (mp.Conduit()->GetPacketTypeStats(&counters)) {
|
||||
s.mNackCount.Construct(counters.nack_packets);
|
||||
// Fill in video only packet type stats
|
||||
if (!isAudio) {
|
||||
s.mFirCount.Construct(counters.fir_packets);
|
||||
s.mPliCount.Construct(counters.pli_packets);
|
||||
}
|
||||
}
|
||||
// Lastly, fill in video decoder stats if this is video
|
||||
if (!isAudio) {
|
||||
double framerateMean;
|
||||
|
@ -155,7 +155,8 @@ struct ChannelStatistics : public RtcpStatistics {
|
||||
};
|
||||
|
||||
// Statistics callback, called at each generation of a new RTCP report block.
|
||||
class StatisticsProxy : public RtcpStatisticsCallback {
|
||||
class StatisticsProxy : public RtcpStatisticsCallback,
|
||||
public RtcpPacketTypeCounterObserver {
|
||||
public:
|
||||
StatisticsProxy(uint32_t ssrc)
|
||||
: stats_lock_(CriticalSectionWrapper::CreateCriticalSection()),
|
||||
@ -186,6 +187,20 @@ class StatisticsProxy : public RtcpStatisticsCallback {
|
||||
return stats_;
|
||||
}
|
||||
|
||||
void RtcpPacketTypesCounterUpdated(uint32_t ssrc,
|
||||
const RtcpPacketTypeCounter& packet_counter) override {
|
||||
CriticalSectionScoped cs(stats_lock_.get());
|
||||
if (ssrc != ssrc_) {
|
||||
return;
|
||||
}
|
||||
packet_counter_ = packet_counter;
|
||||
};
|
||||
|
||||
void GetPacketTypeCounter(RtcpPacketTypeCounter& aPacketTypeCounter) {
|
||||
CriticalSectionScoped cs(stats_lock_.get());
|
||||
aPacketTypeCounter = packet_counter_;
|
||||
}
|
||||
|
||||
private:
|
||||
// StatisticsUpdated calls are triggered from threads in the RTP module,
|
||||
// while GetStats calls can be triggered from the public voice engine API,
|
||||
@ -193,6 +208,7 @@ class StatisticsProxy : public RtcpStatisticsCallback {
|
||||
rtc::scoped_ptr<CriticalSectionWrapper> stats_lock_;
|
||||
uint32_t ssrc_;
|
||||
ChannelStatistics stats_;
|
||||
RtcpPacketTypeCounter packet_counter_;
|
||||
};
|
||||
|
||||
class VoERtcpObserver : public RtcpBandwidthObserver {
|
||||
@ -936,7 +952,7 @@ Channel::Channel(int32_t channelId,
|
||||
statistics_proxy_.reset(new StatisticsProxy(_rtpRtcpModule->SSRC()));
|
||||
rtp_receive_statistics_->RegisterRtcpStatisticsCallback(
|
||||
statistics_proxy_.get());
|
||||
|
||||
configuration.rtcp_packet_type_counter_observer = statistics_proxy_.get();
|
||||
Config audioproc_config;
|
||||
audioproc_config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
|
||||
audioproc_config.Set<ExtendedFilter>(
|
||||
@ -3274,6 +3290,14 @@ Channel::GetRTPStatistics(CallStatistics& stats)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Channel::GetRTCPPacketTypeCounters(RtcpPacketTypeCounter& stats) {
|
||||
if (_rtpRtcpModule->RTCP() == RtcpMode::kOff) {
|
||||
return -1;
|
||||
}
|
||||
statistics_proxy_->GetPacketTypeCounter(stats);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int Channel::SetREDStatus(bool enable, int redPayloadtype) {
|
||||
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
|
||||
"Channel::SetREDStatus()");
|
||||
|
@ -355,6 +355,7 @@ public:
|
||||
unsigned int& maxJitterMs,
|
||||
unsigned int& discardedPackets,
|
||||
unsigned int& cumulativeLost);
|
||||
int GetRTCPPacketTypeCounters(RtcpPacketTypeCounter& stats);
|
||||
int GetRemoteRTCPReportBlocks(std::vector<ReportBlock>* report_blocks);
|
||||
int GetRTPStatistics(CallStatistics& stats);
|
||||
int SetREDStatus(bool enable, int redPayloadtype);
|
||||
|
@ -179,6 +179,10 @@ class WEBRTC_DLLEXPORT VoERTP_RTCP {
|
||||
// Gets RTCP statistics for a specific |channel|.
|
||||
virtual int GetRTCPStatistics(int channel, CallStatistics& stats) = 0;
|
||||
|
||||
// Gets RTCP packet type counters for a specific channel
|
||||
virtual int GetRTCPPacketTypeCounters(int channel,
|
||||
RtcpPacketTypeCounter& stats) = 0;
|
||||
|
||||
// Gets the report block parts of the last received RTCP Sender Report (SR),
|
||||
// or RTCP Receiver Report (RR) on a specified |channel|. Each vector
|
||||
// element also contains the SSRC of the sender in addition to a report
|
||||
|
@ -357,6 +357,22 @@ int VoERTP_RTCPImpl::GetRTCPStatistics(int channel, CallStatistics& stats) {
|
||||
return channelPtr->GetRTPStatistics(stats);
|
||||
}
|
||||
|
||||
int VoERTP_RTCPImpl::GetRTCPPacketTypeCounters(int channel,
|
||||
RtcpPacketTypeCounter& stats) {
|
||||
if (!_shared->statistics().Initialized()) {
|
||||
_shared->SetLastError(VE_NOT_INITED, kTraceError);
|
||||
return -1;
|
||||
}
|
||||
voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
|
||||
voe::Channel* channelPtr = ch.channel();
|
||||
if (channelPtr == NULL) {
|
||||
_shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
|
||||
"GetRTCPPacketTypeCounters() failed to locate channel");
|
||||
return -1;
|
||||
}
|
||||
return channelPtr->GetRTCPPacketTypeCounters(stats);
|
||||
}
|
||||
|
||||
int VoERTP_RTCPImpl::GetRemoteRTCPReportBlocks(
|
||||
int channel, std::vector<ReportBlock>* report_blocks) {
|
||||
if (!_shared->statistics().Initialized()) {
|
||||
|
@ -70,6 +70,9 @@ class VoERTP_RTCPImpl : public VoERTP_RTCP {
|
||||
|
||||
int GetRTCPStatistics(int channel, CallStatistics& stats) override;
|
||||
|
||||
int GetRTCPPacketTypeCounters(int channel,
|
||||
RtcpPacketTypeCounter& stats) override;
|
||||
|
||||
int GetRemoteRTCPReportBlocks(
|
||||
int channel,
|
||||
std::vector<ReportBlock>* report_blocks) override;
|
||||
|
Loading…
Reference in New Issue
Block a user