Bug 1380555 - P2 - Refactor isRemote from telemetry;r?mjf
MozReview-Commit-ID: ESqSZyijKYL
--- a/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.cpp
+++ b/media/webrtc/signaling/src/peerconnection/PeerConnectionCtx.cpp
@@ -183,18 +183,19 @@ void PeerConnectionCtx::Destroy() {
typedef Vector<nsAutoPtr<RTCStatsQuery>> RTCStatsQueries;
// Telemetry reporting every second after start of first call.
// The threading model around the media pipelines is weird:
// - The pipelines are containers,
// - containers that are only safe on main thread, with members only safe on STS,
// - hence the there and back again approach.
+template <class T>
static auto
-FindId(const Sequence<RTCInboundRTPStreamStats>& aArray,
+FindId(const Sequence<T>& aArray,
const nsString &aId) -> decltype(aArray.Length()) {
for (decltype(aArray.Length()) i = 0; i < aArray.Length(); i++) {
if (aArray[i].mId.Value() == aId) {
return i;
}
}
return aArray.NoIndex;
}
@@ -224,70 +225,109 @@ EverySecondTelemetryCallback_s(nsAutoPtr
}
PeerConnectionCtx *ctx = PeerConnectionCtx::GetInstance();
for (auto & q : *aQueryList) {
PeerConnectionImpl::ExecuteStatsQuery_s(q);
auto& r = *q->report;
if (r.mInboundRTPStreamStats.WasPassed()) {
// First, get reports from a second ago, if any, for calculations below
- const Sequence<RTCInboundRTPStreamStats> *lastInboundStats = nullptr;
+ const Sequence<RTCInboundRTPStreamStats>* lastInboundStats = nullptr;
+ const Sequence<RTCRemoteInboundRTPStreamStats>* lastRemoteInboundStats =
+ nullptr;
{
auto i = FindId(ctx->mLastReports, r.mPcid);
if (i != ctx->mLastReports.NoIndex) {
- lastInboundStats = &ctx->mLastReports[i]->mInboundRTPStreamStats.Value();
+ lastInboundStats =
+ &ctx->mLastReports[i]->mInboundRTPStreamStats.Value();
+ lastRemoteInboundStats =
+ &ctx->mLastReports[i]->mRemoteInboundRTPStreamStats.Value();
}
}
+ auto mediaIsAudio = [](const RTCRTPStreamStats& stat) {
+ return stat.mMediaType.Value().EqualsLiteral("audio");
+ };
+
+ auto recordAudioBandwidth = [](const RTCReceivedRTPStreamStats& s,
+ const RTCReceivedRTPStreamStats& lasts,
+ bool isAudio,
+ HistogramID audioId,
+ HistogramID videoId) {
+ if (lasts.mBytesReceived.WasPassed()) {
+ auto delta_ms = int32_t(s.mTimestamp.Value() -
+ lasts.mTimestamp.Value());
+ // In theory we're called every second, so delta *should* be in that range.
+ // Small deltas could cause errors due to division
+ if (delta_ms > 500 && delta_ms < 60000) {
+ auto id = isAudio ? audioId : videoId;
+ Accumulate(id, ((s.mBytesReceived.Value() -
+ lasts.mBytesReceived.Value()) * 8) / delta_ms);
+ }
+ // We could accumulate values until enough time has passed
+ // and then Accumulate() but this isn't that important.
+ }
+ };
+
+ HistogramID id;
// Then, look for the things we want telemetry on
- auto& array = r.mInboundRTPStreamStats.Value();
- for (decltype(array.Length()) i = 0; i < array.Length(); i++) {
- auto& s = array[i];
- bool isAudio = (s.mId.Value().Find("audio") != -1);
+ //Record Remote Inbound Stats
+ for (const auto& s : r.mRemoteInboundRTPStreamStats.Value()) {
+ bool isAudio = mediaIsAudio(s);
if (s.mPacketsLost.WasPassed() && s.mPacketsReceived.WasPassed() &&
(s.mPacketsLost.Value() + s.mPacketsReceived.Value()) != 0) {
- HistogramID id;
- // TODO @@NG TELEMETRY
+ id = isAudio ? WEBRTC_AUDIO_QUALITY_OUTBOUND_PACKETLOSS_RATE :
+ WEBRTC_VIDEO_QUALITY_OUTBOUND_PACKETLOSS_RATE;
+ // *1000 so we can read in 10's of a percent (permille)
+ Accumulate(id,
+ (s.mPacketsLost.Value() * 1000) /
+ (s.mPacketsLost.Value() + s.mPacketsReceived.Value()));
+
+ }
+ if( s.mRoundTripTime.WasPassed()) {
+ id = isAudio ? WEBRTC_AUDIO_QUALITY_OUTBOUND_RTT :
+ WEBRTC_VIDEO_QUALITY_OUTBOUND_RTT;
+ Accumulate(id, s.mRoundTripTime.Value());
+ }
+ if (lastRemoteInboundStats && s.mBytesReceived.WasPassed()) {
+ auto& laststats = *lastRemoteInboundStats;
+ auto i = FindId(laststats, s.mId.Value());
+ if (i != laststats.NoIndex) {
+ auto& lasts = laststats[i];
+ recordAudioBandwidth(s, lasts, isAudio,
+ WEBRTC_AUDIO_QUALITY_OUTBOUND_BANDWIDTH_KBITS,
+ WEBRTC_VIDEO_QUALITY_OUTBOUND_BANDWIDTH_KBITS);
+ }
+ }
+ }
+ // Record Local Inbound Stats
+ for (const auto& s : r.mInboundRTPStreamStats.Value()) {
+ bool isAudio = mediaIsAudio(s);
+ if (s.mPacketsLost.WasPassed() && s.mPacketsReceived.WasPassed() &&
+ (s.mPacketsLost.Value() + s.mPacketsReceived.Value()) != 0) {
id = isAudio ? WEBRTC_AUDIO_QUALITY_INBOUND_PACKETLOSS_RATE :
WEBRTC_VIDEO_QUALITY_INBOUND_PACKETLOSS_RATE;
// *1000 so we can read in 10's of a percent (permille)
Accumulate(id,
(s.mPacketsLost.Value() * 1000) /
(s.mPacketsLost.Value() + s.mPacketsReceived.Value()));
}
if (s.mJitter.WasPassed()) {
- HistogramID id;
- // TODO @@NG TELEMETRY
- id = isAudio ? WEBRTC_AUDIO_QUALITY_INBOUND_JITTER :
- WEBRTC_VIDEO_QUALITY_INBOUND_JITTER;
- //}
+ id = isAudio ? WEBRTC_AUDIO_QUALITY_INBOUND_JITTER :
+ WEBRTC_VIDEO_QUALITY_INBOUND_JITTER;
Accumulate(id, s.mJitter.Value());
}
- // TODO @@NG TELEMETRY
if (lastInboundStats && s.mBytesReceived.WasPassed()) {
auto& laststats = *lastInboundStats;
auto i = FindId(laststats, s.mId.Value());
if (i != laststats.NoIndex) {
auto& lasts = laststats[i];
- if (lasts.mBytesReceived.WasPassed()) {
- auto delta_ms = int32_t(s.mTimestamp.Value() -
- lasts.mTimestamp.Value());
- // In theory we're called every second, so delta *should* be in that range.
- // Small deltas could cause errors due to division
- if (delta_ms > 500 && delta_ms < 60000) {
- HistogramID id;
- // TODO @NG TELEMETRY
- id = isAudio ? WEBRTC_AUDIO_QUALITY_INBOUND_BANDWIDTH_KBITS :
- WEBRTC_VIDEO_QUALITY_INBOUND_BANDWIDTH_KBITS;
- Accumulate(id, ((s.mBytesReceived.Value() -
- lasts.mBytesReceived.Value()) * 8) / delta_ms);
- }
- // We could accumulate values until enough time has passed
- // and then Accumulate() but this isn't that important.
- }
+ recordAudioBandwidth(s, lasts, isAudio,
+ WEBRTC_AUDIO_QUALITY_INBOUND_BANDWIDTH_KBITS,
+ WEBRTC_VIDEO_QUALITY_INBOUND_BANDWIDTH_KBITS);
}
}
}
}
}
// Steal and hang on to reports for the next second
ctx->mLastReports.Clear();
for (auto & q : *aQueryList) {