10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2012, Google Inc.
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer.
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     and/or other materials provided with the distribution.
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     derived from this software without specific prior written permission.
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/app/webrtc/statscollector.h"
290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <utility>
310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <vector>
320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
33cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/session/media/channel.h"
342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/base64.h"
352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/scoped_ptr.h"
362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/timing.h"
370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace webrtc {
390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// The items below are in alphabetical order.
410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameActiveConnection[] =
420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googActiveConnection";
430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameActualEncBitrate[] =
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googActualEncBitrate";
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameAudioOutputLevel[] = "audioOutputLevel";
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameAudioInputLevel[] = "audioInputLevel";
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameAvailableReceiveBandwidth[] =
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googAvailableReceiveBandwidth";
490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameAvailableSendBandwidth[] =
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googAvailableSendBandwidth";
5197fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.orgconst char StatsReport::kStatsValueNameAvgEncodeMs[] = "googAvgEncodeMs";
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameBucketDelay[] = "googBucketDelay";
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameBytesReceived[] = "bytesReceived";
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameBytesSent[] = "bytesSent";
551114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.orgconst char StatsReport::kStatsValueNameBandwidthLimitedResolution[] =
561114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.org    "googBandwidthLimitedResolution";
5797fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.orgconst char StatsReport::kStatsValueNameCaptureJitterMs[] =
5897fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org    "googCaptureJitterMs";
59cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.orgconst char StatsReport::kStatsValueNameCaptureQueueDelayMsPerS[] =
60cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.org    "googCaptureQueueDelayMsPerS";
610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameChannelId[] = "googChannelId";
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameCodecName[] = "googCodecName";
630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameComponent[] = "googComponent";
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameContentName[] = "googContentName";
651114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.orgconst char StatsReport::kStatsValueNameCpuLimitedResolution[] =
661114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.org    "googCpuLimitedResolution";
676019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.orgconst char StatsReport::kStatsValueNameDecodingCTSG[] =
686019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org    "googDecodingCTSG";
696019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.orgconst char StatsReport::kStatsValueNameDecodingCTN[] =
706019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org    "googDecodingCTN";
716019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.orgconst char StatsReport::kStatsValueNameDecodingNormal[] =
726019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org    "googDecodingNormal";
736019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.orgconst char StatsReport::kStatsValueNameDecodingPLC[] =
746019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org    "googDecodingPLC";
756019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.orgconst char StatsReport::kStatsValueNameDecodingCNG[] =
766019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org    "googDecodingCNG";
776019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.orgconst char StatsReport::kStatsValueNameDecodingPLCCNG[] =
786019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org    "googDecodingPLCCNG";
7962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgconst char StatsReport::kStatsValueNameDer[] = "googDerBase64";
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Echo metrics from the audio processing module.
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameEchoCancellationQualityMin[] =
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googEchoCancellationQualityMin";
830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameEchoDelayMedian[] =
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googEchoCancellationEchoDelayMedian";
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameEchoDelayStdDev[] =
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googEchoCancellationEchoDelayStdDev";
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameEchoReturnLoss[] =
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googEchoCancellationReturnLoss";
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameEchoReturnLossEnhancement[] =
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googEchoCancellationReturnLossEnhancement";
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
925c2c63e9e7cea1266756d354efe0af02d8dfe0dfbuildbot@webrtc.orgconst char StatsReport::kStatsValueNameEncodeRelStdDev[] =
935c2c63e9e7cea1266756d354efe0af02d8dfe0dfbuildbot@webrtc.org    "googEncodeRelStdDev";
94cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.orgconst char StatsReport::kStatsValueNameEncodeUsagePercent[] =
95cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.org    "googEncodeUsagePercent";
968a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgconst char StatsReport::kStatsValueNameExpandRate[] = "googExpandRate";
9762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgconst char StatsReport::kStatsValueNameFingerprint[] = "googFingerprint";
988841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.orgconst char StatsReport::kStatsValueNameFingerprintAlgorithm[] =
998841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    "googFingerprintAlgorithm";
1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFirsReceived[] = "googFirsReceived";
1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFirsSent[] = "googFirsSent";
102fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.orgconst char StatsReport::kStatsValueNameFrameHeightInput[] =
103fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.org    "googFrameHeightInput";
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFrameHeightReceived[] =
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googFrameHeightReceived";
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFrameHeightSent[] =
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googFrameHeightSent";
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFrameRateReceived[] =
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googFrameRateReceived";
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFrameRateDecoded[] =
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googFrameRateDecoded";
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFrameRateOutput[] =
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googFrameRateOutput";
1145c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgconst char StatsReport::kStatsValueNameDecodeMs[] = "googDecodeMs";
1155c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgconst char StatsReport::kStatsValueNameMaxDecodeMs[] = "googMaxDecodeMs";
1165c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgconst char StatsReport::kStatsValueNameCurrentDelayMs[] = "googCurrentDelayMs";
1175c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgconst char StatsReport::kStatsValueNameTargetDelayMs[] = "googTargetDelayMs";
1185c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgconst char StatsReport::kStatsValueNameJitterBufferMs[] = "googJitterBufferMs";
1195c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgconst char StatsReport::kStatsValueNameMinPlayoutDelayMs[] =
1205c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    "googMinPlayoutDelayMs";
1215c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgconst char StatsReport::kStatsValueNameRenderDelayMs[] = "googRenderDelayMs";
1225c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
123de6aa3e68a75cbc0529ce287fe1c5ad72c8dfc11buildbot@webrtc.orgconst char StatsReport::kStatsValueNameCaptureStartNtpTimeMs[] =
124de6aa3e68a75cbc0529ce287fe1c5ad72c8dfc11buildbot@webrtc.org    "googCaptureStartNtpTimeMs";
125de6aa3e68a75cbc0529ce287fe1c5ad72c8dfc11buildbot@webrtc.org
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFrameRateInput[] = "googFrameRateInput";
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFrameRateSent[] = "googFrameRateSent";
128fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.orgconst char StatsReport::kStatsValueNameFrameWidthInput[] =
129fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.org    "googFrameWidthInput";
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFrameWidthReceived[] =
1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googFrameWidthReceived";
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameFrameWidthSent[] = "googFrameWidthSent";
1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameInitiator[] = "googInitiator";
13462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgconst char StatsReport::kStatsValueNameIssuerId[] = "googIssuerId";
1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameJitterReceived[] = "googJitterReceived";
1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameLocalAddress[] = "googLocalAddress";
1373db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.orgconst char StatsReport::kStatsValueNameLocalCandidateType[] =
1383db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.org    "googLocalCandidateType";
13962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgconst char StatsReport::kStatsValueNameLocalCertificateId[] =
14062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org    "googLocalCertificateId";
141d24be9140f01dbf49e0ae4154880887f7c52129cbuildbot@webrtc.orgconst char StatsReport::kStatsValueNameAdaptationChanges[] =
142d24be9140f01dbf49e0ae4154880887f7c52129cbuildbot@webrtc.org    "googAdaptationChanges";
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameNacksReceived[] = "googNacksReceived";
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameNacksSent[] = "googNacksSent";
1457587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.orgconst char StatsReport::kStatsValueNamePlisReceived[] = "googPlisReceived";
1467587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.orgconst char StatsReport::kStatsValueNamePlisSent[] = "googPlisSent";
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNamePacketsReceived[] = "packetsReceived";
1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNamePacketsSent[] = "packetsSent";
1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNamePacketsLost[] = "packetsLost";
15018d645088ec394abbc372c6eea18bbde78ea7993jiayl@webrtc.orgconst char StatsReport::kStatsValueNamePreferredJitterBufferMs[] =
15118d645088ec394abbc372c6eea18bbde78ea7993jiayl@webrtc.org    "googPreferredJitterBufferMs";
1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameReadable[] = "googReadable";
1538a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgconst char StatsReport::kStatsValueNameRecvPacketGroupArrivalTimeDebug[] =
1548a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    "googReceivedPacketGroupArrivalTimeDebug";
1558a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgconst char StatsReport::kStatsValueNameRecvPacketGroupPropagationDeltaDebug[] =
1568a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    "googReceivedPacketGroupPropagationDeltaDebug";
1578a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgconst char
1588a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgStatsReport::kStatsValueNameRecvPacketGroupPropagationDeltaSumDebug[] =
1598a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    "googReceivedPacketGroupPropagationDeltaSumDebug";
1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameRemoteAddress[] = "googRemoteAddress";
1613db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.orgconst char StatsReport::kStatsValueNameRemoteCandidateType[] =
1623db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.org    "googRemoteCandidateType";
16362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgconst char StatsReport::kStatsValueNameRemoteCertificateId[] =
16462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org    "googRemoteCertificateId";
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameRetransmitBitrate[] =
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googRetransmitBitrate";
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameRtt[] = "googRtt";
1684ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.orgconst char StatsReport::kStatsValueNameSsrc[] = "ssrc";
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameTargetEncBitrate[] =
1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googTargetEncBitrate";
1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameTransmitBitrate[] =
1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    "googTransmitBitrate";
1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameTransportId[] = "transportId";
1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameTransportType[] = "googTransportType";
1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameTrackId[] = "googTrackId";
1764ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.orgconst char StatsReport::kStatsValueNameTypingNoiseState[] =
1774ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org    "googTypingNoiseState";
1781114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.orgconst char StatsReport::kStatsValueNameViewLimitedResolution[] =
1791114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.org    "googViewLimitedResolution";
1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsValueNameWritable[] = "googWritable";
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsReportTypeSession[] = "googLibjingleSession";
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsReportTypeBwe[] = "VideoBwe";
1845c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgconst char StatsReport::kStatsReportTypeRemoteSsrc[] = "remoteSsrc";
1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsReportTypeSsrc[] = "ssrc";
1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsReportTypeTrack[] = "googTrack";
1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsReportTypeIceCandidate[] = "iceCandidate";
1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsReportTypeTransport[] = "googTransport";
1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsReportTypeComponent[] = "googComponent";
1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsReportTypeCandidatePair[] = "googCandidatePair";
19162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgconst char StatsReport::kStatsReportTypeCertificate[] = "googCertificate";
1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char StatsReport::kStatsReportVideoBweId[] = "bweforvideo";
1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Implementations of functions in statstypes.h
1962829d698040572c81ba900e906448542cfa0844atommi@webrtc.orgvoid StatsReport::AddValue(StatsReport::StatsValueName name,
1972829d698040572c81ba900e906448542cfa0844atommi@webrtc.org                           const std::string& value) {
1982829d698040572c81ba900e906448542cfa0844atommi@webrtc.org  values.push_back(Value(name, value));
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2012829d698040572c81ba900e906448542cfa0844atommi@webrtc.orgvoid StatsReport::AddValue(StatsReport::StatsValueName name, int64 value) {
2022a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  AddValue(name, rtc::ToString<int64>(value));
2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2058a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgtemplate <typename T>
2062829d698040572c81ba900e906448542cfa0844atommi@webrtc.orgvoid StatsReport::AddValue(StatsReport::StatsValueName name,
2078a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org                           const std::vector<T>& value) {
2088a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  std::ostringstream oss;
2098a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  oss << "[";
2108a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  for (size_t i = 0; i < value.size(); ++i) {
2112a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    oss << rtc::ToString<T>(value[i]);
2128a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    if (i != value.size() - 1)
2138a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org      oss << ", ";
2148a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  }
2158a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  oss << "]";
2168a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  AddValue(name, oss.str());
2178a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org}
2188a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org
2192829d698040572c81ba900e906448542cfa0844atommi@webrtc.orgvoid StatsReport::AddBoolean(StatsReport::StatsValueName name, bool value) {
2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  AddValue(name, value ? "true" : "false");
2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2232829d698040572c81ba900e906448542cfa0844atommi@webrtc.orgvoid StatsReport::ReplaceValue(StatsReport::StatsValueName name,
224c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org                               const std::string& value) {
225c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  for (Values::iterator it = values.begin(); it != values.end(); ++it) {
226c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    if ((*it).name == name) {
227c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org      it->value = value;
228c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org      return;
229c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    }
230c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  }
231c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  // It is not reachable here, add an ASSERT to make sure the overwriting is
232c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  // always a success.
233c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  ASSERT(false);
234c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org}
235c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace {
2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
238676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.orgdouble GetTimeNow() {
2392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  return rtc::Timing::WallTimeNow() * rtc::kNumMillisecsPerSec;
240676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org}
241676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org
242676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.orgbool GetTransportIdFromProxy(const cricket::ProxyTransportMap& map,
243676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org                             const std::string& proxy,
244676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org                             std::string* transport) {
245676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  // TODO(hta): Remove handling of empty proxy name once tests do not use it.
246676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  if (proxy.empty()) {
247676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org    transport->clear();
248676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org    return true;
249676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  }
250676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org
251676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  cricket::ProxyTransportMap::const_iterator found = map.find(proxy);
252676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  if (found == map.end()) {
253676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org    LOG(LS_ERROR) << "No transport ID mapping for " << proxy;
254676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org    return false;
255676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  }
256676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org
257676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  std::ostringstream ost;
258676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  // Component 1 is always used for RTP.
259676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  ost << "Channel-" << found->second << "-1";
260676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  *transport = ost.str();
261676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  return true;
262676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org}
263676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org
2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstd::string StatsId(const std::string& type, const std::string& id) {
2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return type + "_" + id;
2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
268890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.orgstd::string StatsId(const std::string& type, const std::string& id,
269890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                    StatsCollector::TrackDirection direction) {
270890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  ASSERT(direction == StatsCollector::kSending ||
271890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org         direction == StatsCollector::kReceiving);
272890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org
273890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  // Strings for the direction of the track.
274890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  const char kSendDirection[] = "send";
275890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  const char kRecvDirection[] = "recv";
276890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org
277890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  const std::string direction_id = (direction == StatsCollector::kSending) ?
278890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      kSendDirection : kRecvDirection;
279890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  return type + "_" + id + "_" + direction_id;
280890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org}
281890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org
2820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool ExtractValueFromReport(
2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const StatsReport& report,
2842829d698040572c81ba900e906448542cfa0844atommi@webrtc.org    StatsReport::StatsValueName name,
2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::string* value) {
2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  StatsReport::Values::const_iterator it = report.values.begin();
2870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (; it != report.values.end(); ++it) {
2880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (it->name == name) {
2890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *value = it->value;
2900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return true;
2910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return false;
2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
296cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.orgvoid AddTrackReport(StatsSet* reports, const std::string& track_id) {
297b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  // Adds an empty track report.
298cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  StatsReport* report = reports->ReplaceOrAddNew(
299cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org      StatsId(StatsReport::kStatsReportTypeTrack, track_id));
300cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->type = StatsReport::kStatsReportTypeTrack;
301cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->AddValue(StatsReport::kStatsValueNameTrackId, track_id);
302b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org}
303b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org
3040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate <class TrackVector>
305cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.orgvoid CreateTrackReports(const TrackVector& tracks, StatsSet* reports) {
3060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (size_t j = 0; j < tracks.size(); ++j) {
3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    webrtc::MediaStreamTrackInterface* track = tracks[j];
308b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org    AddTrackReport(reports, track->id());
3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid ExtractStats(const cricket::VoiceReceiverInfo& info, StatsReport* report) {
3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameAudioOutputLevel,
3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.audio_level);
3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameBytesReceived,
3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.bytes_rcvd);
3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameJitterReceived,
3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.jitter_ms);
31918d645088ec394abbc372c6eea18bbde78ea7993jiayl@webrtc.org  report->AddValue(StatsReport::kStatsValueNameJitterBufferMs,
32018d645088ec394abbc372c6eea18bbde78ea7993jiayl@webrtc.org                   info.jitter_buffer_ms);
32118d645088ec394abbc372c6eea18bbde78ea7993jiayl@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePreferredJitterBufferMs,
32218d645088ec394abbc372c6eea18bbde78ea7993jiayl@webrtc.org                   info.jitter_buffer_preferred_ms);
32318d645088ec394abbc372c6eea18bbde78ea7993jiayl@webrtc.org  report->AddValue(StatsReport::kStatsValueNameCurrentDelayMs,
32418d645088ec394abbc372c6eea18bbde78ea7993jiayl@webrtc.org                   info.delay_estimate_ms);
3258a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameExpandRate,
3262a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                   rtc::ToString<float>(info.expand_rate));
3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePacketsReceived,
3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.packets_rcvd);
3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePacketsLost,
3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.packets_lost);
3316019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameDecodingCTSG,
3326019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org                   info.decoding_calls_to_silence_generator);
3336019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameDecodingCTN,
3346019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org                   info.decoding_calls_to_neteq);
3356019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameDecodingNormal,
3366019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org                   info.decoding_normal);
3376019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameDecodingPLC,
3386019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org                   info.decoding_plc);
3396019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameDecodingCNG,
3406019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org                   info.decoding_cng);
3416019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameDecodingPLCCNG,
3426019a0f470cf75a9a5787f7900162498609f509bbuildbot@webrtc.org                   info.decoding_plc_cng);
343842c369caaf7ab0115e101686ee5640a289da0e8buildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
344842c369caaf7ab0115e101686ee5640a289da0e8buildbot@webrtc.org                   info.capture_start_ntp_time_ms);
345ec0b1b83d70e08f3bd47940d33ad69cb8bb0878fbuildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameCodecName, info.codec_name);
3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid ExtractStats(const cricket::VoiceSenderInfo& info, StatsReport* report) {
3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameAudioInputLevel,
3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.audio_level);
3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameBytesSent,
3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.bytes_sent);
3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePacketsSent,
3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.packets_sent);
35584c6e3c1afec56005a015955d68cab895341f190henrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePacketsLost,
35684c6e3c1afec56005a015955d68cab895341f190henrike@webrtc.org                   info.packets_lost);
3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameJitterReceived,
3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.jitter_ms);
3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameRtt, info.rtt_ms);
3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameEchoCancellationQualityMin,
3612a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                   rtc::ToString<float>(info.aec_quality_min));
3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameEchoDelayMedian,
3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.echo_delay_median_ms);
3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameEchoDelayStdDev,
3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.echo_delay_std_ms);
3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameEchoReturnLoss,
3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.echo_return_loss);
3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameEchoReturnLossEnhancement,
3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.echo_return_loss_enhancement);
3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameCodecName, info.codec_name);
3714ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org  report->AddBoolean(StatsReport::kStatsValueNameTypingNoiseState,
3724ba8b9ea10385f43b19d6ed7408f4a09bdc1cbdawu@webrtc.org                     info.typing_noise_detected);
3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid ExtractStats(const cricket::VideoReceiverInfo& info, StatsReport* report) {
3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameBytesReceived,
3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.bytes_rcvd);
3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePacketsReceived,
3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.packets_rcvd);
3800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePacketsLost,
3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.packets_lost);
3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFirsSent,
3840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.firs_sent);
3857587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePlisSent,
3867587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org                   info.plis_sent);
3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameNacksSent,
3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.nacks_sent);
3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameWidthReceived,
3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.frame_width);
3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameHeightReceived,
3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.frame_height);
3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameRateReceived,
3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.framerate_rcvd);
3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameRateDecoded,
3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.framerate_decoded);
3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameRateOutput,
3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.framerate_output);
3995c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
4005c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameDecodeMs,
4015c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                   info.decode_ms);
4025c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameMaxDecodeMs,
4035c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                   info.max_decode_ms);
4045c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameCurrentDelayMs,
4055c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                   info.current_delay_ms);
4065c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameTargetDelayMs,
4075c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                   info.target_delay_ms);
4085c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameJitterBufferMs,
4095c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                   info.jitter_buffer_ms);
4105c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameMinPlayoutDelayMs,
4115c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                   info.min_playout_delay_ms);
4125c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameRenderDelayMs,
4135c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                   info.render_delay_ms);
414de6aa3e68a75cbc0529ce287fe1c5ad72c8dfc11buildbot@webrtc.org
415de6aa3e68a75cbc0529ce287fe1c5ad72c8dfc11buildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameCaptureStartNtpTimeMs,
416de6aa3e68a75cbc0529ce287fe1c5ad72c8dfc11buildbot@webrtc.org                   info.capture_start_ntp_time_ms);
4170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid ExtractStats(const cricket::VideoSenderInfo& info, StatsReport* report) {
4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameBytesSent,
4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.bytes_sent);
4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePacketsSent,
4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.packets_sent);
42484c6e3c1afec56005a015955d68cab895341f190henrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePacketsLost,
42584c6e3c1afec56005a015955d68cab895341f190henrike@webrtc.org                   info.packets_lost);
4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFirsReceived,
4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.firs_rcvd);
4297587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNamePlisReceived,
4307587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org                   info.plis_rcvd);
4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameNacksReceived,
4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.nacks_rcvd);
433fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameWidthInput,
434fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.org                   info.input_frame_width);
435fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameHeightInput,
436fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.org                   info.input_frame_height);
4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameWidthSent,
438fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.org                   info.send_frame_width);
4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameHeightSent,
440fc1e785be93c8b9bcce13c29d35af2a1ca91e6afwu@webrtc.org                   info.send_frame_height);
4410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameRateInput,
4420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.framerate_input);
4430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFrameRateSent,
4440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.framerate_sent);
4450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameRtt, info.rtt_ms);
4460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameCodecName, info.codec_name);
4471114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.org  report->AddBoolean(StatsReport::kStatsValueNameCpuLimitedResolution,
4481114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.org                     (info.adapt_reason & 0x1) > 0);
4491114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.org  report->AddBoolean(StatsReport::kStatsValueNameBandwidthLimitedResolution,
4501114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.org                     (info.adapt_reason & 0x2) > 0);
4511114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.org  report->AddBoolean(StatsReport::kStatsValueNameViewLimitedResolution,
4521114b945276ca2ded11890cf2c884d78e6188386mallinath@webrtc.org                     (info.adapt_reason & 0x4) > 0);
453d24be9140f01dbf49e0ae4154880887f7c52129cbuildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameAdaptationChanges,
454d24be9140f01dbf49e0ae4154880887f7c52129cbuildbot@webrtc.org                   info.adapt_changes);
45597fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org  report->AddValue(StatsReport::kStatsValueNameAvgEncodeMs, info.avg_encode_ms);
45697fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org  report->AddValue(StatsReport::kStatsValueNameCaptureJitterMs,
45797fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org                   info.capture_jitter_ms);
458cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameCaptureQueueDelayMsPerS,
459cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.org                   info.capture_queue_delay_ms_per_s);
460cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameEncodeUsagePercent,
461cfd624796c7321c5ffac2249b407cdd0d496e00awu@webrtc.org                   info.encode_usage_percent);
4625c2c63e9e7cea1266756d354efe0af02d8dfe0dfbuildbot@webrtc.org  report->AddValue(StatsReport::kStatsValueNameEncodeRelStdDev,
4635c2c63e9e7cea1266756d354efe0af02d8dfe0dfbuildbot@webrtc.org                   info.encode_rsd);
4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid ExtractStats(const cricket::BandwidthEstimationInfo& info,
4670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  double stats_gathering_started,
4688a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org                  PeerConnectionInterface::StatsOutputLevel level,
4690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  StatsReport* report) {
470cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  ASSERT(report->id == StatsReport::kStatsReportVideoBweId);
4710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->type = StatsReport::kStatsReportTypeBwe;
4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Clear out stats from previous GatherStats calls if any.
4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (report->timestamp != stats_gathering_started) {
4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    report->values.clear();
4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    report->timestamp = stats_gathering_started;
4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameAvailableSendBandwidth,
4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.available_send_bandwidth);
4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameAvailableReceiveBandwidth,
4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.available_recv_bandwidth);
4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameTargetEncBitrate,
4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.target_enc_bitrate);
4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameActualEncBitrate,
4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.actual_enc_bitrate);
4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameRetransmitBitrate,
4880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.retransmit_bitrate);
4890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameTransmitBitrate,
4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.transmit_bitrate);
4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameBucketDelay,
4920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   info.bucket_delay);
4938a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  if (level >= PeerConnectionInterface::kStatsOutputLevelDebug) {
4948a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    report->AddValue(
4958a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org        StatsReport::kStatsValueNameRecvPacketGroupPropagationDeltaSumDebug,
4968a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org        info.total_received_propagation_delta_ms);
4978a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    if (info.recent_received_propagation_delta_ms.size() > 0) {
4988a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org      report->AddValue(
4998a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org          StatsReport::kStatsValueNameRecvPacketGroupPropagationDeltaDebug,
5008a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org          info.recent_received_propagation_delta_ms);
5018a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org      report->AddValue(
5028a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org          StatsReport::kStatsValueNameRecvPacketGroupArrivalTimeDebug,
5038a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org          info.recent_received_packet_group_arrival_time_ms);
5048a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    }
5058a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  }
5060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5085c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgvoid ExtractRemoteStats(const cricket::MediaSenderInfo& info,
5095c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                        StatsReport* report) {
5105c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->timestamp = info.remote_stats[0].timestamp;
5115c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  // TODO(hta): Extract some stats here.
5125c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org}
5135c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
5145c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgvoid ExtractRemoteStats(const cricket::MediaReceiverInfo& info,
5155c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                        StatsReport* report) {
5165c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->timestamp = info.remote_stats[0].timestamp;
5175c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  // TODO(hta): Extract some stats here.
5185c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org}
5195c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Template to extract stats from a data vector.
52197fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org// In order to use the template, the functions that are called from it,
52297fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org// ExtractStats and ExtractRemoteStats, must be defined and overloaded
52397fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org// for each type.
5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate<typename T>
5250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid ExtractStatsFromList(const std::vector<T>& data,
5260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          const std::string& transport_id,
527890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                          StatsCollector* collector,
528890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                          StatsCollector::TrackDirection direction) {
5290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  typename std::vector<T>::const_iterator it = data.begin();
5300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (; it != data.end(); ++it) {
5310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::string id;
53297fbd309a28be4e38d138b40662507d50cab6d26sergeyu@chromium.org    uint32 ssrc = it->ssrc();
533890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    // Each track can have stats for both local and remote objects.
5345c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    // TODO(hta): Handle the case of multiple SSRCs per object.
535890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    StatsReport* report = collector->PrepareLocalReport(ssrc, transport_id,
536890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                                                        direction);
537890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    if (report)
538890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      ExtractStats(*it, report);
539890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org
5405c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    if (it->remote_stats.size() > 0) {
541890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      report = collector->PrepareRemoteReport(ssrc, transport_id,
542890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                                              direction);
5435c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org      if (!report) {
5445c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org        continue;
5455c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org      }
5465c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org      ExtractRemoteStats(*it, report);
5475c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    }
5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5498a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org}
5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}  // namespace
5520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
553fd1e42f2876772d9f690207af69eed20f6a99d2etommi@webrtc.orgStatsCollector::StatsCollector(WebRtcSession* session)
554fd1e42f2876772d9f690207af69eed20f6a99d2etommi@webrtc.org    : session_(session), stats_gathering_started_(0) {
555fd1e42f2876772d9f690207af69eed20f6a99d2etommi@webrtc.org  ASSERT(session_);
556fd1e42f2876772d9f690207af69eed20f6a99d2etommi@webrtc.org}
557fd1e42f2876772d9f690207af69eed20f6a99d2etommi@webrtc.org
558fd1e42f2876772d9f690207af69eed20f6a99d2etommi@webrtc.orgStatsCollector::~StatsCollector() {
5590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Adds a MediaStream with tracks that can be used as a |selector| in a call
5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// to GetStats.
5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid StatsCollector::AddStream(MediaStreamInterface* stream) {
5640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(stream != NULL);
5650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTrackReports<AudioTrackVector>(stream->GetAudioTracks(),
5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                       &reports_);
5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CreateTrackReports<VideoTrackVector>(stream->GetVideoTracks(),
5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                       &reports_);
5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
572c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.orgvoid StatsCollector::AddLocalAudioTrack(AudioTrackInterface* audio_track,
573c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org                                        uint32 ssrc) {
574c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  ASSERT(audio_track != NULL);
575c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  for (LocalAudioTrackVector::iterator it = local_audio_tracks_.begin();
576c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org       it != local_audio_tracks_.end(); ++it) {
577c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    ASSERT(it->first != audio_track || it->second != ssrc);
578c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  }
579b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org
580c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  local_audio_tracks_.push_back(std::make_pair(audio_track, ssrc));
581b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org
582b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  // Create the kStatsReportTypeTrack report for the new track if there is no
583b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  // report yet.
584cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  StatsReport* found = reports_.Find(
585b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org      StatsId(StatsReport::kStatsReportTypeTrack, audio_track->id()));
586cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  if (!found)
587b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org    AddTrackReport(&reports_, audio_track->id());
588c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org}
589c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
590c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.orgvoid StatsCollector::RemoveLocalAudioTrack(AudioTrackInterface* audio_track,
591c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org                                           uint32 ssrc) {
592c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  ASSERT(audio_track != NULL);
593c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  for (LocalAudioTrackVector::iterator it = local_audio_tracks_.begin();
594c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org       it != local_audio_tracks_.end(); ++it) {
595c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    if (it->first == audio_track && it->second == ssrc) {
596c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org      local_audio_tracks_.erase(it);
597c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org      return;
598c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    }
599c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  }
600c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
601c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  ASSERT(false);
602c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org}
603c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
604cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.orgvoid StatsCollector::GetStats(MediaStreamTrackInterface* track,
6050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              StatsReports* reports) {
6060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(reports != NULL);
607cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  ASSERT(reports->empty());
6080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!track) {
610cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    StatsSet::const_iterator it;
611cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    for (it = reports_.begin(); it != reports_.end(); ++it)
612cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org      reports->push_back(&(*it));
613cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    return;
6140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
616cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  StatsReport* report =
617cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org      reports_.Find(StatsId(StatsReport::kStatsReportTypeSession,
618cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                            session_->id()));
619cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  if (report)
620cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    reports->push_back(report);
6210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
622cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report = reports_.Find(
623cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org      StatsId(StatsReport::kStatsReportTypeTrack, track->id()));
6240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
625cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  if (!report)
626cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    return;
6270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
628cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  reports->push_back(report);
6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string track_id;
631cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  for (StatsSet::const_iterator it = reports_.begin(); it != reports_.end();
632cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org       ++it) {
633cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    if (it->type != StatsReport::kStatsReportTypeSsrc)
6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      continue;
635cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org
636cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    if (ExtractValueFromReport(*it,
6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               StatsReport::kStatsValueNameTrackId,
6380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               &track_id)) {
6390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (track_id == track->id()) {
640cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org        reports->push_back(&(*it));
6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
6420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
6430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6468a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgvoid
6478a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgStatsCollector::UpdateStats(PeerConnectionInterface::StatsOutputLevel level) {
6480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  double time_now = GetTimeNow();
6490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Calls to UpdateStats() that occur less than kMinGatherStatsPeriod number of
6500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // ms apart will be ignored.
6510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const double kMinGatherStatsPeriod = 50;
652b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  if (stats_gathering_started_ != 0 &&
653b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org      stats_gathering_started_ + kMinGatherStatsPeriod > time_now) {
6540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
6550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  stats_gathering_started_ = time_now;
6570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (session_) {
6590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ExtractSessionInfo();
6600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ExtractVoiceInfo();
6618a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    ExtractVideoInfo(level);
6620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6655c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgStatsReport* StatsCollector::PrepareLocalReport(
6665c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    uint32 ssrc,
667890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    const std::string& transport_id,
668890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    TrackDirection direction) {
6692a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  const std::string ssrc_id = rtc::ToString<uint32>(ssrc);
670cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  StatsReport* report = reports_.Find(
671cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org      StatsId(StatsReport::kStatsReportTypeSsrc, ssrc_id, direction));
6720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
673b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  // Use the ID of the track that is currently mapped to the SSRC, if any.
6740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string track_id;
675b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  if (!GetTrackIdBySsrc(ssrc, &track_id, direction)) {
676cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    if (!report) {
677b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org      // The ssrc is not used by any track or existing report, return NULL
678b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org      // in such case to indicate no report is prepared for the ssrc.
6790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return NULL;
680b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org    }
681b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org
682b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org    // The ssrc is not used by any existing track. Keeps the old track id
683b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org    // since we want to report the stats for inactive ssrc.
684cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    ExtractValueFromReport(*report,
6850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           StatsReport::kStatsValueNameTrackId,
6860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           &track_id);
6870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
689cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report = GetOrCreateReport(
690cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org      StatsReport::kStatsReportTypeSsrc, ssrc_id, direction);
6910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Clear out stats from previous GatherStats calls if any.
693b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  // This is required since the report will be returned for the new values.
694b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  // Having the old values in the report will lead to multiple values with
695b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  // the same name.
696b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  // TODO(xians): Consider changing StatsReport to use map instead of vector.
697b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  report->values.clear();
698b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  report->timestamp = stats_gathering_started_;
6990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameSsrc, ssrc_id);
7010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameTrackId, track_id);
7020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Add the mapping of SSRC to transport.
7030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  report->AddValue(StatsReport::kStatsValueNameTransportId,
7040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   transport_id);
7050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return report;
7060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
7070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7085c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.orgStatsReport* StatsCollector::PrepareRemoteReport(
7095c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    uint32 ssrc,
710890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    const std::string& transport_id,
711890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    TrackDirection direction) {
7122a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  const std::string ssrc_id = rtc::ToString<uint32>(ssrc);
713cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  StatsReport* report = reports_.Find(
714cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org      StatsId(StatsReport::kStatsReportTypeRemoteSsrc, ssrc_id, direction));
7155c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
716b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  // Use the ID of the track that is currently mapped to the SSRC, if any.
7175c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  std::string track_id;
718b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  if (!GetTrackIdBySsrc(ssrc, &track_id, direction)) {
719cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    if (!report) {
720b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org      // The ssrc is not used by any track or existing report, return NULL
721b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org      // in such case to indicate no report is prepared for the ssrc.
7225c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org      return NULL;
723b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org    }
724b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org
725b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org    // The ssrc is not used by any existing track. Keeps the old track id
726b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org    // since we want to report the stats for inactive ssrc.
727cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    ExtractValueFromReport(*report,
7285c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                           StatsReport::kStatsValueNameTrackId,
7295c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                           &track_id);
7305c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  }
7315c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
732cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report = GetOrCreateReport(
733890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      StatsReport::kStatsReportTypeRemoteSsrc, ssrc_id, direction);
7345c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
7355c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  // Clear out stats from previous GatherStats calls if any.
7365c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  // The timestamp will be added later. Zero it for debugging.
7375c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->values.clear();
7385c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->timestamp = 0;
7395c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
7405c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameSsrc, ssrc_id);
7415c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameTrackId, track_id);
7425c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  // Add the mapping of SSRC to transport.
7435c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  report->AddValue(StatsReport::kStatsValueNameTransportId,
7445c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org                   transport_id);
7455c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  return report;
7465c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org}
7475c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
74862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgstd::string StatsCollector::AddOneCertificateReport(
7492a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    const rtc::SSLCertificate* cert, const std::string& issuer_id) {
75062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // TODO(bemasc): Move this computation to a helper class that caches these
75162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // values to reduce CPU use in GetStats.  This will require adding a fast
75262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // SSLCertificate::Equals() method to detect certificate changes.
7538841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org
7548841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org  std::string digest_algorithm;
7558841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org  if (!cert->GetSignatureDigestAlgorithm(&digest_algorithm))
7568841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    return std::string();
7578841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org
7582a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLFingerprint> ssl_fingerprint(
7592a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::SSLFingerprint::Create(digest_algorithm, cert));
7608a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org
7618a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  // SSLFingerprint::Create can fail if the algorithm returned by
7628a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  // SSLCertificate::GetSignatureDigestAlgorithm is not supported by the
7638a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  // implementation of SSLCertificate::ComputeDigest.  This currently happens
7648a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  // with MD5- and SHA-224-signed certificates when linked to libNSS.
7658a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  if (!ssl_fingerprint)
7668a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    return std::string();
7678a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org
76862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  std::string fingerprint = ssl_fingerprint->GetRfc4572Fingerprint();
76962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
7702a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Buffer der_buffer;
77162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  cert->ToDER(&der_buffer);
77262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  std::string der_base64;
7732a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::Base64::EncodeFromArray(
77462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      der_buffer.data(), der_buffer.length(), &der_base64);
77562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
776cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  StatsReport* report = reports_.ReplaceOrAddNew(
777cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org      StatsId(StatsReport::kStatsReportTypeCertificate, fingerprint));
778cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->type = StatsReport::kStatsReportTypeCertificate;
779cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->timestamp = stats_gathering_started_;
780cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFingerprint, fingerprint);
781cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->AddValue(StatsReport::kStatsValueNameFingerprintAlgorithm,
782cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                   digest_algorithm);
783cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->AddValue(StatsReport::kStatsValueNameDer, der_base64);
78462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  if (!issuer_id.empty())
785cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    report->AddValue(StatsReport::kStatsValueNameIssuerId, issuer_id);
786cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  return report->id;
78762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org}
78862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
78962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.orgstd::string StatsCollector::AddCertificateReports(
7902a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    const rtc::SSLCertificate* cert) {
79162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // Produces a chain of StatsReports representing this certificate and the rest
79262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // of its chain, and adds those reports to |reports_|.  The return value is
79362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // the id of the leaf report.  The provided cert must be non-null, so at least
79462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // one report will always be provided and the returned string will never be
79562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // empty.
79662fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  ASSERT(cert != NULL);
79762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
79862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  std::string issuer_id;
7992a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<rtc::SSLCertChain> chain;
80062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  if (cert->GetChain(chain.accept())) {
80162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org    // This loop runs in reverse, i.e. from root to leaf, so that each
80262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org    // certificate's issuer's report ID is known before the child certificate's
80362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org    // report is generated.  The root certificate does not have an issuer ID
80462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org    // value.
80562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org    for (ptrdiff_t i = chain->GetSize() - 1; i >= 0; --i) {
8062a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      const rtc::SSLCertificate& cert_i = chain->Get(i);
80762fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      issuer_id = AddOneCertificateReport(&cert_i, issuer_id);
80862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org    }
80962fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  }
81062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  // Add the leaf certificate.
81162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org  return AddOneCertificateReport(cert, issuer_id);
81262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org}
81362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org
8140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid StatsCollector::ExtractSessionInfo() {
8150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Extract information from the base session.
816cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  StatsReport* report = reports_.ReplaceOrAddNew(
817cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org      StatsId(StatsReport::kStatsReportTypeSession, session_->id()));
818cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->type = StatsReport::kStatsReportTypeSession;
819cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->timestamp = stats_gathering_started_;
820cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->values.clear();
821cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  report->AddBoolean(StatsReport::kStatsValueNameInitiator,
822cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                     session_->initiator());
8230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::SessionStats stats;
8250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (session_->GetStats(&stats)) {
8260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Store the proxy map away for use in SSRC reporting.
8270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    proxy_to_transport_ = stats.proxy_to_transport;
8280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (cricket::TransportStatsMap::iterator transport_iter
8300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             = stats.transport_stats.begin();
8310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org         transport_iter != stats.transport_stats.end(); ++transport_iter) {
83262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      // Attempt to get a copy of the certificates from the transport and
83362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      // expose them in stats reports.  All channels in a transport share the
83462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      // same local and remote certificates.
8354c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org      //
8364c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org      // Note that Transport::GetIdentity and Transport::GetRemoteCertificate
8374c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org      // invoke method calls on the worker thread and block this thread, but
8384c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org      // messages are still processed on this thread, which may blow way the
8394c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org      // existing transports. So we cannot reuse |transport| after these calls.
84062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      std::string local_cert_report_id, remote_cert_report_id;
8414c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org
84262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      cricket::Transport* transport =
84362fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org          session_->GetTransport(transport_iter->second.content_name);
8442a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::scoped_ptr<rtc::SSLIdentity> identity;
8454c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org      if (transport && transport->GetIdentity(identity.accept())) {
8464c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org        local_cert_report_id =
8474c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org            AddCertificateReports(&(identity->certificate()));
8484c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org      }
8494c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org
8504c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org      transport = session_->GetTransport(transport_iter->second.content_name);
8512a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::scoped_ptr<rtc::SSLCertificate> cert;
8524c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org      if (transport && transport->GetRemoteCertificate(cert.accept())) {
8534c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org        remote_cert_report_id = AddCertificateReports(cert.get());
85462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org      }
8554c20a21a2b6ab79feab61457b654ba1e140659dejiayl@webrtc.org
8560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (cricket::TransportChannelStatsList::iterator channel_iter
8570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org               = transport_iter->second.channel_stats.begin();
8580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org           channel_iter != transport_iter->second.channel_stats.end();
8590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org           ++channel_iter) {
8600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        std::ostringstream ostc;
8610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ostc << "Channel-" << transport_iter->second.content_name
8620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             << "-" << channel_iter->component;
863cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org        StatsReport* channel_report = reports_.ReplaceOrAddNew(ostc.str());
864cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org        channel_report->type = StatsReport::kStatsReportTypeComponent;
865cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org        channel_report->timestamp = stats_gathering_started_;
866cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org        channel_report->AddValue(StatsReport::kStatsValueNameComponent,
867cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                                 channel_iter->component);
86862fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org        if (!local_cert_report_id.empty())
869cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          channel_report->AddValue(
87062fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org              StatsReport::kStatsValueNameLocalCertificateId,
87162fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org              local_cert_report_id);
87262fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org        if (!remote_cert_report_id.empty())
873cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          channel_report->AddValue(
87462fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org              StatsReport::kStatsValueNameRemoteCertificateId,
87562fe97f10a7a3200c9724851f6a18537ed270cddwu@webrtc.org              remote_cert_report_id);
8760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        for (size_t i = 0;
8770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             i < channel_iter->connection_infos.size();
8780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             ++i) {
8790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          std::ostringstream ost;
8800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          ost << "Conn-" << transport_iter->first << "-"
8810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org              << channel_iter->component << "-" << i;
882cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          StatsReport* report = reports_.ReplaceOrAddNew(ost.str());
883cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->type = StatsReport::kStatsReportTypeCandidatePair;
884cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->timestamp = stats_gathering_started_;
8850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          // Link from connection to its containing channel.
886cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddValue(StatsReport::kStatsValueNameChannelId,
887cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                           channel_report->id);
888cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org
889cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          const cricket::ConnectionInfo& info =
890cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org              channel_iter->connection_infos[i];
891cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddValue(StatsReport::kStatsValueNameBytesSent,
892cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                           info.sent_total_bytes);
893cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddValue(StatsReport::kStatsValueNameBytesReceived,
894cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                           info.recv_total_bytes);
895cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddBoolean(StatsReport::kStatsValueNameWritable,
896cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                             info.writable);
897cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddBoolean(StatsReport::kStatsValueNameReadable,
898cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                             info.readable);
899cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddBoolean(StatsReport::kStatsValueNameActiveConnection,
900cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                             info.best_connection);
901cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddValue(StatsReport::kStatsValueNameLocalAddress,
902cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                           info.local_candidate.address().ToString());
903cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddValue(StatsReport::kStatsValueNameRemoteAddress,
904cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                           info.remote_candidate.address().ToString());
905cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddValue(StatsReport::kStatsValueNameRtt, info.rtt);
906cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddValue(StatsReport::kStatsValueNameTransportType,
907cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                           info.local_candidate.protocol());
908cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddValue(StatsReport::kStatsValueNameLocalCandidateType,
909cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                           info.local_candidate.type());
910cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org          report->AddValue(StatsReport::kStatsValueNameRemoteCandidateType,
911cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org                           info.remote_candidate.type());
9120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
9130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
9140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
9150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid StatsCollector::ExtractVoiceInfo() {
9190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!session_->voice_channel()) {
9200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
9210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::VoiceMediaInfo voice_info;
9230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!session_->voice_channel()->GetStats(&voice_info)) {
9240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Failed to get voice channel stats.";
9250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
9260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string transport_id;
928676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  if (!GetTransportIdFromProxy(proxy_to_transport_,
929676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org                               session_->voice_channel()->content_name(),
9300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               &transport_id)) {
9310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Failed to get transport name for proxy "
9320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  << session_->voice_channel()->content_name();
9330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
9340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
935890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  ExtractStatsFromList(voice_info.receivers, transport_id, this, kReceiving);
936890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  ExtractStatsFromList(voice_info.senders, transport_id, this, kSending);
937c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
938c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  UpdateStatsFromExistingLocalAudioTracks();
9390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9418a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgvoid StatsCollector::ExtractVideoInfo(
9428a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    PeerConnectionInterface::StatsOutputLevel level) {
9430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!session_->video_channel()) {
9440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
9450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9468a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  cricket::StatsOptions options;
9478a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  options.include_received_propagation_stats =
9488a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org      (level >= PeerConnectionInterface::kStatsOutputLevelDebug) ?
9498a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org          true : false;
9500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::VideoMediaInfo video_info;
9518a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  if (!session_->video_channel()->GetStats(options, &video_info)) {
9520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Failed to get video channel stats.";
9530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
9540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string transport_id;
956676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org  if (!GetTransportIdFromProxy(proxy_to_transport_,
957676a3f8df99a2d3ffdbbac69536c43e875ddca7atommi@webrtc.org                               session_->video_channel()->content_name(),
9580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               &transport_id)) {
9590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Failed to get transport name for proxy "
9600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  << session_->video_channel()->content_name();
9610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
9620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
963890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  ExtractStatsFromList(video_info.receivers, transport_id, this, kReceiving);
964890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  ExtractStatsFromList(video_info.senders, transport_id, this, kSending);
9650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (video_info.bw_estimations.size() != 1) {
9660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "BWEs count: " << video_info.bw_estimations.size();
9670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
968cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    StatsReport* report =
969cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org        reports_.FindOrAddNew(StatsReport::kStatsReportVideoBweId);
9700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ExtractStats(
9718a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org        video_info.bw_estimations[0], stats_gathering_started_, level, report);
9720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
975c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.orgStatsReport* StatsCollector::GetReport(const std::string& type,
976890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                                       const std::string& id,
977890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                                       TrackDirection direction) {
978890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  ASSERT(type == StatsReport::kStatsReportTypeSsrc ||
979890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org         type == StatsReport::kStatsReportTypeRemoteSsrc);
980cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org  return reports_.Find(StatsId(type, id, direction));
981c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org}
982c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
983c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.orgStatsReport* StatsCollector::GetOrCreateReport(const std::string& type,
984890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                                               const std::string& id,
985890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                                               TrackDirection direction) {
986890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  ASSERT(type == StatsReport::kStatsReportTypeSsrc ||
987890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org         type == StatsReport::kStatsReportTypeRemoteSsrc);
988890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  StatsReport* report = GetReport(type, id, direction);
989c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  if (report == NULL) {
990890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    std::string statsid = StatsId(type, id, direction);
991cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    report = reports_.FindOrAddNew(statsid);
992cdfebb33771edb19b50f64f292bd33b86b077745tommi@webrtc.org    ASSERT(report->id == statsid);
9935c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    report->type = type;
9945c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  }
995c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
9965c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  return report;
9975c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org}
9985c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org
999c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.orgvoid StatsCollector::UpdateStatsFromExistingLocalAudioTracks() {
1000c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  // Loop through the existing local audio tracks.
1001c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  for (LocalAudioTrackVector::const_iterator it = local_audio_tracks_.begin();
1002c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org       it != local_audio_tracks_.end(); ++it) {
1003c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    AudioTrackInterface* track = it->first;
1004c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    uint32 ssrc = it->second;
10052a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    std::string ssrc_id = rtc::ToString<uint32>(ssrc);
1006c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    StatsReport* report = GetReport(StatsReport::kStatsReportTypeSsrc,
1007890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                                    ssrc_id,
1008890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                                    kSending);
10096e2c318450409ed8a96e9acfee1bebb4aa72a5b2henrike@webrtc.org    if (report == NULL) {
10106e2c318450409ed8a96e9acfee1bebb4aa72a5b2henrike@webrtc.org      // This can happen if a local audio track is added to a stream on the
10116e2c318450409ed8a96e9acfee1bebb4aa72a5b2henrike@webrtc.org      // fly and the report has not been set up yet. Do nothing in this case.
10126e2c318450409ed8a96e9acfee1bebb4aa72a5b2henrike@webrtc.org      LOG(LS_ERROR) << "Stats report does not exist for ssrc " << ssrc;
10136e2c318450409ed8a96e9acfee1bebb4aa72a5b2henrike@webrtc.org      continue;
10146e2c318450409ed8a96e9acfee1bebb4aa72a5b2henrike@webrtc.org    }
1015c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
1016c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    // The same ssrc can be used by both local and remote audio tracks.
1017c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    std::string track_id;
1018c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    if (!ExtractValueFromReport(*report,
1019c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org                                StatsReport::kStatsValueNameTrackId,
1020c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org                                &track_id) ||
1021c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org        track_id != track->id()) {
1022c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org      continue;
1023c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    }
1024c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
1025c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    UpdateReportFromAudioTrack(track, report);
1026c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  }
1027c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org}
1028c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
1029c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.orgvoid StatsCollector::UpdateReportFromAudioTrack(AudioTrackInterface* track,
1030c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org                                                StatsReport* report) {
1031c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  ASSERT(track != NULL);
1032c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  if (report == NULL)
1033c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    return;
1034c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
1035c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  int signal_level = 0;
1036c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  if (track->GetSignalLevel(&signal_level)) {
1037c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    report->ReplaceValue(StatsReport::kStatsValueNameAudioInputLevel,
10382a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                         rtc::ToString<int>(signal_level));
1039c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  }
1040c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
10412a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_refptr<AudioProcessorInterface> audio_processor(
1042c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org      track->GetAudioProcessor());
1043c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  if (audio_processor.get() == NULL)
1044c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org    return;
1045c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
1046c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  AudioProcessorInterface::AudioProcessorStats stats;
1047c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  audio_processor->GetStats(&stats);
1048c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  report->ReplaceValue(StatsReport::kStatsValueNameTypingNoiseState,
1049c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org                       stats.typing_noise_detected ? "true" : "false");
1050c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  report->ReplaceValue(StatsReport::kStatsValueNameEchoReturnLoss,
10512a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                       rtc::ToString<int>(stats.echo_return_loss));
1052c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  report->ReplaceValue(
1053c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org      StatsReport::kStatsValueNameEchoReturnLossEnhancement,
10542a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::ToString<int>(stats.echo_return_loss_enhancement));
1055c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  report->ReplaceValue(StatsReport::kStatsValueNameEchoDelayMedian,
10562a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                       rtc::ToString<int>(stats.echo_delay_median_ms));
1057c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  report->ReplaceValue(StatsReport::kStatsValueNameEchoCancellationQualityMin,
10582a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                       rtc::ToString<float>(stats.aec_quality_min));
1059c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org  report->ReplaceValue(StatsReport::kStatsValueNameEchoDelayStdDev,
10602a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                       rtc::ToString<int>(stats.echo_delay_std_ms));
1061c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org}
1062c583107e6b398a140dc56f9539b0e01b58af8c61henrike@webrtc.org
1063890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.orgbool StatsCollector::GetTrackIdBySsrc(uint32 ssrc, std::string* track_id,
1064890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                                      TrackDirection direction) {
1065890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  if (direction == kSending) {
1066fd1e42f2876772d9f690207af69eed20f6a99d2etommi@webrtc.org    if (!session_->GetLocalTrackIdBySsrc(ssrc, track_id)) {
1067890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      LOG(LS_WARNING) << "The SSRC " << ssrc
1068890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                      << " is not associated with a sending track";
1069890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      return false;
1070890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    }
1071890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  } else {
1072890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    ASSERT(direction == kReceiving);
1073fd1e42f2876772d9f690207af69eed20f6a99d2etommi@webrtc.org    if (!session_->GetRemoteTrackIdBySsrc(ssrc, track_id)) {
1074890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      LOG(LS_WARNING) << "The SSRC " << ssrc
1075890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org                      << " is not associated with a receiving track";
1076890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      return false;
1077890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    }
1078890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  }
1079890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org
1080890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org  return true;
1081890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org}
1082890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org
1083b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.orgvoid StatsCollector::ClearUpdateStatsCache() {
1084b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org  stats_gathering_started_ = 0;
1085b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org}
1086b87379285e18afb4c4e705a78ac4c1001bfbbc9exians@webrtc.org
10870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}  // namespace webrtc
1088