2016-08-30 14:04:35 -07:00
|
|
|
/*
|
|
|
|
|
* Copyright 2016 The WebRTC project authors. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "pc/rtc_stats_collector.h"
|
2019-07-05 19:08:33 +02:00
|
|
|
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
#include <ctype.h>
|
|
|
|
|
|
|
|
|
|
#include <algorithm>
|
2017-01-20 02:47:10 -08:00
|
|
|
#include <initializer_list>
|
2016-08-30 14:04:35 -07:00
|
|
|
#include <memory>
|
2016-10-25 10:55:08 -07:00
|
|
|
#include <ostream>
|
2016-08-30 14:04:35 -07:00
|
|
|
#include <string>
|
2017-10-30 09:57:42 -07:00
|
|
|
#include <utility>
|
2016-08-30 14:04:35 -07:00
|
|
|
#include <vector>
|
|
|
|
|
|
Use absl::make_unique and absl::WrapUnique directly
Instead of going through our wrappers in ptr_util.h.
This CL was generated by the following script:
git grep -l ptr_util | xargs perl -pi -e 's,#include "rtc_base/ptr_util.h",#include "absl/memory/memory.h",'
git grep -l MakeUnique | xargs perl -pi -e 's,\b(rtc::)?MakeUnique\b,absl::make_unique,g'
git grep -l WrapUnique | xargs perl -pi -e 's,\b(rtc::)?WrapUnique\b,absl::WrapUnique,g'
git checkout -- rtc_base/ptr_util{.h,_unittest.cc}
git cl format
Followed by manually adding dependencies on
//third_party/abseil-cpp/absl/memory until `gn check` stopped
complaining.
Bug: webrtc:9473
Change-Id: I89ccd363f070479b8c431eb2c3d404a46eaacc1c
Reviewed-on: https://webrtc-review.googlesource.com/86600
Commit-Queue: Karl Wiberg <kwiberg@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#23850}
2018-07-05 11:40:33 +02:00
|
|
|
#include "absl/memory/memory.h"
|
2019-02-14 15:13:09 -08:00
|
|
|
#include "absl/strings/str_replace.h"
|
2021-05-21 20:46:09 +02:00
|
|
|
#include "api/dtls_transport_interface.h"
|
2020-10-11 13:03:47 +00:00
|
|
|
#include "api/media_stream_track.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "api/rtp_parameters.h"
|
|
|
|
|
#include "api/stats/rtc_stats_report.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "api/stats/rtcstats_objects.h"
|
2018-05-08 14:52:22 +02:00
|
|
|
#include "api/units/time_delta.h"
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
#include "modules/rtp_rtcp/include/report_block_data.h"
|
|
|
|
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "p2p/base/p2p_constants.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "p2p/base/port.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "pc/media_stream.h"
|
2020-07-09 15:32:34 -07:00
|
|
|
#include "pc/test/fake_data_channel_provider.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "pc/test/fake_peer_connection_for_stats.h"
|
|
|
|
|
#include "pc/test/mock_data_channel.h"
|
|
|
|
|
#include "pc/test/mock_rtp_receiver_internal.h"
|
|
|
|
|
#include "pc/test/mock_rtp_sender_internal.h"
|
|
|
|
|
#include "pc/test/rtc_stats_obtainer.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/checks.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "rtc_base/fake_clock.h"
|
|
|
|
|
#include "rtc_base/fake_ssl_identity.h"
|
2017-09-15 06:47:31 +02:00
|
|
|
#include "rtc_base/gunit.h"
|
|
|
|
|
#include "rtc_base/logging.h"
|
2020-01-09 12:58:23 +01:00
|
|
|
#include "rtc_base/strings/json.h"
|
2020-07-07 19:08:53 +02:00
|
|
|
#include "rtc_base/synchronization/mutex.h"
|
2019-01-11 09:11:00 -08:00
|
|
|
#include "rtc_base/time_utils.h"
|
2016-08-30 14:04:35 -07:00
|
|
|
|
2021-03-18 12:55:11 +01:00
|
|
|
using ::testing::_;
|
2019-04-09 15:11:12 +02:00
|
|
|
using ::testing::AtLeast;
|
|
|
|
|
using ::testing::Invoke;
|
|
|
|
|
using ::testing::Return;
|
2016-08-30 14:04:35 -07:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
|
|
|
|
|
2016-10-25 10:55:08 -07:00
|
|
|
// These are used by gtest code, such as if |EXPECT_EQ| fails.
|
|
|
|
|
void PrintTo(const RTCCertificateStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-10-25 10:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
2016-11-23 02:32:06 -08:00
|
|
|
void PrintTo(const RTCCodecStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-11-23 02:32:06 -08:00
|
|
|
}
|
|
|
|
|
|
2016-10-25 10:55:08 -07:00
|
|
|
void PrintTo(const RTCDataChannelStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-10-25 10:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrintTo(const RTCIceCandidatePairStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-10-25 10:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrintTo(const RTCLocalIceCandidateStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-10-25 10:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrintTo(const RTCRemoteIceCandidateStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-10-25 10:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrintTo(const RTCPeerConnectionStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-10-25 10:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
2016-11-08 06:29:22 -08:00
|
|
|
void PrintTo(const RTCMediaStreamStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-11-08 06:29:22 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrintTo(const RTCMediaStreamTrackStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-11-08 06:29:22 -08:00
|
|
|
}
|
|
|
|
|
|
2016-11-01 03:00:17 -07:00
|
|
|
void PrintTo(const RTCInboundRTPStreamStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-11-01 03:00:17 -07:00
|
|
|
}
|
|
|
|
|
|
2016-11-01 01:50:46 -07:00
|
|
|
void PrintTo(const RTCOutboundRTPStreamStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-11-01 01:50:46 -07:00
|
|
|
}
|
|
|
|
|
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
void PrintTo(const RTCRemoteInboundRtpStreamStats& stats, ::std::ostream* os) {
|
|
|
|
|
*os << stats.ToJson();
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-22 15:49:42 +02:00
|
|
|
void PrintTo(const RTCAudioSourceStats& stats, ::std::ostream* os) {
|
|
|
|
|
*os << stats.ToJson();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PrintTo(const RTCVideoSourceStats& stats, ::std::ostream* os) {
|
|
|
|
|
*os << stats.ToJson();
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-25 10:55:08 -07:00
|
|
|
void PrintTo(const RTCTransportStats& stats, ::std::ostream* os) {
|
2017-07-28 07:29:12 -07:00
|
|
|
*os << stats.ToJson();
|
2016-10-25 10:55:08 -07:00
|
|
|
}
|
|
|
|
|
|
2016-09-05 01:36:50 -07:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
const int64_t kGetStatsReportTimeoutMs = 1000;
|
|
|
|
|
|
2021-03-23 17:23:04 +01:00
|
|
|
// Fake data used by `SetupExampleStatsVoiceGraph()` to fill in remote outbound
|
|
|
|
|
// stats.
|
|
|
|
|
constexpr int64_t kRemoteOutboundStatsTimestampMs = 123;
|
|
|
|
|
constexpr int64_t kRemoteOutboundStatsRemoteTimestampMs = 456;
|
|
|
|
|
constexpr uint32_t kRemoteOutboundStatsPacketsSent = 7u;
|
|
|
|
|
constexpr uint64_t kRemoteOutboundStatsBytesSent = 8u;
|
|
|
|
|
constexpr uint64_t kRemoteOutboundStatsReportsCount = 9u;
|
|
|
|
|
|
2016-10-03 14:16:56 -07:00
|
|
|
struct CertificateInfo {
|
|
|
|
|
rtc::scoped_refptr<rtc::RTCCertificate> certificate;
|
|
|
|
|
std::vector<std::string> ders;
|
|
|
|
|
std::vector<std::string> pems;
|
|
|
|
|
std::vector<std::string> fingerprints;
|
|
|
|
|
};
|
|
|
|
|
|
2018-01-14 09:18:58 +01:00
|
|
|
// Return the ID for an object of the given type in a report.
|
|
|
|
|
// The object must be present and be unique.
|
|
|
|
|
template <typename T>
|
|
|
|
|
std::string IdForType(const RTCStatsReport* report) {
|
|
|
|
|
auto stats_of_my_type = report->RTCStatsReport::GetStatsOfType<T>();
|
|
|
|
|
// We cannot use ASSERT here, since we're within a function.
|
2018-07-03 12:53:23 +02:00
|
|
|
EXPECT_EQ(1U, stats_of_my_type.size())
|
2018-01-14 09:18:58 +01:00
|
|
|
<< "Unexpected number of stats of this type";
|
|
|
|
|
if (stats_of_my_type.size() == 1) {
|
|
|
|
|
return stats_of_my_type[0]->id();
|
|
|
|
|
} else {
|
|
|
|
|
// Return something that is not going to be a valid stas ID.
|
|
|
|
|
return "Type not found";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-03 14:16:56 -07:00
|
|
|
std::unique_ptr<CertificateInfo> CreateFakeCertificateAndInfoFromDers(
|
|
|
|
|
const std::vector<std::string>& ders) {
|
|
|
|
|
RTC_CHECK(!ders.empty());
|
|
|
|
|
std::unique_ptr<CertificateInfo> info(new CertificateInfo());
|
|
|
|
|
info->ders = ders;
|
|
|
|
|
for (const std::string& der : ders) {
|
|
|
|
|
info->pems.push_back(rtc::SSLIdentity::DerToPem(
|
|
|
|
|
"CERTIFICATE", reinterpret_cast<const unsigned char*>(der.c_str()),
|
|
|
|
|
der.length()));
|
|
|
|
|
}
|
|
|
|
|
info->certificate =
|
|
|
|
|
rtc::RTCCertificate::Create(std::unique_ptr<rtc::FakeSSLIdentity>(
|
2018-02-23 13:04:51 -08:00
|
|
|
new rtc::FakeSSLIdentity(info->pems)));
|
2016-10-03 14:16:56 -07:00
|
|
|
// Strip header/footer and newline characters of PEM strings.
|
|
|
|
|
for (size_t i = 0; i < info->pems.size(); ++i) {
|
2019-02-14 15:13:09 -08:00
|
|
|
absl::StrReplaceAll({{"-----BEGIN CERTIFICATE-----", ""},
|
|
|
|
|
{"-----END CERTIFICATE-----", ""},
|
|
|
|
|
{"\n", ""}},
|
|
|
|
|
&info->pems[i]);
|
2016-10-03 14:16:56 -07:00
|
|
|
}
|
2018-02-23 13:04:51 -08:00
|
|
|
// Fingerprints for the whole certificate chain, starting with leaf
|
|
|
|
|
// certificate.
|
2018-10-25 01:16:26 -07:00
|
|
|
const rtc::SSLCertChain& chain = info->certificate->GetSSLCertificateChain();
|
2018-02-23 13:04:51 -08:00
|
|
|
std::unique_ptr<rtc::SSLFingerprint> fp;
|
|
|
|
|
for (size_t i = 0; i < chain.GetSize(); i++) {
|
2018-10-15 19:27:44 -07:00
|
|
|
fp = rtc::SSLFingerprint::Create("sha-1", chain.Get(i));
|
2018-02-23 13:04:51 -08:00
|
|
|
EXPECT_TRUE(fp);
|
|
|
|
|
info->fingerprints.push_back(fp->GetRfc4572Fingerprint());
|
2016-10-03 14:16:56 -07:00
|
|
|
}
|
|
|
|
|
EXPECT_EQ(info->ders.size(), info->fingerprints.size());
|
|
|
|
|
return info;
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-07 02:18:47 -07:00
|
|
|
std::unique_ptr<cricket::Candidate> CreateFakeCandidate(
|
|
|
|
|
const std::string& hostname,
|
|
|
|
|
int port,
|
|
|
|
|
const std::string& protocol,
|
2017-11-21 10:49:36 -08:00
|
|
|
const rtc::AdapterType adapter_type,
|
2016-10-07 02:18:47 -07:00
|
|
|
const std::string& candidate_type,
|
|
|
|
|
uint32_t priority) {
|
|
|
|
|
std::unique_ptr<cricket::Candidate> candidate(new cricket::Candidate());
|
|
|
|
|
candidate->set_address(rtc::SocketAddress(hostname, port));
|
|
|
|
|
candidate->set_protocol(protocol);
|
2017-11-21 10:49:36 -08:00
|
|
|
candidate->set_network_type(adapter_type);
|
2016-10-07 02:18:47 -07:00
|
|
|
candidate->set_type(candidate_type);
|
|
|
|
|
candidate->set_priority(priority);
|
|
|
|
|
return candidate;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-24 13:32:50 -07:00
|
|
|
class FakeAudioProcessor : public AudioProcessorInterface {
|
|
|
|
|
public:
|
|
|
|
|
FakeAudioProcessor() {}
|
|
|
|
|
~FakeAudioProcessor() {}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
AudioProcessorInterface::AudioProcessorStatistics GetStats(
|
|
|
|
|
bool has_recv_streams) override {
|
|
|
|
|
AudioProcessorStatistics stats;
|
|
|
|
|
stats.apm_statistics.echo_return_loss = 2.0;
|
|
|
|
|
stats.apm_statistics.echo_return_loss_enhancement = 3.0;
|
|
|
|
|
return stats;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2016-11-08 06:29:22 -08:00
|
|
|
class FakeAudioTrackForStats : public MediaStreamTrack<AudioTrackInterface> {
|
|
|
|
|
public:
|
|
|
|
|
static rtc::scoped_refptr<FakeAudioTrackForStats> Create(
|
|
|
|
|
const std::string& id,
|
2021-06-24 13:32:50 -07:00
|
|
|
MediaStreamTrackInterface::TrackState state,
|
|
|
|
|
bool create_fake_audio_processor) {
|
2016-11-08 06:29:22 -08:00
|
|
|
rtc::scoped_refptr<FakeAudioTrackForStats> audio_track_stats(
|
2017-01-20 02:47:10 -08:00
|
|
|
new rtc::RefCountedObject<FakeAudioTrackForStats>(id));
|
2016-11-08 06:29:22 -08:00
|
|
|
audio_track_stats->set_state(state);
|
2021-06-24 13:32:50 -07:00
|
|
|
if (create_fake_audio_processor) {
|
|
|
|
|
audio_track_stats->processor_ =
|
|
|
|
|
rtc::make_ref_counted<FakeAudioProcessor>();
|
|
|
|
|
}
|
2016-11-08 06:29:22 -08:00
|
|
|
return audio_track_stats;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-30 09:57:42 -07:00
|
|
|
explicit FakeAudioTrackForStats(const std::string& id)
|
|
|
|
|
: MediaStreamTrack<AudioTrackInterface>(id) {}
|
2016-11-08 06:29:22 -08:00
|
|
|
|
|
|
|
|
std::string kind() const override {
|
|
|
|
|
return MediaStreamTrackInterface::kAudioKind;
|
|
|
|
|
}
|
|
|
|
|
webrtc::AudioSourceInterface* GetSource() const override { return nullptr; }
|
|
|
|
|
void AddSink(webrtc::AudioTrackSinkInterface* sink) override {}
|
|
|
|
|
void RemoveSink(webrtc::AudioTrackSinkInterface* sink) override {}
|
2017-01-20 02:47:10 -08:00
|
|
|
bool GetSignalLevel(int* level) override { return false; }
|
2016-11-08 06:29:22 -08:00
|
|
|
rtc::scoped_refptr<AudioProcessorInterface> GetAudioProcessor() override {
|
2021-06-24 13:32:50 -07:00
|
|
|
return processor_;
|
2016-11-08 06:29:22 -08:00
|
|
|
}
|
2021-06-24 13:32:50 -07:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
rtc::scoped_refptr<FakeAudioProcessor> processor_;
|
2016-11-08 06:29:22 -08:00
|
|
|
};
|
|
|
|
|
|
2019-05-22 15:49:42 +02:00
|
|
|
class FakeVideoTrackSourceForStats : public VideoTrackSourceInterface {
|
|
|
|
|
public:
|
|
|
|
|
static rtc::scoped_refptr<FakeVideoTrackSourceForStats> Create(
|
|
|
|
|
int input_width,
|
|
|
|
|
int input_height) {
|
|
|
|
|
return rtc::scoped_refptr<FakeVideoTrackSourceForStats>(
|
|
|
|
|
new rtc::RefCountedObject<FakeVideoTrackSourceForStats>(input_width,
|
|
|
|
|
input_height));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FakeVideoTrackSourceForStats(int input_width, int input_height)
|
|
|
|
|
: input_width_(input_width), input_height_(input_height) {}
|
|
|
|
|
~FakeVideoTrackSourceForStats() override {}
|
|
|
|
|
|
|
|
|
|
// VideoTrackSourceInterface
|
|
|
|
|
bool is_screencast() const override { return false; }
|
|
|
|
|
absl::optional<bool> needs_denoising() const override { return false; }
|
|
|
|
|
bool GetStats(VideoTrackSourceInterface::Stats* stats) override {
|
|
|
|
|
stats->input_width = input_width_;
|
|
|
|
|
stats->input_height = input_height_;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
// MediaSourceInterface (part of VideoTrackSourceInterface)
|
|
|
|
|
MediaSourceInterface::SourceState state() const override {
|
|
|
|
|
return MediaSourceInterface::SourceState::kLive;
|
|
|
|
|
}
|
|
|
|
|
bool remote() const override { return false; }
|
|
|
|
|
// NotifierInterface (part of MediaSourceInterface)
|
|
|
|
|
void RegisterObserver(ObserverInterface* observer) override {}
|
|
|
|
|
void UnregisterObserver(ObserverInterface* observer) override {}
|
|
|
|
|
// rtc::VideoSourceInterface<VideoFrame> (part of VideoTrackSourceInterface)
|
|
|
|
|
void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
|
|
|
|
|
const rtc::VideoSinkWants& wants) override {}
|
|
|
|
|
void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override {}
|
2020-05-05 20:11:13 +02:00
|
|
|
bool SupportsEncodedOutput() const override { return false; }
|
|
|
|
|
void GenerateKeyFrame() override {}
|
|
|
|
|
void AddEncodedSink(
|
|
|
|
|
rtc::VideoSinkInterface<RecordableEncodedFrame>* sink) override {}
|
|
|
|
|
void RemoveEncodedSink(
|
|
|
|
|
rtc::VideoSinkInterface<RecordableEncodedFrame>* sink) override {}
|
2019-05-22 15:49:42 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
int input_width_;
|
|
|
|
|
int input_height_;
|
|
|
|
|
};
|
|
|
|
|
|
2016-11-08 06:29:22 -08:00
|
|
|
class FakeVideoTrackForStats : public MediaStreamTrack<VideoTrackInterface> {
|
|
|
|
|
public:
|
|
|
|
|
static rtc::scoped_refptr<FakeVideoTrackForStats> Create(
|
|
|
|
|
const std::string& id,
|
2019-05-22 15:49:42 +02:00
|
|
|
MediaStreamTrackInterface::TrackState state,
|
|
|
|
|
rtc::scoped_refptr<VideoTrackSourceInterface> source) {
|
2016-11-08 06:29:22 -08:00
|
|
|
rtc::scoped_refptr<FakeVideoTrackForStats> video_track(
|
2019-05-22 15:49:42 +02:00
|
|
|
new rtc::RefCountedObject<FakeVideoTrackForStats>(id,
|
|
|
|
|
std::move(source)));
|
2016-11-08 06:29:22 -08:00
|
|
|
video_track->set_state(state);
|
|
|
|
|
return video_track;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-22 15:49:42 +02:00
|
|
|
FakeVideoTrackForStats(const std::string& id,
|
|
|
|
|
rtc::scoped_refptr<VideoTrackSourceInterface> source)
|
|
|
|
|
: MediaStreamTrack<VideoTrackInterface>(id), source_(source) {}
|
2016-11-08 06:29:22 -08:00
|
|
|
|
|
|
|
|
std::string kind() const override {
|
|
|
|
|
return MediaStreamTrackInterface::kVideoKind;
|
|
|
|
|
}
|
2017-07-31 23:22:01 -07:00
|
|
|
|
|
|
|
|
void AddOrUpdateSink(rtc::VideoSinkInterface<VideoFrame>* sink,
|
2019-02-25 09:12:02 +01:00
|
|
|
const rtc::VideoSinkWants& wants) override {}
|
|
|
|
|
void RemoveSink(rtc::VideoSinkInterface<VideoFrame>* sink) override {}
|
2017-07-31 23:22:01 -07:00
|
|
|
|
2019-05-22 15:49:42 +02:00
|
|
|
VideoTrackSourceInterface* GetSource() const override {
|
|
|
|
|
return source_.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
rtc::scoped_refptr<VideoTrackSourceInterface> source_;
|
2016-11-08 06:29:22 -08:00
|
|
|
};
|
|
|
|
|
|
2017-01-16 06:16:44 -08:00
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> CreateFakeTrack(
|
|
|
|
|
cricket::MediaType media_type,
|
2017-01-20 02:47:10 -08:00
|
|
|
const std::string& track_id,
|
2021-06-24 13:32:50 -07:00
|
|
|
MediaStreamTrackInterface::TrackState track_state,
|
|
|
|
|
bool create_fake_audio_processor = false) {
|
2017-01-16 06:16:44 -08:00
|
|
|
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
2021-06-24 13:32:50 -07:00
|
|
|
return FakeAudioTrackForStats::Create(track_id, track_state,
|
|
|
|
|
create_fake_audio_processor);
|
2017-01-16 06:16:44 -08:00
|
|
|
} else {
|
|
|
|
|
RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO);
|
2019-05-22 15:49:42 +02:00
|
|
|
return FakeVideoTrackForStats::Create(track_id, track_state, nullptr);
|
2017-01-16 06:16:44 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> CreateMockSender(
|
2019-05-22 15:49:42 +02:00
|
|
|
cricket::MediaType media_type,
|
|
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> track,
|
2018-01-11 17:18:19 +01:00
|
|
|
uint32_t ssrc,
|
2018-01-14 09:18:58 +01:00
|
|
|
int attachment_id,
|
|
|
|
|
std::vector<std::string> local_stream_ids) {
|
2019-05-22 15:49:42 +02:00
|
|
|
RTC_DCHECK(!track ||
|
|
|
|
|
(track->kind() == MediaStreamTrackInterface::kAudioKind &&
|
|
|
|
|
media_type == cricket::MEDIA_TYPE_AUDIO) ||
|
|
|
|
|
(track->kind() == MediaStreamTrackInterface::kVideoKind &&
|
|
|
|
|
media_type == cricket::MEDIA_TYPE_VIDEO));
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> sender(
|
|
|
|
|
new rtc::RefCountedObject<MockRtpSenderInternal>());
|
2017-01-20 02:47:10 -08:00
|
|
|
EXPECT_CALL(*sender, track()).WillRepeatedly(Return(track));
|
|
|
|
|
EXPECT_CALL(*sender, ssrc()).WillRepeatedly(Return(ssrc));
|
2019-05-22 15:49:42 +02:00
|
|
|
EXPECT_CALL(*sender, media_type()).WillRepeatedly(Return(media_type));
|
2017-01-20 02:47:10 -08:00
|
|
|
EXPECT_CALL(*sender, GetParameters()).WillRepeatedly(Invoke([ssrc]() {
|
|
|
|
|
RtpParameters params;
|
|
|
|
|
params.encodings.push_back(RtpEncodingParameters());
|
2017-11-16 10:56:07 +01:00
|
|
|
params.encodings[0].ssrc = ssrc;
|
2017-01-20 02:47:10 -08:00
|
|
|
return params;
|
|
|
|
|
}));
|
2018-01-11 17:18:19 +01:00
|
|
|
EXPECT_CALL(*sender, AttachmentId()).WillRepeatedly(Return(attachment_id));
|
2018-01-14 09:18:58 +01:00
|
|
|
EXPECT_CALL(*sender, stream_ids()).WillRepeatedly(Return(local_stream_ids));
|
2021-03-18 12:55:11 +01:00
|
|
|
EXPECT_CALL(*sender, SetTransceiverAsStopped());
|
|
|
|
|
EXPECT_CALL(*sender, Stop());
|
2017-01-20 02:47:10 -08:00
|
|
|
return sender;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpReceiverInternal> CreateMockReceiver(
|
2017-11-21 17:04:20 +01:00
|
|
|
const rtc::scoped_refptr<MediaStreamTrackInterface>& track,
|
2018-01-11 17:18:19 +01:00
|
|
|
uint32_t ssrc,
|
|
|
|
|
int attachment_id) {
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpReceiverInternal> receiver(
|
|
|
|
|
new rtc::RefCountedObject<MockRtpReceiverInternal>());
|
2017-01-20 02:47:10 -08:00
|
|
|
EXPECT_CALL(*receiver, track()).WillRepeatedly(Return(track));
|
2018-01-14 09:18:58 +01:00
|
|
|
EXPECT_CALL(*receiver, streams())
|
|
|
|
|
.WillRepeatedly(
|
|
|
|
|
Return(std::vector<rtc::scoped_refptr<MediaStreamInterface>>({})));
|
|
|
|
|
|
2017-01-20 02:47:10 -08:00
|
|
|
EXPECT_CALL(*receiver, media_type())
|
|
|
|
|
.WillRepeatedly(
|
|
|
|
|
Return(track->kind() == MediaStreamTrackInterface::kAudioKind
|
|
|
|
|
? cricket::MEDIA_TYPE_AUDIO
|
|
|
|
|
: cricket::MEDIA_TYPE_VIDEO));
|
|
|
|
|
EXPECT_CALL(*receiver, GetParameters()).WillRepeatedly(Invoke([ssrc]() {
|
|
|
|
|
RtpParameters params;
|
|
|
|
|
params.encodings.push_back(RtpEncodingParameters());
|
2017-11-16 10:56:07 +01:00
|
|
|
params.encodings[0].ssrc = ssrc;
|
2017-01-20 02:47:10 -08:00
|
|
|
return params;
|
|
|
|
|
}));
|
2018-01-11 17:18:19 +01:00
|
|
|
EXPECT_CALL(*receiver, AttachmentId()).WillRepeatedly(Return(attachment_id));
|
2021-03-18 12:55:11 +01:00
|
|
|
EXPECT_CALL(*receiver, StopAndEndTrack());
|
2017-01-20 02:47:10 -08:00
|
|
|
return receiver;
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
class RTCStatsCollectorWrapper {
|
2016-08-30 14:04:35 -07:00
|
|
|
public:
|
2018-02-02 16:00:20 -08:00
|
|
|
explicit RTCStatsCollectorWrapper(
|
|
|
|
|
rtc::scoped_refptr<FakePeerConnectionForStats> pc)
|
|
|
|
|
: pc_(pc),
|
|
|
|
|
stats_collector_(
|
|
|
|
|
RTCStatsCollector::Create(pc, 50 * rtc::kNumMicrosecsPerMillisec)) {
|
2016-08-30 14:04:35 -07:00
|
|
|
}
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<RTCStatsCollector> stats_collector() {
|
|
|
|
|
return stats_collector_;
|
2016-08-30 14:04:35 -07:00
|
|
|
}
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> GetStatsReport() {
|
|
|
|
|
rtc::scoped_refptr<RTCStatsObtainer> callback = RTCStatsObtainer::Create();
|
|
|
|
|
stats_collector_->GetStatsReport(callback);
|
2018-03-19 13:52:56 +01:00
|
|
|
return WaitForReport(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> GetStatsReportWithSenderSelector(
|
|
|
|
|
rtc::scoped_refptr<RtpSenderInternal> selector) {
|
|
|
|
|
rtc::scoped_refptr<RTCStatsObtainer> callback = RTCStatsObtainer::Create();
|
|
|
|
|
stats_collector_->GetStatsReport(selector, callback);
|
|
|
|
|
return WaitForReport(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> GetStatsReportWithReceiverSelector(
|
|
|
|
|
rtc::scoped_refptr<RtpReceiverInternal> selector) {
|
|
|
|
|
rtc::scoped_refptr<RTCStatsObtainer> callback = RTCStatsObtainer::Create();
|
|
|
|
|
stats_collector_->GetStatsReport(selector, callback);
|
|
|
|
|
return WaitForReport(callback);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> GetFreshStatsReport() {
|
|
|
|
|
stats_collector_->ClearCachedStatsReport();
|
|
|
|
|
return GetStatsReport();
|
2016-08-30 14:04:35 -07:00
|
|
|
}
|
|
|
|
|
|
2018-03-19 13:52:56 +01:00
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> SetupLocalTrackAndSender(
|
|
|
|
|
cricket::MediaType media_type,
|
|
|
|
|
const std::string& track_id,
|
|
|
|
|
uint32_t ssrc,
|
2019-05-22 15:49:42 +02:00
|
|
|
bool add_stream,
|
|
|
|
|
int attachment_id) {
|
2018-01-02 14:08:34 +01:00
|
|
|
rtc::scoped_refptr<MediaStream> local_stream;
|
|
|
|
|
if (add_stream) {
|
2018-03-02 11:34:10 -08:00
|
|
|
local_stream = MediaStream::Create("LocalStreamId");
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->mutable_local_streams()->AddStream(local_stream);
|
2018-01-02 14:08:34 +01:00
|
|
|
}
|
2017-01-16 06:16:44 -08:00
|
|
|
|
|
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> track;
|
|
|
|
|
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
2017-01-20 02:47:10 -08:00
|
|
|
track = CreateFakeTrack(media_type, track_id,
|
|
|
|
|
MediaStreamTrackInterface::kLive);
|
2018-01-02 14:08:34 +01:00
|
|
|
if (add_stream) {
|
|
|
|
|
local_stream->AddTrack(static_cast<AudioTrackInterface*>(track.get()));
|
|
|
|
|
}
|
2017-01-16 06:16:44 -08:00
|
|
|
} else {
|
2017-01-20 02:47:10 -08:00
|
|
|
track = CreateFakeTrack(media_type, track_id,
|
|
|
|
|
MediaStreamTrackInterface::kLive);
|
2018-01-02 14:08:34 +01:00
|
|
|
if (add_stream) {
|
|
|
|
|
local_stream->AddTrack(static_cast<VideoTrackInterface*>(track.get()));
|
|
|
|
|
}
|
2017-01-16 06:16:44 -08:00
|
|
|
}
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> sender =
|
2019-05-22 15:49:42 +02:00
|
|
|
CreateMockSender(media_type, track, ssrc, attachment_id, {});
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddSender(sender);
|
2018-03-19 13:52:56 +01:00
|
|
|
return sender;
|
2017-01-16 06:16:44 -08:00
|
|
|
}
|
|
|
|
|
|
2018-03-19 13:52:56 +01:00
|
|
|
rtc::scoped_refptr<MockRtpReceiverInternal> SetupRemoteTrackAndReceiver(
|
|
|
|
|
cricket::MediaType media_type,
|
|
|
|
|
const std::string& track_id,
|
|
|
|
|
const std::string& stream_id,
|
|
|
|
|
uint32_t ssrc) {
|
2017-01-16 06:16:44 -08:00
|
|
|
rtc::scoped_refptr<MediaStream> remote_stream =
|
2018-03-19 13:52:56 +01:00
|
|
|
MediaStream::Create(stream_id);
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->mutable_remote_streams()->AddStream(remote_stream);
|
2017-01-16 06:16:44 -08:00
|
|
|
|
|
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> track;
|
|
|
|
|
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
|
2017-01-20 02:47:10 -08:00
|
|
|
track = CreateFakeTrack(media_type, track_id,
|
|
|
|
|
MediaStreamTrackInterface::kLive);
|
2017-01-16 06:16:44 -08:00
|
|
|
remote_stream->AddTrack(static_cast<AudioTrackInterface*>(track.get()));
|
|
|
|
|
} else {
|
2017-01-20 02:47:10 -08:00
|
|
|
track = CreateFakeTrack(media_type, track_id,
|
|
|
|
|
MediaStreamTrackInterface::kLive);
|
2017-01-16 06:16:44 -08:00
|
|
|
remote_stream->AddTrack(static_cast<VideoTrackInterface*>(track.get()));
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpReceiverInternal> receiver =
|
2018-01-11 17:18:19 +01:00
|
|
|
CreateMockReceiver(track, ssrc, 62);
|
2018-01-14 09:18:58 +01:00
|
|
|
EXPECT_CALL(*receiver, streams())
|
|
|
|
|
.WillRepeatedly(
|
|
|
|
|
Return(std::vector<rtc::scoped_refptr<MediaStreamInterface>>(
|
|
|
|
|
{remote_stream})));
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddReceiver(receiver);
|
2018-03-19 13:52:56 +01:00
|
|
|
return receiver;
|
2017-01-16 06:16:44 -08:00
|
|
|
}
|
|
|
|
|
|
2017-01-20 02:47:10 -08:00
|
|
|
// Attaches tracks to peer connections by configuring RTP senders and RTP
|
|
|
|
|
// receivers according to the tracks' pairings with
|
|
|
|
|
// |[Voice/Video][Sender/Receiver]Info| and their SSRCs. Local tracks can be
|
|
|
|
|
// associated with multiple |[Voice/Video]SenderInfo|s, remote tracks can only
|
|
|
|
|
// be associated with one |[Voice/Video]ReceiverInfo|.
|
2019-05-22 15:49:42 +02:00
|
|
|
// Senders get assigned attachment ID "ssrc + 10".
|
2017-01-20 02:47:10 -08:00
|
|
|
void CreateMockRtpSendersReceiversAndChannels(
|
2018-01-14 09:18:58 +01:00
|
|
|
std::initializer_list<
|
|
|
|
|
std::pair<MediaStreamTrackInterface*, cricket::VoiceSenderInfo>>
|
|
|
|
|
local_audio_track_info_pairs,
|
|
|
|
|
std::initializer_list<
|
|
|
|
|
std::pair<MediaStreamTrackInterface*, cricket::VoiceReceiverInfo>>
|
|
|
|
|
remote_audio_track_info_pairs,
|
|
|
|
|
std::initializer_list<
|
|
|
|
|
std::pair<MediaStreamTrackInterface*, cricket::VideoSenderInfo>>
|
|
|
|
|
local_video_track_info_pairs,
|
|
|
|
|
std::initializer_list<
|
|
|
|
|
std::pair<MediaStreamTrackInterface*, cricket::VideoReceiverInfo>>
|
|
|
|
|
remote_video_track_info_pairs,
|
|
|
|
|
std::vector<std::string> local_stream_ids,
|
|
|
|
|
std::vector<rtc::scoped_refptr<MediaStreamInterface>> remote_streams) {
|
2018-02-02 16:00:20 -08:00
|
|
|
cricket::VoiceMediaInfo voice_media_info;
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
|
|
|
|
|
2017-01-20 02:47:10 -08:00
|
|
|
// Local audio tracks and voice sender infos
|
|
|
|
|
for (auto& pair : local_audio_track_info_pairs) {
|
|
|
|
|
MediaStreamTrackInterface* local_audio_track = pair.first;
|
|
|
|
|
const cricket::VoiceSenderInfo& voice_sender_info = pair.second;
|
|
|
|
|
RTC_DCHECK_EQ(local_audio_track->kind(),
|
|
|
|
|
MediaStreamTrackInterface::kAudioKind);
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
voice_media_info.senders.push_back(voice_sender_info);
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> rtp_sender = CreateMockSender(
|
2019-05-22 15:49:42 +02:00
|
|
|
cricket::MEDIA_TYPE_AUDIO,
|
2018-01-11 17:18:19 +01:00
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface>(local_audio_track),
|
2019-05-22 15:49:42 +02:00
|
|
|
voice_sender_info.local_stats[0].ssrc,
|
|
|
|
|
voice_sender_info.local_stats[0].ssrc + 10, local_stream_ids);
|
2021-03-18 12:55:11 +01:00
|
|
|
EXPECT_CALL(*rtp_sender, SetMediaChannel(_));
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddSender(rtp_sender);
|
2017-01-20 02:47:10 -08:00
|
|
|
}
|
2018-02-02 16:00:20 -08:00
|
|
|
|
2017-01-20 02:47:10 -08:00
|
|
|
// Remote audio tracks and voice receiver infos
|
|
|
|
|
for (auto& pair : remote_audio_track_info_pairs) {
|
|
|
|
|
MediaStreamTrackInterface* remote_audio_track = pair.first;
|
|
|
|
|
const cricket::VoiceReceiverInfo& voice_receiver_info = pair.second;
|
|
|
|
|
RTC_DCHECK_EQ(remote_audio_track->kind(),
|
|
|
|
|
MediaStreamTrackInterface::kAudioKind);
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
voice_media_info.receivers.push_back(voice_receiver_info);
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpReceiverInternal> rtp_receiver =
|
|
|
|
|
CreateMockReceiver(
|
|
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface>(remote_audio_track),
|
2019-05-22 15:49:42 +02:00
|
|
|
voice_receiver_info.local_stats[0].ssrc,
|
|
|
|
|
voice_receiver_info.local_stats[0].ssrc + 10);
|
2018-01-14 09:18:58 +01:00
|
|
|
EXPECT_CALL(*rtp_receiver, streams())
|
|
|
|
|
.WillRepeatedly(Return(remote_streams));
|
2021-03-18 12:55:11 +01:00
|
|
|
EXPECT_CALL(*rtp_receiver, SetMediaChannel(_));
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddReceiver(rtp_receiver);
|
2017-01-20 02:47:10 -08:00
|
|
|
}
|
2018-02-02 16:00:20 -08:00
|
|
|
|
2017-01-20 02:47:10 -08:00
|
|
|
// Local video tracks and video sender infos
|
|
|
|
|
for (auto& pair : local_video_track_info_pairs) {
|
|
|
|
|
MediaStreamTrackInterface* local_video_track = pair.first;
|
|
|
|
|
const cricket::VideoSenderInfo& video_sender_info = pair.second;
|
|
|
|
|
RTC_DCHECK_EQ(local_video_track->kind(),
|
|
|
|
|
MediaStreamTrackInterface::kVideoKind);
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
video_media_info.senders.push_back(video_sender_info);
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
video_media_info.aggregated_senders.push_back(video_sender_info);
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> rtp_sender = CreateMockSender(
|
2019-05-22 15:49:42 +02:00
|
|
|
cricket::MEDIA_TYPE_VIDEO,
|
2018-01-11 17:18:19 +01:00
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface>(local_video_track),
|
2019-05-22 15:49:42 +02:00
|
|
|
video_sender_info.local_stats[0].ssrc,
|
|
|
|
|
video_sender_info.local_stats[0].ssrc + 10, local_stream_ids);
|
2021-03-18 12:55:11 +01:00
|
|
|
EXPECT_CALL(*rtp_sender, SetMediaChannel(_));
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddSender(rtp_sender);
|
2017-01-20 02:47:10 -08:00
|
|
|
}
|
2018-02-02 16:00:20 -08:00
|
|
|
|
2017-01-20 02:47:10 -08:00
|
|
|
// Remote video tracks and video receiver infos
|
|
|
|
|
for (auto& pair : remote_video_track_info_pairs) {
|
|
|
|
|
MediaStreamTrackInterface* remote_video_track = pair.first;
|
|
|
|
|
const cricket::VideoReceiverInfo& video_receiver_info = pair.second;
|
|
|
|
|
RTC_DCHECK_EQ(remote_video_track->kind(),
|
|
|
|
|
MediaStreamTrackInterface::kVideoKind);
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
video_media_info.receivers.push_back(video_receiver_info);
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpReceiverInternal> rtp_receiver =
|
|
|
|
|
CreateMockReceiver(
|
|
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface>(remote_video_track),
|
2019-05-22 15:49:42 +02:00
|
|
|
video_receiver_info.local_stats[0].ssrc,
|
|
|
|
|
video_receiver_info.local_stats[0].ssrc + 10);
|
2018-01-14 09:18:58 +01:00
|
|
|
EXPECT_CALL(*rtp_receiver, streams())
|
|
|
|
|
.WillRepeatedly(Return(remote_streams));
|
2021-03-18 12:55:11 +01:00
|
|
|
EXPECT_CALL(*rtp_receiver, SetMediaChannel(_));
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddReceiver(rtp_receiver);
|
2017-01-20 02:47:10 -08:00
|
|
|
}
|
2016-09-05 01:36:50 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
auto* voice_media_channel = pc_->AddVoiceChannel("audio", "transport");
|
|
|
|
|
voice_media_channel->SetStats(voice_media_info);
|
2016-09-05 01:36:50 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
auto* video_media_channel = pc_->AddVideoChannel("video", "transport");
|
|
|
|
|
video_media_channel->SetStats(video_media_info);
|
2016-09-05 01:36:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
2018-03-19 13:52:56 +01:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> WaitForReport(
|
|
|
|
|
rtc::scoped_refptr<RTCStatsObtainer> callback) {
|
|
|
|
|
EXPECT_TRUE_WAIT(callback->report(), kGetStatsReportTimeoutMs);
|
|
|
|
|
int64_t after = rtc::TimeUTCMicros();
|
|
|
|
|
for (const RTCStats& stats : *callback->report()) {
|
2021-03-23 17:23:04 +01:00
|
|
|
if (stats.type() == RTCRemoteInboundRtpStreamStats::kType ||
|
|
|
|
|
stats.type() == RTCRemoteOutboundRtpStreamStats::kType) {
|
|
|
|
|
// Ignore remote timestamps.
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2018-03-19 13:52:56 +01:00
|
|
|
EXPECT_LE(stats.timestamp_us(), after);
|
|
|
|
|
}
|
|
|
|
|
return callback->report();
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<FakePeerConnectionForStats> pc_;
|
|
|
|
|
rtc::scoped_refptr<RTCStatsCollector> stats_collector_;
|
2016-09-05 01:36:50 -07:00
|
|
|
};
|
|
|
|
|
|
2019-04-09 15:11:12 +02:00
|
|
|
class RTCStatsCollectorTest : public ::testing::Test {
|
2016-08-30 14:04:35 -07:00
|
|
|
public:
|
|
|
|
|
RTCStatsCollectorTest()
|
2018-02-02 16:00:20 -08:00
|
|
|
: pc_(new rtc::RefCountedObject<FakePeerConnectionForStats>()),
|
|
|
|
|
stats_(new RTCStatsCollectorWrapper(pc_)) {}
|
2016-08-30 14:04:35 -07:00
|
|
|
|
2016-10-03 14:16:56 -07:00
|
|
|
void ExpectReportContainsCertificateInfo(
|
|
|
|
|
const rtc::scoped_refptr<const RTCStatsReport>& report,
|
2016-12-21 04:29:17 -08:00
|
|
|
const CertificateInfo& certinfo) {
|
|
|
|
|
for (size_t i = 0; i < certinfo.fingerprints.size(); ++i) {
|
|
|
|
|
RTCCertificateStats expected_certificate_stats(
|
|
|
|
|
"RTCCertificate_" + certinfo.fingerprints[i], report->timestamp_us());
|
|
|
|
|
expected_certificate_stats.fingerprint = certinfo.fingerprints[i];
|
|
|
|
|
expected_certificate_stats.fingerprint_algorithm = "sha-1";
|
|
|
|
|
expected_certificate_stats.base64_certificate = certinfo.pems[i];
|
|
|
|
|
if (i + 1 < certinfo.fingerprints.size()) {
|
|
|
|
|
expected_certificate_stats.issuer_certificate_id =
|
|
|
|
|
"RTCCertificate_" + certinfo.fingerprints[i + 1];
|
2016-10-03 14:16:56 -07:00
|
|
|
}
|
2016-12-21 04:29:17 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_certificate_stats.id()));
|
|
|
|
|
EXPECT_EQ(expected_certificate_stats,
|
|
|
|
|
report->Get(expected_certificate_stats.id())
|
|
|
|
|
->cast_to<RTCCertificateStats>());
|
2016-10-03 14:16:56 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-19 13:52:56 +01:00
|
|
|
struct ExampleStatsGraph {
|
|
|
|
|
rtc::scoped_refptr<RtpSenderInternal> sender;
|
|
|
|
|
rtc::scoped_refptr<RtpReceiverInternal> receiver;
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> full_report;
|
|
|
|
|
std::string send_codec_id;
|
|
|
|
|
std::string recv_codec_id;
|
|
|
|
|
std::string outbound_rtp_id;
|
|
|
|
|
std::string inbound_rtp_id;
|
2021-03-23 17:23:04 +01:00
|
|
|
std::string remote_outbound_rtp_id;
|
2018-03-19 13:52:56 +01:00
|
|
|
std::string transport_id;
|
|
|
|
|
std::string sender_track_id;
|
|
|
|
|
std::string receiver_track_id;
|
|
|
|
|
std::string remote_stream_id;
|
|
|
|
|
std::string peer_connection_id;
|
2019-05-22 15:49:42 +02:00
|
|
|
std::string media_source_id;
|
2018-03-19 13:52:56 +01:00
|
|
|
};
|
|
|
|
|
|
2021-03-23 17:23:04 +01:00
|
|
|
// Sets up the example stats graph (see ASCII art below) for a video only
|
|
|
|
|
// call. The graph is used for testing the stats selection algorithm (see
|
|
|
|
|
// https://w3c.github.io/webrtc-pc/#dfn-stats-selection-algorithm).
|
2018-03-19 13:52:56 +01:00
|
|
|
// These tests test the integration of the stats traversal algorithm inside of
|
|
|
|
|
// RTCStatsCollector. See rtcstatstraveral_unittest.cc for more stats
|
|
|
|
|
// traversal tests.
|
|
|
|
|
ExampleStatsGraph SetupExampleStatsGraphForSelectorTests() {
|
|
|
|
|
ExampleStatsGraph graph;
|
|
|
|
|
|
|
|
|
|
// codec (send)
|
|
|
|
|
graph.send_codec_id = "RTCCodec_VideoMid_Outbound_1";
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
|
|
|
|
RtpCodecParameters send_codec;
|
|
|
|
|
send_codec.payload_type = 1;
|
|
|
|
|
send_codec.clock_rate = 0;
|
|
|
|
|
video_media_info.send_codecs.insert(
|
|
|
|
|
std::make_pair(send_codec.payload_type, send_codec));
|
|
|
|
|
// codec (recv)
|
|
|
|
|
graph.recv_codec_id = "RTCCodec_VideoMid_Inbound_2";
|
|
|
|
|
RtpCodecParameters recv_codec;
|
|
|
|
|
recv_codec.payload_type = 2;
|
|
|
|
|
recv_codec.clock_rate = 0;
|
|
|
|
|
video_media_info.receive_codecs.insert(
|
|
|
|
|
std::make_pair(recv_codec.payload_type, recv_codec));
|
|
|
|
|
// outbound-rtp
|
|
|
|
|
graph.outbound_rtp_id = "RTCOutboundRTPVideoStream_3";
|
|
|
|
|
video_media_info.senders.push_back(cricket::VideoSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats.push_back(
|
|
|
|
|
cricket::SsrcSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats[0].ssrc = 3;
|
|
|
|
|
video_media_info.senders[0].codec_payload_type = send_codec.payload_type;
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
video_media_info.aggregated_senders.push_back(video_media_info.senders[0]);
|
2018-03-19 13:52:56 +01:00
|
|
|
// inbound-rtp
|
|
|
|
|
graph.inbound_rtp_id = "RTCInboundRTPVideoStream_4";
|
|
|
|
|
video_media_info.receivers.push_back(cricket::VideoReceiverInfo());
|
|
|
|
|
video_media_info.receivers[0].local_stats.push_back(
|
|
|
|
|
cricket::SsrcReceiverInfo());
|
|
|
|
|
video_media_info.receivers[0].local_stats[0].ssrc = 4;
|
|
|
|
|
video_media_info.receivers[0].codec_payload_type = recv_codec.payload_type;
|
|
|
|
|
// transport
|
|
|
|
|
graph.transport_id = "RTCTransport_TransportName_1";
|
|
|
|
|
auto* video_media_channel =
|
|
|
|
|
pc_->AddVideoChannel("VideoMid", "TransportName");
|
|
|
|
|
video_media_channel->SetStats(video_media_info);
|
|
|
|
|
// track (sender)
|
|
|
|
|
graph.sender = stats_->SetupLocalTrackAndSender(
|
2019-05-22 15:49:42 +02:00
|
|
|
cricket::MEDIA_TYPE_VIDEO, "LocalVideoTrackID", 3, false, 50);
|
2018-03-19 13:52:56 +01:00
|
|
|
graph.sender_track_id = "RTCMediaStreamTrack_sender_" +
|
2018-07-05 11:59:48 +02:00
|
|
|
rtc::ToString(graph.sender->AttachmentId());
|
2018-03-19 13:52:56 +01:00
|
|
|
// track (receiver) and stream (remote stream)
|
|
|
|
|
graph.receiver = stats_->SetupRemoteTrackAndReceiver(
|
|
|
|
|
cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID", "RemoteStreamId", 4);
|
|
|
|
|
graph.receiver_track_id = "RTCMediaStreamTrack_receiver_" +
|
2018-07-05 11:59:48 +02:00
|
|
|
rtc::ToString(graph.receiver->AttachmentId());
|
2018-03-19 13:52:56 +01:00
|
|
|
graph.remote_stream_id = "RTCMediaStream_RemoteStreamId";
|
|
|
|
|
// peer-connection
|
|
|
|
|
graph.peer_connection_id = "RTCPeerConnection";
|
2019-05-22 15:49:42 +02:00
|
|
|
// media-source (kind: video)
|
|
|
|
|
graph.media_source_id =
|
|
|
|
|
"RTCVideoSource_" + rtc::ToString(graph.sender->AttachmentId());
|
2018-03-19 13:52:56 +01:00
|
|
|
|
|
|
|
|
// Expected stats graph:
|
|
|
|
|
//
|
2019-05-22 15:49:42 +02:00
|
|
|
// +--- track (sender) stream (remote stream) ---> track (receiver)
|
|
|
|
|
// | ^ ^
|
|
|
|
|
// | | |
|
|
|
|
|
// | +--------- outbound-rtp inbound-rtp ---------------+
|
|
|
|
|
// | | | | | |
|
|
|
|
|
// | | v v v v
|
|
|
|
|
// | | codec (send) transport codec (recv) peer-connection
|
|
|
|
|
// v v
|
|
|
|
|
// media-source
|
2018-03-19 13:52:56 +01:00
|
|
|
|
|
|
|
|
// Verify the stats graph is set up correctly.
|
|
|
|
|
graph.full_report = stats_->GetStatsReport();
|
2019-05-22 15:49:42 +02:00
|
|
|
EXPECT_EQ(graph.full_report->size(), 10u);
|
2018-03-19 13:52:56 +01:00
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.send_codec_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.recv_codec_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.outbound_rtp_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.inbound_rtp_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.transport_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.sender_track_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.receiver_track_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.remote_stream_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.peer_connection_id));
|
2019-05-22 15:49:42 +02:00
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.media_source_id));
|
|
|
|
|
const auto& sender_track = graph.full_report->Get(graph.sender_track_id)
|
|
|
|
|
->cast_to<RTCMediaStreamTrackStats>();
|
|
|
|
|
EXPECT_EQ(*sender_track.media_source_id, graph.media_source_id);
|
2018-03-19 13:52:56 +01:00
|
|
|
const auto& outbound_rtp = graph.full_report->Get(graph.outbound_rtp_id)
|
|
|
|
|
->cast_to<RTCOutboundRTPStreamStats>();
|
2019-05-22 15:49:42 +02:00
|
|
|
EXPECT_EQ(*outbound_rtp.media_source_id, graph.media_source_id);
|
2018-03-19 13:52:56 +01:00
|
|
|
EXPECT_EQ(*outbound_rtp.codec_id, graph.send_codec_id);
|
|
|
|
|
EXPECT_EQ(*outbound_rtp.track_id, graph.sender_track_id);
|
|
|
|
|
EXPECT_EQ(*outbound_rtp.transport_id, graph.transport_id);
|
|
|
|
|
const auto& inbound_rtp = graph.full_report->Get(graph.inbound_rtp_id)
|
|
|
|
|
->cast_to<RTCInboundRTPStreamStats>();
|
|
|
|
|
EXPECT_EQ(*inbound_rtp.codec_id, graph.recv_codec_id);
|
|
|
|
|
EXPECT_EQ(*inbound_rtp.track_id, graph.receiver_track_id);
|
|
|
|
|
EXPECT_EQ(*inbound_rtp.transport_id, graph.transport_id);
|
|
|
|
|
|
|
|
|
|
return graph;
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-23 17:23:04 +01:00
|
|
|
// Sets up an example stats graph (see ASCII art below) for an audio only call
|
|
|
|
|
// and checks that the expected stats are generated.
|
|
|
|
|
ExampleStatsGraph SetupExampleStatsVoiceGraph(
|
|
|
|
|
bool add_remote_outbound_stats) {
|
|
|
|
|
constexpr uint32_t kLocalSsrc = 3;
|
|
|
|
|
constexpr uint32_t kRemoteSsrc = 4;
|
|
|
|
|
ExampleStatsGraph graph;
|
|
|
|
|
|
|
|
|
|
// codec (send)
|
|
|
|
|
graph.send_codec_id = "RTCCodec_VoiceMid_Outbound_1";
|
|
|
|
|
cricket::VoiceMediaInfo media_info;
|
|
|
|
|
RtpCodecParameters send_codec;
|
|
|
|
|
send_codec.payload_type = 1;
|
|
|
|
|
send_codec.clock_rate = 0;
|
|
|
|
|
media_info.send_codecs.insert(
|
|
|
|
|
std::make_pair(send_codec.payload_type, send_codec));
|
|
|
|
|
// codec (recv)
|
|
|
|
|
graph.recv_codec_id = "RTCCodec_VoiceMid_Inbound_2";
|
|
|
|
|
RtpCodecParameters recv_codec;
|
|
|
|
|
recv_codec.payload_type = 2;
|
|
|
|
|
recv_codec.clock_rate = 0;
|
|
|
|
|
media_info.receive_codecs.insert(
|
|
|
|
|
std::make_pair(recv_codec.payload_type, recv_codec));
|
|
|
|
|
// outbound-rtp
|
|
|
|
|
graph.outbound_rtp_id = "RTCOutboundRTPAudioStream_3";
|
|
|
|
|
media_info.senders.push_back(cricket::VoiceSenderInfo());
|
|
|
|
|
media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
media_info.senders[0].local_stats[0].ssrc = kLocalSsrc;
|
|
|
|
|
media_info.senders[0].codec_payload_type = send_codec.payload_type;
|
|
|
|
|
// inbound-rtp
|
|
|
|
|
graph.inbound_rtp_id = "RTCInboundRTPAudioStream_4";
|
|
|
|
|
media_info.receivers.push_back(cricket::VoiceReceiverInfo());
|
|
|
|
|
media_info.receivers[0].local_stats.push_back(cricket::SsrcReceiverInfo());
|
|
|
|
|
media_info.receivers[0].local_stats[0].ssrc = kRemoteSsrc;
|
|
|
|
|
media_info.receivers[0].codec_payload_type = recv_codec.payload_type;
|
|
|
|
|
// remote-outbound-rtp
|
|
|
|
|
if (add_remote_outbound_stats) {
|
|
|
|
|
graph.remote_outbound_rtp_id = "RTCRemoteOutboundRTPAudioStream_4";
|
|
|
|
|
media_info.receivers[0].last_sender_report_timestamp_ms =
|
|
|
|
|
kRemoteOutboundStatsTimestampMs;
|
|
|
|
|
media_info.receivers[0].last_sender_report_remote_timestamp_ms =
|
|
|
|
|
kRemoteOutboundStatsRemoteTimestampMs;
|
|
|
|
|
media_info.receivers[0].sender_reports_packets_sent =
|
|
|
|
|
kRemoteOutboundStatsPacketsSent;
|
|
|
|
|
media_info.receivers[0].sender_reports_bytes_sent =
|
|
|
|
|
kRemoteOutboundStatsBytesSent;
|
|
|
|
|
media_info.receivers[0].sender_reports_reports_count =
|
|
|
|
|
kRemoteOutboundStatsReportsCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// transport
|
|
|
|
|
graph.transport_id = "RTCTransport_TransportName_1";
|
|
|
|
|
auto* video_media_channel =
|
|
|
|
|
pc_->AddVoiceChannel("VoiceMid", "TransportName");
|
|
|
|
|
video_media_channel->SetStats(media_info);
|
|
|
|
|
// track (sender)
|
|
|
|
|
graph.sender = stats_->SetupLocalTrackAndSender(
|
|
|
|
|
cricket::MEDIA_TYPE_AUDIO, "LocalAudioTrackID", kLocalSsrc, false, 50);
|
|
|
|
|
graph.sender_track_id = "RTCMediaStreamTrack_sender_" +
|
|
|
|
|
rtc::ToString(graph.sender->AttachmentId());
|
|
|
|
|
// track (receiver) and stream (remote stream)
|
|
|
|
|
graph.receiver = stats_->SetupRemoteTrackAndReceiver(
|
|
|
|
|
cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID", "RemoteStreamId",
|
|
|
|
|
kRemoteSsrc);
|
|
|
|
|
graph.receiver_track_id = "RTCMediaStreamTrack_receiver_" +
|
|
|
|
|
rtc::ToString(graph.receiver->AttachmentId());
|
|
|
|
|
graph.remote_stream_id = "RTCMediaStream_RemoteStreamId";
|
|
|
|
|
// peer-connection
|
|
|
|
|
graph.peer_connection_id = "RTCPeerConnection";
|
|
|
|
|
// media-source (kind: video)
|
|
|
|
|
graph.media_source_id =
|
|
|
|
|
"RTCAudioSource_" + rtc::ToString(graph.sender->AttachmentId());
|
|
|
|
|
|
|
|
|
|
// Expected stats graph:
|
|
|
|
|
//
|
|
|
|
|
// +--- track (sender) stream (remote stream) ---> track (receiver)
|
|
|
|
|
// | ^ ^
|
|
|
|
|
// | | |
|
|
|
|
|
// | +--------- outbound-rtp inbound-rtp ---------------+
|
|
|
|
|
// | | | | | |
|
|
|
|
|
// | | v v v v
|
|
|
|
|
// | | codec (send) transport codec (recv) peer-connection
|
|
|
|
|
// v v
|
|
|
|
|
// media-source
|
|
|
|
|
|
|
|
|
|
// Verify the stats graph is set up correctly.
|
|
|
|
|
graph.full_report = stats_->GetStatsReport();
|
|
|
|
|
EXPECT_EQ(graph.full_report->size(), add_remote_outbound_stats ? 11u : 10u);
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.send_codec_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.recv_codec_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.outbound_rtp_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.inbound_rtp_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.transport_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.sender_track_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.receiver_track_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.remote_stream_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.peer_connection_id));
|
|
|
|
|
EXPECT_TRUE(graph.full_report->Get(graph.media_source_id));
|
|
|
|
|
// `graph.remote_outbound_rtp_id` is omitted on purpose so that expectations
|
|
|
|
|
// can be added by the caller depending on what value it sets for the
|
|
|
|
|
// `add_remote_outbound_stats` argument.
|
|
|
|
|
const auto& sender_track = graph.full_report->Get(graph.sender_track_id)
|
|
|
|
|
->cast_to<RTCMediaStreamTrackStats>();
|
|
|
|
|
EXPECT_EQ(*sender_track.media_source_id, graph.media_source_id);
|
|
|
|
|
const auto& outbound_rtp = graph.full_report->Get(graph.outbound_rtp_id)
|
|
|
|
|
->cast_to<RTCOutboundRTPStreamStats>();
|
|
|
|
|
EXPECT_EQ(*outbound_rtp.media_source_id, graph.media_source_id);
|
|
|
|
|
EXPECT_EQ(*outbound_rtp.codec_id, graph.send_codec_id);
|
|
|
|
|
EXPECT_EQ(*outbound_rtp.track_id, graph.sender_track_id);
|
|
|
|
|
EXPECT_EQ(*outbound_rtp.transport_id, graph.transport_id);
|
|
|
|
|
const auto& inbound_rtp = graph.full_report->Get(graph.inbound_rtp_id)
|
|
|
|
|
->cast_to<RTCInboundRTPStreamStats>();
|
|
|
|
|
EXPECT_EQ(*inbound_rtp.codec_id, graph.recv_codec_id);
|
|
|
|
|
EXPECT_EQ(*inbound_rtp.track_id, graph.receiver_track_id);
|
|
|
|
|
EXPECT_EQ(*inbound_rtp.transport_id, graph.transport_id);
|
|
|
|
|
|
|
|
|
|
return graph;
|
|
|
|
|
}
|
|
|
|
|
|
2016-08-30 14:04:35 -07:00
|
|
|
protected:
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::ScopedFakeClock fake_clock_;
|
|
|
|
|
rtc::scoped_refptr<FakePeerConnectionForStats> pc_;
|
|
|
|
|
std::unique_ptr<RTCStatsCollectorWrapper> stats_;
|
2016-08-30 14:04:35 -07:00
|
|
|
};
|
|
|
|
|
|
2016-09-05 01:36:50 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, SingleCallback) {
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> result;
|
2018-02-02 16:00:20 -08:00
|
|
|
stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&result));
|
2016-09-05 01:36:50 -07:00
|
|
|
EXPECT_TRUE_WAIT(result, kGetStatsReportTimeoutMs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, MultipleCallbacks) {
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> a, b, c;
|
|
|
|
|
stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&a));
|
|
|
|
|
stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&b));
|
|
|
|
|
stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&c));
|
2016-09-05 01:36:50 -07:00
|
|
|
EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs);
|
|
|
|
|
EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs);
|
|
|
|
|
EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs);
|
2018-02-02 16:00:20 -08:00
|
|
|
|
2016-09-05 01:36:50 -07:00
|
|
|
EXPECT_EQ(a.get(), b.get());
|
|
|
|
|
EXPECT_EQ(b.get(), c.get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, CachedStatsReports) {
|
2016-08-30 14:04:35 -07:00
|
|
|
// Caching should ensure |a| and |b| are the same report.
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> a = stats_->GetStatsReport();
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> b = stats_->GetStatsReport();
|
2016-08-30 14:04:35 -07:00
|
|
|
EXPECT_EQ(a.get(), b.get());
|
|
|
|
|
// Invalidate cache by clearing it.
|
2018-02-02 16:00:20 -08:00
|
|
|
stats_->stats_collector()->ClearCachedStatsReport();
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> c = stats_->GetStatsReport();
|
2016-08-30 14:04:35 -07:00
|
|
|
EXPECT_NE(b.get(), c.get());
|
|
|
|
|
// Invalidate cache by advancing time.
|
2020-02-10 11:16:00 +01:00
|
|
|
fake_clock_.AdvanceTime(TimeDelta::Millis(51));
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> d = stats_->GetStatsReport();
|
2016-08-30 14:04:35 -07:00
|
|
|
EXPECT_TRUE(d);
|
|
|
|
|
EXPECT_NE(c.get(), d.get());
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-05 01:36:50 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, MultipleCallbacksWithInvalidatedCacheInBetween) {
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> a, b, c;
|
|
|
|
|
stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&a));
|
|
|
|
|
stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&b));
|
2016-09-05 01:36:50 -07:00
|
|
|
// Cache is invalidated after 50 ms.
|
2020-02-10 11:16:00 +01:00
|
|
|
fake_clock_.AdvanceTime(TimeDelta::Millis(51));
|
2018-02-02 16:00:20 -08:00
|
|
|
stats_->stats_collector()->GetStatsReport(RTCStatsObtainer::Create(&c));
|
2016-09-05 01:36:50 -07:00
|
|
|
EXPECT_TRUE_WAIT(a, kGetStatsReportTimeoutMs);
|
|
|
|
|
EXPECT_TRUE_WAIT(b, kGetStatsReportTimeoutMs);
|
|
|
|
|
EXPECT_TRUE_WAIT(c, kGetStatsReportTimeoutMs);
|
|
|
|
|
EXPECT_EQ(a.get(), b.get());
|
|
|
|
|
// The act of doing |AdvanceTime| processes all messages. If this was not the
|
|
|
|
|
// case we might not require |c| to be fresher than |b|.
|
|
|
|
|
EXPECT_NE(c.get(), b.get());
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-09 12:58:23 +01:00
|
|
|
TEST_F(RTCStatsCollectorTest, ToJsonProducesParseableJson) {
|
|
|
|
|
ExampleStatsGraph graph = SetupExampleStatsGraphForSelectorTests();
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
std::string json_format = report->ToJson();
|
|
|
|
|
Json::Reader reader;
|
|
|
|
|
Json::Value json_value;
|
|
|
|
|
ASSERT_TRUE(reader.parse(json_format, json_value));
|
|
|
|
|
// A very brief sanity check on the result.
|
|
|
|
|
EXPECT_EQ(report->size(), json_value.size());
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-03 14:16:56 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsSingle) {
|
2018-02-02 16:00:20 -08:00
|
|
|
const char kTransportName[] = "transport";
|
|
|
|
|
|
|
|
|
|
pc_->AddVoiceChannel("audio", kTransportName);
|
|
|
|
|
|
2016-10-03 14:16:56 -07:00
|
|
|
std::unique_ptr<CertificateInfo> local_certinfo =
|
|
|
|
|
CreateFakeCertificateAndInfoFromDers(
|
|
|
|
|
std::vector<std::string>({"(local) single certificate"}));
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetLocalCertificate(kTransportName, local_certinfo->certificate);
|
|
|
|
|
|
2016-10-03 14:16:56 -07:00
|
|
|
std::unique_ptr<CertificateInfo> remote_certinfo =
|
|
|
|
|
CreateFakeCertificateAndInfoFromDers(
|
|
|
|
|
std::vector<std::string>({"(remote) single certificate"}));
|
2018-02-23 13:04:51 -08:00
|
|
|
pc_->SetRemoteCertChain(
|
2018-10-25 01:16:26 -07:00
|
|
|
kTransportName,
|
|
|
|
|
remote_certinfo->certificate->GetSSLCertificateChain().Clone());
|
2018-02-02 16:00:20 -08:00
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-10-03 14:16:56 -07:00
|
|
|
|
2016-12-21 04:29:17 -08:00
|
|
|
ExpectReportContainsCertificateInfo(report, *local_certinfo);
|
|
|
|
|
ExpectReportContainsCertificateInfo(report, *remote_certinfo);
|
2016-10-03 14:16:56 -07:00
|
|
|
}
|
|
|
|
|
|
2016-11-23 02:32:06 -08:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCCodecStats) {
|
|
|
|
|
// Audio
|
|
|
|
|
cricket::VoiceMediaInfo voice_media_info;
|
|
|
|
|
|
|
|
|
|
RtpCodecParameters inbound_audio_codec;
|
|
|
|
|
inbound_audio_codec.payload_type = 1;
|
2017-02-04 12:09:01 -08:00
|
|
|
inbound_audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
|
|
|
|
|
inbound_audio_codec.name = "opus";
|
2017-11-16 10:56:07 +01:00
|
|
|
inbound_audio_codec.clock_rate = 1337;
|
2020-02-10 14:05:55 +01:00
|
|
|
inbound_audio_codec.num_channels = 1;
|
|
|
|
|
inbound_audio_codec.parameters = {{"minptime", "10"}, {"useinbandfec", "1"}};
|
2016-11-23 02:32:06 -08:00
|
|
|
voice_media_info.receive_codecs.insert(
|
|
|
|
|
std::make_pair(inbound_audio_codec.payload_type, inbound_audio_codec));
|
|
|
|
|
|
|
|
|
|
RtpCodecParameters outbound_audio_codec;
|
|
|
|
|
outbound_audio_codec.payload_type = 2;
|
2017-02-04 12:09:01 -08:00
|
|
|
outbound_audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
|
|
|
|
|
outbound_audio_codec.name = "isac";
|
2017-11-16 10:56:07 +01:00
|
|
|
outbound_audio_codec.clock_rate = 1338;
|
2020-02-10 14:05:55 +01:00
|
|
|
outbound_audio_codec.num_channels = 2;
|
2016-11-23 02:32:06 -08:00
|
|
|
voice_media_info.send_codecs.insert(
|
|
|
|
|
std::make_pair(outbound_audio_codec.payload_type, outbound_audio_codec));
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
|
2018-02-02 16:00:20 -08:00
|
|
|
voice_media_channel->SetStats(voice_media_info);
|
2016-11-23 02:32:06 -08:00
|
|
|
|
|
|
|
|
// Video
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
|
|
|
|
|
|
|
|
|
RtpCodecParameters inbound_video_codec;
|
|
|
|
|
inbound_video_codec.payload_type = 3;
|
2017-02-04 12:09:01 -08:00
|
|
|
inbound_video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
|
|
|
|
|
inbound_video_codec.name = "H264";
|
2017-11-16 10:56:07 +01:00
|
|
|
inbound_video_codec.clock_rate = 1339;
|
2020-02-10 14:05:55 +01:00
|
|
|
inbound_video_codec.parameters = {{"level-asymmetry-allowed", "1"},
|
|
|
|
|
{"packetization-mode", "1"},
|
|
|
|
|
{"profile-level-id", "42001f"}};
|
2016-11-23 02:32:06 -08:00
|
|
|
video_media_info.receive_codecs.insert(
|
|
|
|
|
std::make_pair(inbound_video_codec.payload_type, inbound_video_codec));
|
|
|
|
|
|
|
|
|
|
RtpCodecParameters outbound_video_codec;
|
|
|
|
|
outbound_video_codec.payload_type = 4;
|
2017-02-04 12:09:01 -08:00
|
|
|
outbound_video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
|
|
|
|
|
outbound_video_codec.name = "VP8";
|
2017-11-16 10:56:07 +01:00
|
|
|
outbound_video_codec.clock_rate = 1340;
|
2016-11-23 02:32:06 -08:00
|
|
|
video_media_info.send_codecs.insert(
|
|
|
|
|
std::make_pair(outbound_video_codec.payload_type, outbound_video_codec));
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
|
2018-02-02 16:00:20 -08:00
|
|
|
video_media_channel->SetStats(video_media_info);
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
RTCCodecStats expected_inbound_audio_codec("RTCCodec_AudioMid_Inbound_1",
|
|
|
|
|
report->timestamp_us());
|
2016-11-23 02:32:06 -08:00
|
|
|
expected_inbound_audio_codec.payload_type = 1;
|
2017-02-28 06:56:04 -08:00
|
|
|
expected_inbound_audio_codec.mime_type = "audio/opus";
|
2016-11-23 02:32:06 -08:00
|
|
|
expected_inbound_audio_codec.clock_rate = 1337;
|
2020-02-10 14:05:55 +01:00
|
|
|
expected_inbound_audio_codec.channels = 1;
|
|
|
|
|
expected_inbound_audio_codec.sdp_fmtp_line = "minptime=10;useinbandfec=1";
|
2020-11-16 20:08:27 +01:00
|
|
|
expected_inbound_audio_codec.transport_id = "RTCTransport_TransportName_1";
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
RTCCodecStats expected_outbound_audio_codec("RTCCodec_AudioMid_Outbound_2",
|
|
|
|
|
report->timestamp_us());
|
2016-11-23 02:32:06 -08:00
|
|
|
expected_outbound_audio_codec.payload_type = 2;
|
2017-02-28 06:56:04 -08:00
|
|
|
expected_outbound_audio_codec.mime_type = "audio/isac";
|
2016-11-23 02:32:06 -08:00
|
|
|
expected_outbound_audio_codec.clock_rate = 1338;
|
2020-02-10 14:05:55 +01:00
|
|
|
expected_outbound_audio_codec.channels = 2;
|
2020-11-16 20:08:27 +01:00
|
|
|
expected_outbound_audio_codec.transport_id = "RTCTransport_TransportName_1";
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
RTCCodecStats expected_inbound_video_codec("RTCCodec_VideoMid_Inbound_3",
|
|
|
|
|
report->timestamp_us());
|
2016-11-23 02:32:06 -08:00
|
|
|
expected_inbound_video_codec.payload_type = 3;
|
2017-02-28 06:56:04 -08:00
|
|
|
expected_inbound_video_codec.mime_type = "video/H264";
|
2016-11-23 02:32:06 -08:00
|
|
|
expected_inbound_video_codec.clock_rate = 1339;
|
2020-02-10 14:05:55 +01:00
|
|
|
expected_inbound_video_codec.sdp_fmtp_line =
|
|
|
|
|
"level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f";
|
2020-11-16 20:08:27 +01:00
|
|
|
expected_inbound_video_codec.transport_id = "RTCTransport_TransportName_1";
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
RTCCodecStats expected_outbound_video_codec("RTCCodec_VideoMid_Outbound_4",
|
|
|
|
|
report->timestamp_us());
|
2016-11-23 02:32:06 -08:00
|
|
|
expected_outbound_video_codec.payload_type = 4;
|
2017-02-28 06:56:04 -08:00
|
|
|
expected_outbound_video_codec.mime_type = "video/VP8";
|
2016-11-23 02:32:06 -08:00
|
|
|
expected_outbound_video_codec.clock_rate = 1340;
|
2020-11-16 20:08:27 +01:00
|
|
|
expected_outbound_video_codec.transport_id = "RTCTransport_TransportName_1";
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2017-01-18 07:20:55 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_inbound_audio_codec.id()));
|
2016-11-23 02:32:06 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_inbound_audio_codec,
|
|
|
|
|
report->Get(expected_inbound_audio_codec.id())->cast_to<RTCCodecStats>());
|
|
|
|
|
|
2017-01-18 07:20:55 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_outbound_audio_codec.id()));
|
2016-11-23 02:32:06 -08:00
|
|
|
EXPECT_EQ(expected_outbound_audio_codec,
|
|
|
|
|
report->Get(expected_outbound_audio_codec.id())
|
|
|
|
|
->cast_to<RTCCodecStats>());
|
|
|
|
|
|
2017-01-18 07:20:55 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_inbound_video_codec.id()));
|
2016-11-23 02:32:06 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_inbound_video_codec,
|
|
|
|
|
report->Get(expected_inbound_video_codec.id())->cast_to<RTCCodecStats>());
|
|
|
|
|
|
2017-01-18 07:20:55 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_outbound_video_codec.id()));
|
2016-11-23 02:32:06 -08:00
|
|
|
EXPECT_EQ(expected_outbound_video_codec,
|
|
|
|
|
report->Get(expected_outbound_video_codec.id())
|
|
|
|
|
->cast_to<RTCCodecStats>());
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-03 14:16:56 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsMultiple) {
|
2018-02-02 16:00:20 -08:00
|
|
|
const char kAudioTransport[] = "audio";
|
|
|
|
|
const char kVideoTransport[] = "video";
|
|
|
|
|
|
|
|
|
|
pc_->AddVoiceChannel("audio", kAudioTransport);
|
2016-10-03 14:16:56 -07:00
|
|
|
std::unique_ptr<CertificateInfo> audio_local_certinfo =
|
|
|
|
|
CreateFakeCertificateAndInfoFromDers(
|
|
|
|
|
std::vector<std::string>({"(local) audio"}));
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetLocalCertificate(kAudioTransport, audio_local_certinfo->certificate);
|
2016-10-03 14:16:56 -07:00
|
|
|
std::unique_ptr<CertificateInfo> audio_remote_certinfo =
|
|
|
|
|
CreateFakeCertificateAndInfoFromDers(
|
|
|
|
|
std::vector<std::string>({"(remote) audio"}));
|
2018-02-23 13:04:51 -08:00
|
|
|
pc_->SetRemoteCertChain(
|
|
|
|
|
kAudioTransport,
|
2018-10-25 01:16:26 -07:00
|
|
|
audio_remote_certinfo->certificate->GetSSLCertificateChain().Clone());
|
2016-10-03 14:16:56 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddVideoChannel("video", kVideoTransport);
|
2016-10-03 14:16:56 -07:00
|
|
|
std::unique_ptr<CertificateInfo> video_local_certinfo =
|
|
|
|
|
CreateFakeCertificateAndInfoFromDers(
|
|
|
|
|
std::vector<std::string>({"(local) video"}));
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetLocalCertificate(kVideoTransport, video_local_certinfo->certificate);
|
2016-10-03 14:16:56 -07:00
|
|
|
std::unique_ptr<CertificateInfo> video_remote_certinfo =
|
|
|
|
|
CreateFakeCertificateAndInfoFromDers(
|
|
|
|
|
std::vector<std::string>({"(remote) video"}));
|
2018-02-23 13:04:51 -08:00
|
|
|
pc_->SetRemoteCertChain(
|
|
|
|
|
kVideoTransport,
|
2018-10-25 01:16:26 -07:00
|
|
|
video_remote_certinfo->certificate->GetSSLCertificateChain().Clone());
|
2018-02-02 16:00:20 -08:00
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-12-21 04:29:17 -08:00
|
|
|
ExpectReportContainsCertificateInfo(report, *audio_local_certinfo);
|
|
|
|
|
ExpectReportContainsCertificateInfo(report, *audio_remote_certinfo);
|
|
|
|
|
ExpectReportContainsCertificateInfo(report, *video_local_certinfo);
|
|
|
|
|
ExpectReportContainsCertificateInfo(report, *video_remote_certinfo);
|
2016-10-03 14:16:56 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCCertificateStatsChain) {
|
2018-02-02 16:00:20 -08:00
|
|
|
const char kTransportName[] = "transport";
|
|
|
|
|
|
|
|
|
|
pc_->AddVoiceChannel("audio", kTransportName);
|
|
|
|
|
|
2016-10-03 14:16:56 -07:00
|
|
|
std::unique_ptr<CertificateInfo> local_certinfo =
|
2018-02-02 16:00:20 -08:00
|
|
|
CreateFakeCertificateAndInfoFromDers(
|
|
|
|
|
{"(local) this", "(local) is", "(local) a", "(local) chain"});
|
|
|
|
|
pc_->SetLocalCertificate(kTransportName, local_certinfo->certificate);
|
|
|
|
|
|
2016-10-03 14:16:56 -07:00
|
|
|
std::unique_ptr<CertificateInfo> remote_certinfo =
|
2018-02-02 16:00:20 -08:00
|
|
|
CreateFakeCertificateAndInfoFromDers({"(remote) this", "(remote) is",
|
|
|
|
|
"(remote) another",
|
|
|
|
|
"(remote) chain"});
|
2018-02-23 13:04:51 -08:00
|
|
|
pc_->SetRemoteCertChain(
|
2018-10-25 01:16:26 -07:00
|
|
|
kTransportName,
|
|
|
|
|
remote_certinfo->certificate->GetSSLCertificateChain().Clone());
|
2018-02-02 16:00:20 -08:00
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-12-21 04:29:17 -08:00
|
|
|
ExpectReportContainsCertificateInfo(report, *local_certinfo);
|
|
|
|
|
ExpectReportContainsCertificateInfo(report, *remote_certinfo);
|
2016-10-03 14:16:56 -07:00
|
|
|
}
|
|
|
|
|
|
2019-07-31 07:16:45 -04:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectTwoRTCDataChannelStatsWithPendingId) {
|
|
|
|
|
pc_->AddSctpDataChannel(
|
2020-07-09 15:32:34 -07:00
|
|
|
new MockSctpDataChannel(/*id=*/-1, DataChannelInterface::kConnecting));
|
2019-07-31 07:16:45 -04:00
|
|
|
pc_->AddSctpDataChannel(
|
2020-07-09 15:32:34 -07:00
|
|
|
new MockSctpDataChannel(/*id=*/-1, DataChannelInterface::kConnecting));
|
2019-07-31 07:16:45 -04:00
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-18 12:48:31 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCDataChannelStats) {
|
2019-07-31 07:16:45 -04:00
|
|
|
// Note: The test assumes data channel IDs are predictable.
|
|
|
|
|
// This is not a safe assumption, but in order to make it work for
|
|
|
|
|
// the test, we reset the ID allocator at test start.
|
2020-07-09 15:32:34 -07:00
|
|
|
SctpDataChannel::ResetInternalIdAllocatorForTesting(-1);
|
|
|
|
|
pc_->AddSctpDataChannel(new MockSctpDataChannel(
|
|
|
|
|
0, "MockSctpDataChannel0", DataChannelInterface::kConnecting, "udp", 1, 2,
|
|
|
|
|
3, 4));
|
2016-12-21 01:57:46 -08:00
|
|
|
RTCDataChannelStats expected_data_channel0("RTCDataChannel_0", 0);
|
2020-07-09 15:32:34 -07:00
|
|
|
expected_data_channel0.label = "MockSctpDataChannel0";
|
2016-12-21 01:57:46 -08:00
|
|
|
expected_data_channel0.protocol = "udp";
|
2020-06-05 15:38:51 +02:00
|
|
|
expected_data_channel0.data_channel_identifier = 0;
|
2016-12-21 01:57:46 -08:00
|
|
|
expected_data_channel0.state = "connecting";
|
|
|
|
|
expected_data_channel0.messages_sent = 1;
|
|
|
|
|
expected_data_channel0.bytes_sent = 2;
|
|
|
|
|
expected_data_channel0.messages_received = 3;
|
|
|
|
|
expected_data_channel0.bytes_received = 4;
|
2016-10-18 12:48:31 -07:00
|
|
|
|
2020-07-09 15:32:34 -07:00
|
|
|
pc_->AddSctpDataChannel(new MockSctpDataChannel(1, "MockSctpDataChannel1",
|
|
|
|
|
DataChannelInterface::kOpen,
|
|
|
|
|
"tcp", 5, 6, 7, 8));
|
2016-12-21 01:57:46 -08:00
|
|
|
RTCDataChannelStats expected_data_channel1("RTCDataChannel_1", 0);
|
2020-07-09 15:32:34 -07:00
|
|
|
expected_data_channel1.label = "MockSctpDataChannel1";
|
2016-12-21 01:57:46 -08:00
|
|
|
expected_data_channel1.protocol = "tcp";
|
2020-06-05 15:38:51 +02:00
|
|
|
expected_data_channel1.data_channel_identifier = 1;
|
2016-12-21 01:57:46 -08:00
|
|
|
expected_data_channel1.state = "open";
|
|
|
|
|
expected_data_channel1.messages_sent = 5;
|
|
|
|
|
expected_data_channel1.bytes_sent = 6;
|
|
|
|
|
expected_data_channel1.messages_received = 7;
|
|
|
|
|
expected_data_channel1.bytes_received = 8;
|
|
|
|
|
|
2020-07-09 15:32:34 -07:00
|
|
|
pc_->AddSctpDataChannel(new MockSctpDataChannel(
|
|
|
|
|
2, "MockSctpDataChannel2", DataChannelInterface::kClosing, "udp", 9, 10,
|
|
|
|
|
11, 12));
|
2016-12-21 01:57:46 -08:00
|
|
|
RTCDataChannelStats expected_data_channel2("RTCDataChannel_2", 0);
|
2020-07-09 15:32:34 -07:00
|
|
|
expected_data_channel2.label = "MockSctpDataChannel2";
|
2016-12-21 01:57:46 -08:00
|
|
|
expected_data_channel2.protocol = "udp";
|
2020-06-05 15:38:51 +02:00
|
|
|
expected_data_channel2.data_channel_identifier = 2;
|
2016-12-21 01:57:46 -08:00
|
|
|
expected_data_channel2.state = "closing";
|
|
|
|
|
expected_data_channel2.messages_sent = 9;
|
|
|
|
|
expected_data_channel2.bytes_sent = 10;
|
|
|
|
|
expected_data_channel2.messages_received = 11;
|
|
|
|
|
expected_data_channel2.bytes_received = 12;
|
|
|
|
|
|
2020-07-09 15:32:34 -07:00
|
|
|
pc_->AddSctpDataChannel(new MockSctpDataChannel(3, "MockSctpDataChannel3",
|
|
|
|
|
DataChannelInterface::kClosed,
|
|
|
|
|
"tcp", 13, 14, 15, 16));
|
2016-12-21 01:57:46 -08:00
|
|
|
RTCDataChannelStats expected_data_channel3("RTCDataChannel_3", 0);
|
2020-07-09 15:32:34 -07:00
|
|
|
expected_data_channel3.label = "MockSctpDataChannel3";
|
2016-12-21 01:57:46 -08:00
|
|
|
expected_data_channel3.protocol = "tcp";
|
2020-06-05 15:38:51 +02:00
|
|
|
expected_data_channel3.data_channel_identifier = 3;
|
2016-12-21 01:57:46 -08:00
|
|
|
expected_data_channel3.state = "closed";
|
|
|
|
|
expected_data_channel3.messages_sent = 13;
|
|
|
|
|
expected_data_channel3.bytes_sent = 14;
|
|
|
|
|
expected_data_channel3.messages_received = 15;
|
|
|
|
|
expected_data_channel3.bytes_received = 16;
|
2016-10-18 12:48:31 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_data_channel0.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_data_channel0,
|
|
|
|
|
report->Get(expected_data_channel0.id())->cast_to<RTCDataChannelStats>());
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_data_channel1.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_data_channel1,
|
|
|
|
|
report->Get(expected_data_channel1.id())->cast_to<RTCDataChannelStats>());
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_data_channel2.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_data_channel2,
|
|
|
|
|
report->Get(expected_data_channel2.id())->cast_to<RTCDataChannelStats>());
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_data_channel3.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_data_channel3,
|
|
|
|
|
report->Get(expected_data_channel3.id())->cast_to<RTCDataChannelStats>());
|
2016-10-18 12:48:31 -07:00
|
|
|
}
|
|
|
|
|
|
2016-10-07 02:18:47 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidateStats) {
|
|
|
|
|
// Candidates in the first transport stats.
|
2017-11-21 10:49:36 -08:00
|
|
|
std::unique_ptr<cricket::Candidate> a_local_host =
|
|
|
|
|
CreateFakeCandidate("1.2.3.4", 5, "a_local_host's protocol",
|
|
|
|
|
rtc::ADAPTER_TYPE_VPN, cricket::LOCAL_PORT_TYPE, 0);
|
2016-12-21 03:31:45 -08:00
|
|
|
RTCLocalIceCandidateStats expected_a_local_host(
|
|
|
|
|
"RTCIceCandidate_" + a_local_host->id(), 0);
|
2017-01-02 09:59:31 -08:00
|
|
|
expected_a_local_host.transport_id = "RTCTransport_a_0";
|
2017-11-21 10:49:36 -08:00
|
|
|
expected_a_local_host.network_type = "vpn";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_a_local_host.ip = "1.2.3.4";
|
2021-03-22 13:22:54 +01:00
|
|
|
expected_a_local_host.address = "1.2.3.4";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_a_local_host.port = 5;
|
|
|
|
|
expected_a_local_host.protocol = "a_local_host's protocol";
|
|
|
|
|
expected_a_local_host.candidate_type = "host";
|
|
|
|
|
expected_a_local_host.priority = 0;
|
2017-01-02 04:46:15 -08:00
|
|
|
EXPECT_FALSE(*expected_a_local_host.is_remote);
|
2016-12-21 03:31:45 -08:00
|
|
|
|
2016-10-07 02:18:47 -07:00
|
|
|
std::unique_ptr<cricket::Candidate> a_remote_srflx = CreateFakeCandidate(
|
2017-11-21 10:49:36 -08:00
|
|
|
"6.7.8.9", 10, "remote_srflx's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
|
|
|
|
|
cricket::STUN_PORT_TYPE, 1);
|
2016-12-21 03:31:45 -08:00
|
|
|
RTCRemoteIceCandidateStats expected_a_remote_srflx(
|
|
|
|
|
"RTCIceCandidate_" + a_remote_srflx->id(), 0);
|
2017-01-02 09:59:31 -08:00
|
|
|
expected_a_remote_srflx.transport_id = "RTCTransport_a_0";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_a_remote_srflx.ip = "6.7.8.9";
|
2021-03-22 13:22:54 +01:00
|
|
|
expected_a_remote_srflx.address = "6.7.8.9";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_a_remote_srflx.port = 10;
|
|
|
|
|
expected_a_remote_srflx.protocol = "remote_srflx's protocol";
|
|
|
|
|
expected_a_remote_srflx.candidate_type = "srflx";
|
|
|
|
|
expected_a_remote_srflx.priority = 1;
|
2017-01-02 04:46:15 -08:00
|
|
|
EXPECT_TRUE(*expected_a_remote_srflx.is_remote);
|
2016-12-21 03:31:45 -08:00
|
|
|
|
2016-10-07 02:18:47 -07:00
|
|
|
std::unique_ptr<cricket::Candidate> a_local_prflx = CreateFakeCandidate(
|
2017-11-21 10:49:36 -08:00
|
|
|
"11.12.13.14", 15, "a_local_prflx's protocol", rtc::ADAPTER_TYPE_CELLULAR,
|
|
|
|
|
cricket::PRFLX_PORT_TYPE, 2);
|
2016-12-21 03:31:45 -08:00
|
|
|
RTCLocalIceCandidateStats expected_a_local_prflx(
|
|
|
|
|
"RTCIceCandidate_" + a_local_prflx->id(), 0);
|
2017-01-02 09:59:31 -08:00
|
|
|
expected_a_local_prflx.transport_id = "RTCTransport_a_0";
|
2017-11-21 10:49:36 -08:00
|
|
|
expected_a_local_prflx.network_type = "cellular";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_a_local_prflx.ip = "11.12.13.14";
|
2021-03-22 13:22:54 +01:00
|
|
|
expected_a_local_prflx.address = "11.12.13.14";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_a_local_prflx.port = 15;
|
|
|
|
|
expected_a_local_prflx.protocol = "a_local_prflx's protocol";
|
|
|
|
|
expected_a_local_prflx.candidate_type = "prflx";
|
|
|
|
|
expected_a_local_prflx.priority = 2;
|
2017-01-02 04:46:15 -08:00
|
|
|
EXPECT_FALSE(*expected_a_local_prflx.is_remote);
|
2016-12-21 03:31:45 -08:00
|
|
|
|
2016-10-07 02:18:47 -07:00
|
|
|
std::unique_ptr<cricket::Candidate> a_remote_relay = CreateFakeCandidate(
|
2017-11-21 10:49:36 -08:00
|
|
|
"16.17.18.19", 20, "a_remote_relay's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
|
|
|
|
|
cricket::RELAY_PORT_TYPE, 3);
|
2016-12-21 03:31:45 -08:00
|
|
|
RTCRemoteIceCandidateStats expected_a_remote_relay(
|
|
|
|
|
"RTCIceCandidate_" + a_remote_relay->id(), 0);
|
2017-01-02 09:59:31 -08:00
|
|
|
expected_a_remote_relay.transport_id = "RTCTransport_a_0";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_a_remote_relay.ip = "16.17.18.19";
|
2021-03-22 13:22:54 +01:00
|
|
|
expected_a_remote_relay.address = "16.17.18.19";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_a_remote_relay.port = 20;
|
|
|
|
|
expected_a_remote_relay.protocol = "a_remote_relay's protocol";
|
|
|
|
|
expected_a_remote_relay.candidate_type = "relay";
|
|
|
|
|
expected_a_remote_relay.priority = 3;
|
2017-01-02 04:46:15 -08:00
|
|
|
EXPECT_TRUE(*expected_a_remote_relay.is_remote);
|
2016-12-21 03:31:45 -08:00
|
|
|
|
2018-09-27 14:40:08 +02:00
|
|
|
std::unique_ptr<cricket::Candidate> a_local_relay = CreateFakeCandidate(
|
|
|
|
|
"16.17.18.19", 21, "a_local_relay's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
|
|
|
|
|
cricket::RELAY_PORT_TYPE, 1);
|
|
|
|
|
a_local_relay->set_relay_protocol("tcp");
|
|
|
|
|
|
|
|
|
|
RTCRemoteIceCandidateStats expected_a_local_relay(
|
|
|
|
|
"RTCIceCandidate_" + a_local_relay->id(), 0);
|
|
|
|
|
expected_a_local_relay.transport_id = "RTCTransport_a_0";
|
|
|
|
|
expected_a_local_relay.ip = "16.17.18.19";
|
2021-03-22 13:22:54 +01:00
|
|
|
expected_a_local_relay.address = "16.17.18.19";
|
2018-09-27 14:40:08 +02:00
|
|
|
expected_a_local_relay.port = 21;
|
|
|
|
|
expected_a_local_relay.protocol = "a_local_relay's protocol";
|
|
|
|
|
expected_a_local_relay.relay_protocol = "tcp";
|
|
|
|
|
expected_a_local_relay.candidate_type = "relay";
|
|
|
|
|
expected_a_local_relay.priority = 1;
|
|
|
|
|
EXPECT_TRUE(*expected_a_local_relay.is_remote);
|
|
|
|
|
|
2016-10-07 02:18:47 -07:00
|
|
|
// Candidates in the second transport stats.
|
2017-11-21 10:49:36 -08:00
|
|
|
std::unique_ptr<cricket::Candidate> b_local =
|
|
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "b_local's protocol",
|
|
|
|
|
rtc::ADAPTER_TYPE_WIFI, cricket::LOCAL_PORT_TYPE, 42);
|
2016-12-21 03:31:45 -08:00
|
|
|
RTCLocalIceCandidateStats expected_b_local("RTCIceCandidate_" + b_local->id(),
|
|
|
|
|
0);
|
2017-01-02 09:59:31 -08:00
|
|
|
expected_b_local.transport_id = "RTCTransport_b_0";
|
2017-11-21 10:49:36 -08:00
|
|
|
expected_b_local.network_type = "wifi";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_b_local.ip = "42.42.42.42";
|
2021-03-22 13:22:54 +01:00
|
|
|
expected_b_local.address = "42.42.42.42";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_b_local.port = 42;
|
|
|
|
|
expected_b_local.protocol = "b_local's protocol";
|
|
|
|
|
expected_b_local.candidate_type = "host";
|
|
|
|
|
expected_b_local.priority = 42;
|
2017-01-02 04:46:15 -08:00
|
|
|
EXPECT_FALSE(*expected_b_local.is_remote);
|
2016-12-21 03:31:45 -08:00
|
|
|
|
2016-10-07 02:18:47 -07:00
|
|
|
std::unique_ptr<cricket::Candidate> b_remote = CreateFakeCandidate(
|
2017-11-21 10:49:36 -08:00
|
|
|
"42.42.42.42", 42, "b_remote's protocol", rtc::ADAPTER_TYPE_UNKNOWN,
|
|
|
|
|
cricket::LOCAL_PORT_TYPE, 42);
|
2016-12-21 03:31:45 -08:00
|
|
|
RTCRemoteIceCandidateStats expected_b_remote(
|
|
|
|
|
"RTCIceCandidate_" + b_remote->id(), 0);
|
2017-01-02 09:59:31 -08:00
|
|
|
expected_b_remote.transport_id = "RTCTransport_b_0";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_b_remote.ip = "42.42.42.42";
|
2021-03-22 13:22:54 +01:00
|
|
|
expected_b_remote.address = "42.42.42.42";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_b_remote.port = 42;
|
|
|
|
|
expected_b_remote.protocol = "b_remote's protocol";
|
|
|
|
|
expected_b_remote.candidate_type = "host";
|
|
|
|
|
expected_b_remote.priority = 42;
|
2017-01-02 04:46:15 -08:00
|
|
|
EXPECT_TRUE(*expected_b_remote.is_remote);
|
2016-10-07 02:18:47 -07:00
|
|
|
|
2018-09-27 14:40:08 +02:00
|
|
|
// Add candidate pairs to connection.
|
2016-10-07 02:18:47 -07:00
|
|
|
cricket::TransportChannelStats a_transport_channel_stats;
|
2019-08-28 08:10:27 +02:00
|
|
|
a_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
2016-10-07 02:18:47 -07:00
|
|
|
cricket::ConnectionInfo());
|
2019-08-28 08:10:27 +02:00
|
|
|
a_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
|
|
|
|
.local_candidate = *a_local_host.get();
|
|
|
|
|
a_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
|
|
|
|
.remote_candidate = *a_remote_srflx.get();
|
|
|
|
|
a_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
2016-10-07 02:18:47 -07:00
|
|
|
cricket::ConnectionInfo());
|
2019-08-28 08:10:27 +02:00
|
|
|
a_transport_channel_stats.ice_transport_stats.connection_infos[1]
|
|
|
|
|
.local_candidate = *a_local_prflx.get();
|
|
|
|
|
a_transport_channel_stats.ice_transport_stats.connection_infos[1]
|
|
|
|
|
.remote_candidate = *a_remote_relay.get();
|
|
|
|
|
a_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
2018-09-27 14:40:08 +02:00
|
|
|
cricket::ConnectionInfo());
|
2019-08-28 08:10:27 +02:00
|
|
|
a_transport_channel_stats.ice_transport_stats.connection_infos[2]
|
|
|
|
|
.local_candidate = *a_local_relay.get();
|
|
|
|
|
a_transport_channel_stats.ice_transport_stats.connection_infos[2]
|
|
|
|
|
.remote_candidate = *a_remote_relay.get();
|
2018-02-02 16:00:20 -08:00
|
|
|
|
|
|
|
|
pc_->AddVoiceChannel("audio", "a");
|
|
|
|
|
pc_->SetTransportStats("a", a_transport_channel_stats);
|
2016-10-07 02:18:47 -07:00
|
|
|
|
|
|
|
|
cricket::TransportChannelStats b_transport_channel_stats;
|
2019-08-28 08:10:27 +02:00
|
|
|
b_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
2016-10-07 02:18:47 -07:00
|
|
|
cricket::ConnectionInfo());
|
2019-08-28 08:10:27 +02:00
|
|
|
b_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
|
|
|
|
.local_candidate = *b_local.get();
|
|
|
|
|
b_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
|
|
|
|
.remote_candidate = *b_remote.get();
|
2016-10-07 02:18:47 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddVideoChannel("video", "b");
|
|
|
|
|
pc_->SetTransportStats("b", b_transport_channel_stats);
|
2016-10-07 02:18:47 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-12-21 03:31:45 -08:00
|
|
|
|
2017-01-02 09:59:31 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_a_local_host.id()));
|
2016-12-21 03:31:45 -08:00
|
|
|
EXPECT_EQ(expected_a_local_host, report->Get(expected_a_local_host.id())
|
|
|
|
|
->cast_to<RTCLocalIceCandidateStats>());
|
2017-01-02 09:59:31 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_a_remote_srflx.id()));
|
2016-12-21 03:31:45 -08:00
|
|
|
EXPECT_EQ(expected_a_remote_srflx,
|
|
|
|
|
report->Get(expected_a_remote_srflx.id())
|
|
|
|
|
->cast_to<RTCRemoteIceCandidateStats>());
|
2017-01-02 09:59:31 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_a_local_prflx.id()));
|
2016-12-21 03:31:45 -08:00
|
|
|
EXPECT_EQ(expected_a_local_prflx, report->Get(expected_a_local_prflx.id())
|
|
|
|
|
->cast_to<RTCLocalIceCandidateStats>());
|
2017-01-02 09:59:31 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_a_remote_relay.id()));
|
2016-12-21 03:31:45 -08:00
|
|
|
EXPECT_EQ(expected_a_remote_relay,
|
|
|
|
|
report->Get(expected_a_remote_relay.id())
|
|
|
|
|
->cast_to<RTCRemoteIceCandidateStats>());
|
2017-01-02 09:59:31 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_b_local.id()));
|
2016-12-21 03:31:45 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_b_local,
|
|
|
|
|
report->Get(expected_b_local.id())->cast_to<RTCLocalIceCandidateStats>());
|
2017-01-02 09:59:31 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_b_remote.id()));
|
2016-12-21 03:31:45 -08:00
|
|
|
EXPECT_EQ(expected_b_remote, report->Get(expected_b_remote.id())
|
|
|
|
|
->cast_to<RTCRemoteIceCandidateStats>());
|
2017-01-02 09:59:31 -08:00
|
|
|
EXPECT_TRUE(report->Get("RTCTransport_a_0"));
|
|
|
|
|
EXPECT_TRUE(report->Get("RTCTransport_b_0"));
|
2016-10-07 02:18:47 -07:00
|
|
|
}
|
|
|
|
|
|
2016-10-11 14:54:49 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCIceCandidatePairStats) {
|
2018-02-02 16:00:20 -08:00
|
|
|
const char kTransportName[] = "transport";
|
2017-02-07 06:41:21 -08:00
|
|
|
|
2017-11-21 10:49:36 -08:00
|
|
|
std::unique_ptr<cricket::Candidate> local_candidate =
|
|
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_WIFI,
|
|
|
|
|
cricket::LOCAL_PORT_TYPE, 42);
|
2016-10-11 14:54:49 -07:00
|
|
|
std::unique_ptr<cricket::Candidate> remote_candidate = CreateFakeCandidate(
|
2017-11-21 10:49:36 -08:00
|
|
|
"42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_UNKNOWN,
|
|
|
|
|
cricket::LOCAL_PORT_TYPE, 42);
|
2016-10-11 14:54:49 -07:00
|
|
|
|
|
|
|
|
cricket::ConnectionInfo connection_info;
|
2017-02-07 06:41:21 -08:00
|
|
|
connection_info.best_connection = false;
|
2016-10-11 14:54:49 -07:00
|
|
|
connection_info.local_candidate = *local_candidate.get();
|
|
|
|
|
connection_info.remote_candidate = *remote_candidate.get();
|
|
|
|
|
connection_info.writable = true;
|
|
|
|
|
connection_info.sent_total_bytes = 42;
|
|
|
|
|
connection_info.recv_total_bytes = 1234;
|
2017-02-28 06:34:47 -08:00
|
|
|
connection_info.total_round_trip_time_ms = 0;
|
2018-06-19 16:47:43 +02:00
|
|
|
connection_info.current_round_trip_time_ms = absl::nullopt;
|
2016-12-09 04:12:39 -08:00
|
|
|
connection_info.recv_ping_requests = 2020;
|
2016-12-12 01:22:53 -08:00
|
|
|
connection_info.sent_ping_requests_total = 2020;
|
|
|
|
|
connection_info.sent_ping_requests_before_first_response = 2000;
|
2016-10-11 14:54:49 -07:00
|
|
|
connection_info.recv_ping_responses = 4321;
|
|
|
|
|
connection_info.sent_ping_responses = 1000;
|
2017-01-02 08:08:18 -08:00
|
|
|
connection_info.state = cricket::IceCandidatePairState::IN_PROGRESS;
|
|
|
|
|
connection_info.priority = 5555;
|
2017-02-27 01:38:08 -08:00
|
|
|
connection_info.nominated = false;
|
2016-10-11 14:54:49 -07:00
|
|
|
|
|
|
|
|
cricket::TransportChannelStats transport_channel_stats;
|
2016-11-30 01:50:14 -08:00
|
|
|
transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
2019-08-28 08:10:27 +02:00
|
|
|
transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
|
|
|
|
connection_info);
|
2017-02-07 06:41:21 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddVideoChannel("video", kTransportName);
|
|
|
|
|
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-30 01:50:14 -08:00
|
|
|
|
|
|
|
|
RTCIceCandidatePairStats expected_pair("RTCIceCandidatePair_" +
|
|
|
|
|
local_candidate->id() + "_" +
|
|
|
|
|
remote_candidate->id(),
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected_pair.transport_id =
|
|
|
|
|
"RTCTransport_transport_" +
|
2018-07-05 11:59:48 +02:00
|
|
|
rtc::ToString(cricket::ICE_CANDIDATE_COMPONENT_RTP);
|
2016-11-30 01:50:14 -08:00
|
|
|
expected_pair.local_candidate_id = "RTCIceCandidate_" + local_candidate->id();
|
|
|
|
|
expected_pair.remote_candidate_id =
|
|
|
|
|
"RTCIceCandidate_" + remote_candidate->id();
|
2017-01-02 08:08:18 -08:00
|
|
|
expected_pair.state = RTCStatsIceCandidatePairState::kInProgress;
|
|
|
|
|
expected_pair.priority = 5555;
|
2017-02-27 01:38:08 -08:00
|
|
|
expected_pair.nominated = false;
|
2016-11-30 01:50:14 -08:00
|
|
|
expected_pair.writable = true;
|
|
|
|
|
expected_pair.bytes_sent = 42;
|
|
|
|
|
expected_pair.bytes_received = 1234;
|
2017-02-28 06:34:47 -08:00
|
|
|
expected_pair.total_round_trip_time = 0.0;
|
2016-12-09 04:12:39 -08:00
|
|
|
expected_pair.requests_received = 2020;
|
2016-12-12 01:22:53 -08:00
|
|
|
expected_pair.requests_sent = 2000;
|
2016-11-30 01:50:14 -08:00
|
|
|
expected_pair.responses_received = 4321;
|
|
|
|
|
expected_pair.responses_sent = 1000;
|
2016-12-12 01:22:53 -08:00
|
|
|
expected_pair.consent_requests_sent = (2020 - 2000);
|
2017-02-28 06:34:47 -08:00
|
|
|
// |expected_pair.current_round_trip_time| should be undefined because the
|
|
|
|
|
// current RTT is not set.
|
2017-02-07 06:41:21 -08:00
|
|
|
// |expected_pair.available_[outgoing/incoming]_bitrate| should be undefined
|
|
|
|
|
// because is is not the current pair.
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_pair.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_pair,
|
|
|
|
|
report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
2016-11-30 01:50:14 -08:00
|
|
|
|
2017-02-27 01:38:08 -08:00
|
|
|
// Set nominated and "GetStats" again.
|
2019-08-28 08:10:27 +02:00
|
|
|
transport_channel_stats.ice_transport_stats.connection_infos[0].nominated =
|
|
|
|
|
true;
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
|
|
|
|
report = stats_->GetFreshStatsReport();
|
2017-02-27 01:38:08 -08:00
|
|
|
expected_pair.nominated = true;
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_pair.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_pair,
|
|
|
|
|
report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
|
|
|
|
|
2017-02-28 06:34:47 -08:00
|
|
|
// Set round trip times and "GetStats" again.
|
2019-08-28 08:10:27 +02:00
|
|
|
transport_channel_stats.ice_transport_stats.connection_infos[0]
|
|
|
|
|
.total_round_trip_time_ms = 7331;
|
|
|
|
|
transport_channel_stats.ice_transport_stats.connection_infos[0]
|
|
|
|
|
.current_round_trip_time_ms = 1337;
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
|
|
|
|
report = stats_->GetFreshStatsReport();
|
2017-02-28 06:34:47 -08:00
|
|
|
expected_pair.total_round_trip_time = 7.331;
|
|
|
|
|
expected_pair.current_round_trip_time = 1.337;
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_pair.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_pair,
|
|
|
|
|
report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
|
|
|
|
|
2017-02-07 06:41:21 -08:00
|
|
|
// Make pair the current pair, clear bandwidth and "GetStats" again.
|
2019-08-28 08:10:27 +02:00
|
|
|
transport_channel_stats.ice_transport_stats.connection_infos[0]
|
|
|
|
|
.best_connection = true;
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetTransportStats(kTransportName, transport_channel_stats);
|
|
|
|
|
report = stats_->GetFreshStatsReport();
|
2017-02-07 06:41:21 -08:00
|
|
|
// |expected_pair.available_[outgoing/incoming]_bitrate| should still be
|
|
|
|
|
// undefined because bandwidth is not set.
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_pair.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_pair,
|
|
|
|
|
report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
|
|
|
|
|
|
|
|
|
// Set bandwidth and "GetStats" again.
|
2017-06-02 06:44:03 -07:00
|
|
|
webrtc::Call::Stats call_stats;
|
|
|
|
|
const int kSendBandwidth = 888;
|
|
|
|
|
call_stats.send_bandwidth_bps = kSendBandwidth;
|
|
|
|
|
const int kRecvBandwidth = 999;
|
|
|
|
|
call_stats.recv_bandwidth_bps = kRecvBandwidth;
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetCallStats(call_stats);
|
|
|
|
|
report = stats_->GetFreshStatsReport();
|
2017-06-02 06:44:03 -07:00
|
|
|
expected_pair.available_outgoing_bitrate = kSendBandwidth;
|
|
|
|
|
expected_pair.available_incoming_bitrate = kRecvBandwidth;
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_pair.id()));
|
2016-11-30 01:50:14 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_pair,
|
|
|
|
|
report->Get(expected_pair.id())->cast_to<RTCIceCandidatePairStats>());
|
2017-01-02 09:59:31 -08:00
|
|
|
EXPECT_TRUE(report->Get(*expected_pair.transport_id));
|
2016-11-30 01:50:14 -08:00
|
|
|
|
2016-12-21 03:31:45 -08:00
|
|
|
RTCLocalIceCandidateStats expected_local_candidate(
|
|
|
|
|
*expected_pair.local_candidate_id, report->timestamp_us());
|
2017-01-02 09:59:31 -08:00
|
|
|
expected_local_candidate.transport_id = *expected_pair.transport_id;
|
2017-11-21 10:49:36 -08:00
|
|
|
expected_local_candidate.network_type = "wifi";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_local_candidate.ip = "42.42.42.42";
|
2021-03-22 13:22:54 +01:00
|
|
|
expected_local_candidate.address = "42.42.42.42";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_local_candidate.port = 42;
|
|
|
|
|
expected_local_candidate.protocol = "protocol";
|
|
|
|
|
expected_local_candidate.candidate_type = "host";
|
|
|
|
|
expected_local_candidate.priority = 42;
|
2017-01-02 04:46:15 -08:00
|
|
|
EXPECT_FALSE(*expected_local_candidate.is_remote);
|
2016-12-21 03:31:45 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_local_candidate.id()));
|
|
|
|
|
EXPECT_EQ(expected_local_candidate,
|
|
|
|
|
report->Get(expected_local_candidate.id())
|
|
|
|
|
->cast_to<RTCLocalIceCandidateStats>());
|
|
|
|
|
|
|
|
|
|
RTCRemoteIceCandidateStats expected_remote_candidate(
|
|
|
|
|
*expected_pair.remote_candidate_id, report->timestamp_us());
|
2017-01-02 09:59:31 -08:00
|
|
|
expected_remote_candidate.transport_id = *expected_pair.transport_id;
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_remote_candidate.ip = "42.42.42.42";
|
2021-03-22 13:22:54 +01:00
|
|
|
expected_remote_candidate.address = "42.42.42.42";
|
2016-12-21 03:31:45 -08:00
|
|
|
expected_remote_candidate.port = 42;
|
|
|
|
|
expected_remote_candidate.protocol = "protocol";
|
|
|
|
|
expected_remote_candidate.candidate_type = "host";
|
|
|
|
|
expected_remote_candidate.priority = 42;
|
2017-01-02 04:46:15 -08:00
|
|
|
EXPECT_TRUE(*expected_remote_candidate.is_remote);
|
2016-12-21 03:31:45 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_remote_candidate.id()));
|
|
|
|
|
EXPECT_EQ(expected_remote_candidate,
|
|
|
|
|
report->Get(expected_remote_candidate.id())
|
|
|
|
|
->cast_to<RTCRemoteIceCandidateStats>());
|
2016-10-11 14:54:49 -07:00
|
|
|
}
|
|
|
|
|
|
2016-08-30 14:04:35 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCPeerConnectionStats) {
|
|
|
|
|
{
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-14 01:41:09 -08:00
|
|
|
RTCPeerConnectionStats expected("RTCPeerConnection",
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected.data_channels_opened = 0;
|
|
|
|
|
expected.data_channels_closed = 0;
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get("RTCPeerConnection"));
|
2016-11-14 01:41:09 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected,
|
|
|
|
|
report->Get("RTCPeerConnection")->cast_to<RTCPeerConnectionStats>());
|
2016-08-30 14:04:35 -07:00
|
|
|
}
|
|
|
|
|
|
2020-06-15 13:47:42 +02:00
|
|
|
// TODO(bugs.webrtc.org/11547): Supply a separate network thread.
|
2020-07-09 15:32:34 -07:00
|
|
|
FakeDataChannelProvider provider;
|
|
|
|
|
rtc::scoped_refptr<SctpDataChannel> dummy_channel_a = SctpDataChannel::Create(
|
|
|
|
|
&provider, "DummyChannelA", InternalDataChannelInit(),
|
2020-06-15 13:47:42 +02:00
|
|
|
rtc::Thread::Current(), rtc::Thread::Current());
|
2020-07-09 15:32:34 -07:00
|
|
|
pc_->SignalSctpDataChannelCreated()(dummy_channel_a.get());
|
|
|
|
|
rtc::scoped_refptr<SctpDataChannel> dummy_channel_b = SctpDataChannel::Create(
|
|
|
|
|
&provider, "DummyChannelB", InternalDataChannelInit(),
|
2020-06-15 13:47:42 +02:00
|
|
|
rtc::Thread::Current(), rtc::Thread::Current());
|
2020-07-09 15:32:34 -07:00
|
|
|
pc_->SignalSctpDataChannelCreated()(dummy_channel_b.get());
|
2016-11-14 01:41:09 -08:00
|
|
|
|
|
|
|
|
dummy_channel_a->SignalOpened(dummy_channel_a.get());
|
|
|
|
|
// Closing a channel that is not opened should not affect the counts.
|
|
|
|
|
dummy_channel_b->SignalClosed(dummy_channel_b.get());
|
|
|
|
|
|
|
|
|
|
{
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report =
|
|
|
|
|
stats_->GetFreshStatsReport();
|
2016-11-14 01:41:09 -08:00
|
|
|
RTCPeerConnectionStats expected("RTCPeerConnection",
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected.data_channels_opened = 1;
|
|
|
|
|
expected.data_channels_closed = 0;
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get("RTCPeerConnection"));
|
2016-11-14 01:41:09 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected,
|
|
|
|
|
report->Get("RTCPeerConnection")->cast_to<RTCPeerConnectionStats>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dummy_channel_b->SignalOpened(dummy_channel_b.get());
|
|
|
|
|
dummy_channel_b->SignalClosed(dummy_channel_b.get());
|
2016-08-30 14:04:35 -07:00
|
|
|
|
|
|
|
|
{
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report =
|
|
|
|
|
stats_->GetFreshStatsReport();
|
2016-11-14 01:41:09 -08:00
|
|
|
RTCPeerConnectionStats expected("RTCPeerConnection",
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected.data_channels_opened = 2;
|
|
|
|
|
expected.data_channels_closed = 1;
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get("RTCPeerConnection"));
|
2016-11-14 01:41:09 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected,
|
|
|
|
|
report->Get("RTCPeerConnection")->cast_to<RTCPeerConnectionStats>());
|
2016-08-30 14:04:35 -07:00
|
|
|
}
|
2017-03-20 03:14:14 -07:00
|
|
|
|
|
|
|
|
// Re-opening a data channel (or opening a new data channel that is re-using
|
|
|
|
|
// the same address in memory) should increase the opened count.
|
|
|
|
|
dummy_channel_b->SignalOpened(dummy_channel_b.get());
|
|
|
|
|
|
|
|
|
|
{
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report =
|
|
|
|
|
stats_->GetFreshStatsReport();
|
2017-03-20 03:14:14 -07:00
|
|
|
RTCPeerConnectionStats expected("RTCPeerConnection",
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected.data_channels_opened = 3;
|
|
|
|
|
expected.data_channels_closed = 1;
|
|
|
|
|
ASSERT_TRUE(report->Get("RTCPeerConnection"));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected,
|
|
|
|
|
report->Get("RTCPeerConnection")->cast_to<RTCPeerConnectionStats>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dummy_channel_a->SignalClosed(dummy_channel_a.get());
|
|
|
|
|
dummy_channel_b->SignalClosed(dummy_channel_b.get());
|
|
|
|
|
|
|
|
|
|
{
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report =
|
|
|
|
|
stats_->GetFreshStatsReport();
|
2017-03-20 03:14:14 -07:00
|
|
|
RTCPeerConnectionStats expected("RTCPeerConnection",
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected.data_channels_opened = 3;
|
|
|
|
|
expected.data_channels_closed = 3;
|
|
|
|
|
ASSERT_TRUE(report->Get("RTCPeerConnection"));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected,
|
|
|
|
|
report->Get("RTCPeerConnection")->cast_to<RTCPeerConnectionStats>());
|
|
|
|
|
}
|
2016-08-30 14:04:35 -07:00
|
|
|
}
|
|
|
|
|
|
2016-11-08 06:29:22 -08:00
|
|
|
TEST_F(RTCStatsCollectorTest,
|
2018-01-14 09:18:58 +01:00
|
|
|
CollectLocalRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Audio) {
|
2016-11-08 06:29:22 -08:00
|
|
|
rtc::scoped_refptr<MediaStream> local_stream =
|
2018-03-02 11:34:10 -08:00
|
|
|
MediaStream::Create("LocalStreamId");
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->mutable_local_streams()->AddStream(local_stream);
|
2016-11-08 06:29:22 -08:00
|
|
|
|
|
|
|
|
// Local audio track
|
2017-01-20 02:47:10 -08:00
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> local_audio_track =
|
|
|
|
|
CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "LocalAudioTrackID",
|
|
|
|
|
MediaStreamTrackInterface::kEnded);
|
|
|
|
|
local_stream->AddTrack(
|
|
|
|
|
static_cast<AudioTrackInterface*>(local_audio_track.get()));
|
|
|
|
|
|
|
|
|
|
cricket::VoiceSenderInfo voice_sender_info_ssrc1;
|
|
|
|
|
voice_sender_info_ssrc1.local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
voice_sender_info_ssrc1.local_stats[0].ssrc = 1;
|
2017-11-24 17:29:59 +01:00
|
|
|
voice_sender_info_ssrc1.apm_statistics.echo_return_loss = 42.0;
|
|
|
|
|
voice_sender_info_ssrc1.apm_statistics.echo_return_loss_enhancement = 52.0;
|
2017-01-20 02:47:10 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
stats_->CreateMockRtpSendersReceiversAndChannels(
|
2018-01-14 09:18:58 +01:00
|
|
|
{std::make_pair(local_audio_track.get(), voice_sender_info_ssrc1)}, {},
|
2018-03-13 16:05:28 -07:00
|
|
|
{}, {}, {local_stream->id()}, {});
|
2018-01-14 09:18:58 +01:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2018-01-14 09:18:58 +01:00
|
|
|
|
|
|
|
|
RTCMediaStreamStats expected_local_stream(
|
|
|
|
|
IdForType<RTCMediaStreamStats>(report), report->timestamp_us());
|
2018-03-13 16:05:28 -07:00
|
|
|
expected_local_stream.stream_identifier = local_stream->id();
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_local_stream.track_ids = {
|
|
|
|
|
IdForType<RTCMediaStreamTrackStats>(report)};
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_local_stream.id()))
|
|
|
|
|
<< "Did not find " << expected_local_stream.id() << " in "
|
|
|
|
|
<< report->ToJson();
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_local_stream,
|
|
|
|
|
report->Get(expected_local_stream.id())->cast_to<RTCMediaStreamStats>());
|
|
|
|
|
|
|
|
|
|
RTCMediaStreamTrackStats expected_local_audio_track_ssrc1(
|
|
|
|
|
IdForType<RTCMediaStreamTrackStats>(report), report->timestamp_us(),
|
|
|
|
|
RTCMediaStreamTrackKind::kAudio);
|
|
|
|
|
expected_local_audio_track_ssrc1.track_identifier = local_audio_track->id();
|
2019-05-22 15:49:42 +02:00
|
|
|
expected_local_audio_track_ssrc1.media_source_id =
|
|
|
|
|
"RTCAudioSource_11"; // Attachment ID = SSRC + 10
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_local_audio_track_ssrc1.remote_source = false;
|
|
|
|
|
expected_local_audio_track_ssrc1.ended = true;
|
|
|
|
|
expected_local_audio_track_ssrc1.detached = false;
|
|
|
|
|
expected_local_audio_track_ssrc1.echo_return_loss = 42.0;
|
|
|
|
|
expected_local_audio_track_ssrc1.echo_return_loss_enhancement = 52.0;
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_local_audio_track_ssrc1.id()))
|
|
|
|
|
<< "Did not find " << expected_local_audio_track_ssrc1.id() << " in "
|
|
|
|
|
<< report->ToJson();
|
|
|
|
|
EXPECT_EQ(expected_local_audio_track_ssrc1,
|
|
|
|
|
report->Get(expected_local_audio_track_ssrc1.id())
|
|
|
|
|
->cast_to<RTCMediaStreamTrackStats>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest,
|
|
|
|
|
CollectRemoteRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Audio) {
|
|
|
|
|
rtc::scoped_refptr<MediaStream> remote_stream =
|
2018-03-02 11:34:10 -08:00
|
|
|
MediaStream::Create("RemoteStreamId");
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->mutable_remote_streams()->AddStream(remote_stream);
|
2018-01-14 09:18:58 +01:00
|
|
|
|
2016-11-08 06:29:22 -08:00
|
|
|
// Remote audio track
|
2017-01-20 02:47:10 -08:00
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio_track =
|
|
|
|
|
CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID",
|
|
|
|
|
MediaStreamTrackInterface::kLive);
|
|
|
|
|
remote_stream->AddTrack(
|
|
|
|
|
static_cast<AudioTrackInterface*>(remote_audio_track.get()));
|
|
|
|
|
|
|
|
|
|
cricket::VoiceReceiverInfo voice_receiver_info;
|
|
|
|
|
voice_receiver_info.local_stats.push_back(cricket::SsrcReceiverInfo());
|
|
|
|
|
voice_receiver_info.local_stats[0].ssrc = 3;
|
2020-10-27 09:50:36 +01:00
|
|
|
voice_receiver_info.audio_level = 16383; // [0,32767]
|
2017-07-14 12:17:49 -07:00
|
|
|
voice_receiver_info.total_output_energy = 0.125;
|
2017-08-24 17:15:13 -07:00
|
|
|
voice_receiver_info.total_samples_received = 4567;
|
2017-07-14 12:17:49 -07:00
|
|
|
voice_receiver_info.total_output_duration = 0.25;
|
2017-08-24 17:15:13 -07:00
|
|
|
voice_receiver_info.concealed_samples = 123;
|
2017-09-18 09:28:20 +02:00
|
|
|
voice_receiver_info.concealment_events = 12;
|
2019-04-30 09:45:21 +02:00
|
|
|
voice_receiver_info.inserted_samples_for_deceleration = 987;
|
|
|
|
|
voice_receiver_info.removed_samples_for_acceleration = 876;
|
|
|
|
|
voice_receiver_info.silent_concealed_samples = 765;
|
2017-10-02 12:00:34 +02:00
|
|
|
voice_receiver_info.jitter_buffer_delay_seconds = 3456;
|
2019-01-15 15:46:29 +01:00
|
|
|
voice_receiver_info.jitter_buffer_emitted_count = 13;
|
2020-03-11 11:18:54 +01:00
|
|
|
voice_receiver_info.jitter_buffer_target_delay_seconds = 7.894;
|
2018-11-22 17:21:10 +01:00
|
|
|
voice_receiver_info.jitter_buffer_flushes = 7;
|
2018-11-27 12:52:16 +01:00
|
|
|
voice_receiver_info.delayed_packet_outage_samples = 15;
|
2019-03-06 09:18:40 +01:00
|
|
|
voice_receiver_info.relative_packet_arrival_delay_seconds = 16;
|
2019-04-29 17:00:46 +02:00
|
|
|
voice_receiver_info.interruption_count = 7788;
|
|
|
|
|
voice_receiver_info.total_interruption_duration_ms = 778899;
|
2017-01-20 02:47:10 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
stats_->CreateMockRtpSendersReceiversAndChannels(
|
2018-01-14 09:18:58 +01:00
|
|
|
{}, {std::make_pair(remote_audio_track.get(), voice_receiver_info)}, {},
|
|
|
|
|
{}, {}, {remote_stream});
|
2016-11-08 06:29:22 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-08 06:29:22 -08:00
|
|
|
|
|
|
|
|
RTCMediaStreamStats expected_remote_stream(
|
2018-01-14 09:18:58 +01:00
|
|
|
IdForType<RTCMediaStreamStats>(report), report->timestamp_us());
|
2018-03-13 16:05:28 -07:00
|
|
|
expected_remote_stream.stream_identifier = remote_stream->id();
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_remote_stream.track_ids =
|
|
|
|
|
std::vector<std::string>({IdForType<RTCMediaStreamTrackStats>(report)});
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_remote_stream.id()))
|
|
|
|
|
<< "Did not find " << expected_remote_stream.id() << " in "
|
|
|
|
|
<< report->ToJson();
|
2016-11-08 06:29:22 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_remote_stream,
|
|
|
|
|
report->Get(expected_remote_stream.id())->cast_to<RTCMediaStreamStats>());
|
|
|
|
|
|
|
|
|
|
RTCMediaStreamTrackStats expected_remote_audio_track(
|
2018-01-14 09:18:58 +01:00
|
|
|
IdForType<RTCMediaStreamTrackStats>(report), report->timestamp_us(),
|
|
|
|
|
RTCMediaStreamTrackKind::kAudio);
|
2016-11-08 06:29:22 -08:00
|
|
|
expected_remote_audio_track.track_identifier = remote_audio_track->id();
|
2019-05-22 15:49:42 +02:00
|
|
|
// |expected_remote_audio_track.media_source_id| should be undefined
|
|
|
|
|
// because the track is remote.
|
2016-11-08 06:29:22 -08:00
|
|
|
expected_remote_audio_track.remote_source = true;
|
|
|
|
|
expected_remote_audio_track.ended = false;
|
|
|
|
|
expected_remote_audio_track.detached = false;
|
2020-10-27 09:50:36 +01:00
|
|
|
expected_remote_audio_track.audio_level = 16383.0 / 32767.0; // [0,1]
|
2017-07-14 12:17:49 -07:00
|
|
|
expected_remote_audio_track.total_audio_energy = 0.125;
|
2017-08-24 17:15:13 -07:00
|
|
|
expected_remote_audio_track.total_samples_received = 4567;
|
2017-07-14 12:17:49 -07:00
|
|
|
expected_remote_audio_track.total_samples_duration = 0.25;
|
2017-08-24 17:15:13 -07:00
|
|
|
expected_remote_audio_track.concealed_samples = 123;
|
2017-09-18 09:28:20 +02:00
|
|
|
expected_remote_audio_track.concealment_events = 12;
|
2019-04-30 09:45:21 +02:00
|
|
|
expected_remote_audio_track.inserted_samples_for_deceleration = 987;
|
|
|
|
|
expected_remote_audio_track.removed_samples_for_acceleration = 876;
|
|
|
|
|
expected_remote_audio_track.silent_concealed_samples = 765;
|
2017-10-02 12:00:34 +02:00
|
|
|
expected_remote_audio_track.jitter_buffer_delay = 3456;
|
2019-01-15 15:46:29 +01:00
|
|
|
expected_remote_audio_track.jitter_buffer_emitted_count = 13;
|
2020-03-11 11:18:54 +01:00
|
|
|
expected_remote_audio_track.jitter_buffer_target_delay = 7.894;
|
2018-11-22 17:21:10 +01:00
|
|
|
expected_remote_audio_track.jitter_buffer_flushes = 7;
|
2018-11-27 12:52:16 +01:00
|
|
|
expected_remote_audio_track.delayed_packet_outage_samples = 15;
|
2019-03-06 09:18:40 +01:00
|
|
|
expected_remote_audio_track.relative_packet_arrival_delay = 16;
|
2019-04-29 17:00:46 +02:00
|
|
|
expected_remote_audio_track.interruption_count = 7788;
|
|
|
|
|
expected_remote_audio_track.total_interruption_duration = 778.899;
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_remote_audio_track.id()));
|
2016-11-08 06:29:22 -08:00
|
|
|
EXPECT_EQ(expected_remote_audio_track,
|
|
|
|
|
report->Get(expected_remote_audio_track.id())
|
|
|
|
|
->cast_to<RTCMediaStreamTrackStats>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest,
|
2018-01-14 09:18:58 +01:00
|
|
|
CollectLocalRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Video) {
|
2016-11-08 06:29:22 -08:00
|
|
|
rtc::scoped_refptr<MediaStream> local_stream =
|
2018-03-02 11:34:10 -08:00
|
|
|
MediaStream::Create("LocalStreamId");
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->mutable_local_streams()->AddStream(local_stream);
|
2016-11-08 06:29:22 -08:00
|
|
|
|
|
|
|
|
// Local video track
|
2017-01-20 02:47:10 -08:00
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> local_video_track =
|
|
|
|
|
CreateFakeTrack(cricket::MEDIA_TYPE_VIDEO, "LocalVideoTrackID",
|
|
|
|
|
MediaStreamTrackInterface::kLive);
|
|
|
|
|
local_stream->AddTrack(
|
|
|
|
|
static_cast<VideoTrackInterface*>(local_video_track.get()));
|
|
|
|
|
|
|
|
|
|
cricket::VideoSenderInfo video_sender_info_ssrc1;
|
|
|
|
|
video_sender_info_ssrc1.local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
video_sender_info_ssrc1.local_stats[0].ssrc = 1;
|
|
|
|
|
video_sender_info_ssrc1.send_frame_width = 1234;
|
|
|
|
|
video_sender_info_ssrc1.send_frame_height = 4321;
|
2017-01-20 06:14:25 -08:00
|
|
|
video_sender_info_ssrc1.frames_encoded = 11;
|
2018-02-28 16:35:03 +01:00
|
|
|
video_sender_info_ssrc1.huge_frames_sent = 1;
|
2017-01-20 02:47:10 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
stats_->CreateMockRtpSendersReceiversAndChannels(
|
2018-01-14 09:18:58 +01:00
|
|
|
{}, {},
|
|
|
|
|
{std::make_pair(local_video_track.get(), video_sender_info_ssrc1)}, {},
|
2018-03-13 16:05:28 -07:00
|
|
|
{local_stream->id()}, {});
|
2018-01-14 09:18:58 +01:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2018-01-14 09:18:58 +01:00
|
|
|
|
|
|
|
|
auto stats_of_my_type = report->GetStatsOfType<RTCMediaStreamStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
ASSERT_EQ(1U, stats_of_my_type.size()) << "No stream in " << report->ToJson();
|
2018-01-14 09:18:58 +01:00
|
|
|
auto stats_of_track_type = report->GetStatsOfType<RTCMediaStreamTrackStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
ASSERT_EQ(1U, stats_of_track_type.size())
|
2018-01-14 09:18:58 +01:00
|
|
|
<< "Wrong number of tracks in " << report->ToJson();
|
|
|
|
|
|
|
|
|
|
RTCMediaStreamStats expected_local_stream(stats_of_my_type[0]->id(),
|
|
|
|
|
report->timestamp_us());
|
2018-03-13 16:05:28 -07:00
|
|
|
expected_local_stream.stream_identifier = local_stream->id();
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_local_stream.track_ids =
|
|
|
|
|
std::vector<std::string>({stats_of_track_type[0]->id()});
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_local_stream.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_local_stream,
|
|
|
|
|
report->Get(expected_local_stream.id())->cast_to<RTCMediaStreamStats>());
|
|
|
|
|
|
|
|
|
|
RTCMediaStreamTrackStats expected_local_video_track_ssrc1(
|
|
|
|
|
stats_of_track_type[0]->id(), report->timestamp_us(),
|
|
|
|
|
RTCMediaStreamTrackKind::kVideo);
|
|
|
|
|
expected_local_video_track_ssrc1.track_identifier = local_video_track->id();
|
2019-05-22 15:49:42 +02:00
|
|
|
expected_local_video_track_ssrc1.media_source_id =
|
|
|
|
|
"RTCVideoSource_11"; // Attachment ID = SSRC + 10
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_local_video_track_ssrc1.remote_source = false;
|
|
|
|
|
expected_local_video_track_ssrc1.ended = false;
|
|
|
|
|
expected_local_video_track_ssrc1.detached = false;
|
|
|
|
|
expected_local_video_track_ssrc1.frame_width = 1234;
|
|
|
|
|
expected_local_video_track_ssrc1.frame_height = 4321;
|
|
|
|
|
expected_local_video_track_ssrc1.frames_sent = 11;
|
2018-02-28 16:35:03 +01:00
|
|
|
expected_local_video_track_ssrc1.huge_frames_sent = 1;
|
2018-01-14 09:18:58 +01:00
|
|
|
ASSERT_TRUE(report->Get(expected_local_video_track_ssrc1.id()));
|
|
|
|
|
EXPECT_EQ(expected_local_video_track_ssrc1,
|
|
|
|
|
report->Get(expected_local_video_track_ssrc1.id())
|
|
|
|
|
->cast_to<RTCMediaStreamTrackStats>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest,
|
|
|
|
|
CollectRemoteRTCMediaStreamStatsAndRTCMediaStreamTrackStats_Video) {
|
|
|
|
|
rtc::scoped_refptr<MediaStream> remote_stream =
|
2018-03-02 11:34:10 -08:00
|
|
|
MediaStream::Create("RemoteStreamId");
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->mutable_remote_streams()->AddStream(remote_stream);
|
2018-01-14 09:18:58 +01:00
|
|
|
|
2017-01-20 02:47:10 -08:00
|
|
|
// Remote video track with values
|
|
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> remote_video_track_ssrc3 =
|
|
|
|
|
CreateFakeTrack(cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID3",
|
|
|
|
|
MediaStreamTrackInterface::kEnded);
|
|
|
|
|
remote_stream->AddTrack(
|
|
|
|
|
static_cast<VideoTrackInterface*>(remote_video_track_ssrc3.get()));
|
|
|
|
|
|
|
|
|
|
cricket::VideoReceiverInfo video_receiver_info_ssrc3;
|
|
|
|
|
video_receiver_info_ssrc3.local_stats.push_back(cricket::SsrcReceiverInfo());
|
|
|
|
|
video_receiver_info_ssrc3.local_stats[0].ssrc = 3;
|
|
|
|
|
video_receiver_info_ssrc3.frame_width = 6789;
|
|
|
|
|
video_receiver_info_ssrc3.frame_height = 9876;
|
2019-05-28 17:38:08 +02:00
|
|
|
video_receiver_info_ssrc3.jitter_buffer_delay_seconds = 2.5;
|
|
|
|
|
video_receiver_info_ssrc3.jitter_buffer_emitted_count = 25;
|
2017-01-23 07:21:55 -08:00
|
|
|
video_receiver_info_ssrc3.frames_received = 1000;
|
|
|
|
|
video_receiver_info_ssrc3.frames_decoded = 995;
|
2019-08-26 15:04:43 +02:00
|
|
|
video_receiver_info_ssrc3.frames_dropped = 10;
|
2017-01-23 07:21:55 -08:00
|
|
|
video_receiver_info_ssrc3.frames_rendered = 990;
|
2019-01-31 16:45:42 +01:00
|
|
|
video_receiver_info_ssrc3.freeze_count = 3;
|
|
|
|
|
video_receiver_info_ssrc3.pause_count = 2;
|
|
|
|
|
video_receiver_info_ssrc3.total_freezes_duration_ms = 1000;
|
|
|
|
|
video_receiver_info_ssrc3.total_pauses_duration_ms = 10000;
|
|
|
|
|
video_receiver_info_ssrc3.total_frames_duration_ms = 15000;
|
|
|
|
|
video_receiver_info_ssrc3.sum_squared_frame_durations = 1.5;
|
2017-01-20 02:47:10 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
stats_->CreateMockRtpSendersReceiversAndChannels(
|
2018-01-14 09:18:58 +01:00
|
|
|
{}, {}, {},
|
2018-01-11 17:18:19 +01:00
|
|
|
{std::make_pair(remote_video_track_ssrc3.get(),
|
2018-01-14 09:18:58 +01:00
|
|
|
video_receiver_info_ssrc3)},
|
|
|
|
|
{}, {remote_stream});
|
2016-11-08 06:29:22 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-08 06:29:22 -08:00
|
|
|
|
2018-01-14 09:18:58 +01:00
|
|
|
auto stats_of_my_type = report->GetStatsOfType<RTCMediaStreamStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
ASSERT_EQ(1U, stats_of_my_type.size()) << "No stream in " << report->ToJson();
|
2018-01-14 09:18:58 +01:00
|
|
|
auto stats_of_track_type = report->GetStatsOfType<RTCMediaStreamTrackStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
ASSERT_EQ(1U, stats_of_track_type.size())
|
2018-01-14 09:18:58 +01:00
|
|
|
<< "Wrong number of tracks in " << report->ToJson();
|
|
|
|
|
ASSERT_TRUE(*(stats_of_track_type[0]->remote_source));
|
2016-11-08 06:29:22 -08:00
|
|
|
|
2018-01-14 09:18:58 +01:00
|
|
|
RTCMediaStreamStats expected_remote_stream(stats_of_my_type[0]->id(),
|
|
|
|
|
report->timestamp_us());
|
2018-03-13 16:05:28 -07:00
|
|
|
expected_remote_stream.stream_identifier = remote_stream->id();
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_remote_stream.track_ids =
|
|
|
|
|
std::vector<std::string>({stats_of_track_type[0]->id()});
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_remote_stream.id()));
|
2016-11-08 06:29:22 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_remote_stream,
|
|
|
|
|
report->Get(expected_remote_stream.id())->cast_to<RTCMediaStreamStats>());
|
|
|
|
|
|
2017-01-20 02:47:10 -08:00
|
|
|
RTCMediaStreamTrackStats expected_remote_video_track_ssrc3(
|
2018-01-14 09:18:58 +01:00
|
|
|
stats_of_track_type[0]->id(), report->timestamp_us(),
|
|
|
|
|
RTCMediaStreamTrackKind::kVideo);
|
2017-01-20 02:47:10 -08:00
|
|
|
expected_remote_video_track_ssrc3.track_identifier =
|
|
|
|
|
remote_video_track_ssrc3->id();
|
2019-05-22 15:49:42 +02:00
|
|
|
// |expected_remote_video_track_ssrc3.media_source_id| should be undefined
|
|
|
|
|
// because the track is remote.
|
2017-01-20 02:47:10 -08:00
|
|
|
expected_remote_video_track_ssrc3.remote_source = true;
|
|
|
|
|
expected_remote_video_track_ssrc3.ended = true;
|
|
|
|
|
expected_remote_video_track_ssrc3.detached = false;
|
|
|
|
|
expected_remote_video_track_ssrc3.frame_width = 6789;
|
|
|
|
|
expected_remote_video_track_ssrc3.frame_height = 9876;
|
2019-05-28 17:38:08 +02:00
|
|
|
expected_remote_video_track_ssrc3.jitter_buffer_delay = 2.5;
|
|
|
|
|
expected_remote_video_track_ssrc3.jitter_buffer_emitted_count = 25;
|
2017-01-23 07:21:55 -08:00
|
|
|
expected_remote_video_track_ssrc3.frames_received = 1000;
|
|
|
|
|
expected_remote_video_track_ssrc3.frames_decoded = 995;
|
2019-08-26 15:04:43 +02:00
|
|
|
expected_remote_video_track_ssrc3.frames_dropped = 10;
|
2019-01-31 16:45:42 +01:00
|
|
|
expected_remote_video_track_ssrc3.freeze_count = 3;
|
|
|
|
|
expected_remote_video_track_ssrc3.pause_count = 2;
|
|
|
|
|
expected_remote_video_track_ssrc3.total_freezes_duration = 1;
|
|
|
|
|
expected_remote_video_track_ssrc3.total_pauses_duration = 10;
|
|
|
|
|
expected_remote_video_track_ssrc3.total_frames_duration = 15;
|
|
|
|
|
expected_remote_video_track_ssrc3.sum_squared_frame_durations = 1.5;
|
|
|
|
|
|
2017-01-20 02:47:10 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_remote_video_track_ssrc3.id()));
|
|
|
|
|
EXPECT_EQ(expected_remote_video_track_ssrc3,
|
|
|
|
|
report->Get(expected_remote_video_track_ssrc3.id())
|
|
|
|
|
->cast_to<RTCMediaStreamTrackStats>());
|
2016-11-08 06:29:22 -08:00
|
|
|
}
|
|
|
|
|
|
2016-11-01 03:00:17 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
|
|
|
|
|
cricket::VoiceMediaInfo voice_media_info;
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2016-11-01 03:00:17 -07:00
|
|
|
voice_media_info.receivers.push_back(cricket::VoiceReceiverInfo());
|
|
|
|
|
voice_media_info.receivers[0].local_stats.push_back(
|
|
|
|
|
cricket::SsrcReceiverInfo());
|
|
|
|
|
voice_media_info.receivers[0].local_stats[0].ssrc = 1;
|
2017-12-13 12:26:04 +01:00
|
|
|
voice_media_info.receivers[0].packets_lost = -1; // Signed per RFC3550
|
2016-11-01 03:00:17 -07:00
|
|
|
voice_media_info.receivers[0].packets_rcvd = 2;
|
2019-04-30 09:45:21 +02:00
|
|
|
voice_media_info.receivers[0].fec_packets_discarded = 5566;
|
|
|
|
|
voice_media_info.receivers[0].fec_packets_received = 6677;
|
2019-10-09 15:01:33 +02:00
|
|
|
voice_media_info.receivers[0].payload_bytes_rcvd = 3;
|
|
|
|
|
voice_media_info.receivers[0].header_and_padding_bytes_rcvd = 4;
|
2017-11-16 10:56:07 +01:00
|
|
|
voice_media_info.receivers[0].codec_payload_type = 42;
|
2016-11-01 03:00:17 -07:00
|
|
|
voice_media_info.receivers[0].jitter_ms = 4500;
|
2020-07-06 14:18:07 +03:00
|
|
|
voice_media_info.receivers[0].jitter_buffer_delay_seconds = 1.0;
|
|
|
|
|
voice_media_info.receivers[0].jitter_buffer_emitted_count = 2;
|
|
|
|
|
voice_media_info.receivers[0].total_samples_received = 3;
|
|
|
|
|
voice_media_info.receivers[0].concealed_samples = 4;
|
|
|
|
|
voice_media_info.receivers[0].silent_concealed_samples = 5;
|
|
|
|
|
voice_media_info.receivers[0].concealment_events = 6;
|
|
|
|
|
voice_media_info.receivers[0].inserted_samples_for_deceleration = 7;
|
|
|
|
|
voice_media_info.receivers[0].removed_samples_for_acceleration = 8;
|
2020-10-27 09:50:36 +01:00
|
|
|
voice_media_info.receivers[0].audio_level = 14442; // [0,32767]
|
2020-07-06 14:18:07 +03:00
|
|
|
voice_media_info.receivers[0].total_output_energy = 10.0;
|
|
|
|
|
voice_media_info.receivers[0].total_output_duration = 11.0;
|
|
|
|
|
|
2019-04-15 17:32:00 +02:00
|
|
|
voice_media_info.receivers[0].last_packet_received_timestamp_ms =
|
|
|
|
|
absl::nullopt;
|
2016-11-23 02:32:06 -08:00
|
|
|
|
|
|
|
|
RtpCodecParameters codec_parameters;
|
|
|
|
|
codec_parameters.payload_type = 42;
|
2017-02-04 12:09:01 -08:00
|
|
|
codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
|
|
|
|
|
codec_parameters.name = "dummy";
|
2017-11-16 10:56:07 +01:00
|
|
|
codec_parameters.clock_rate = 0;
|
2016-11-23 02:32:06 -08:00
|
|
|
voice_media_info.receive_codecs.insert(
|
|
|
|
|
std::make_pair(codec_parameters.payload_type, codec_parameters));
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
|
2018-02-02 16:00:20 -08:00
|
|
|
voice_media_channel->SetStats(voice_media_info);
|
2018-03-19 13:52:56 +01:00
|
|
|
stats_->SetupRemoteTrackAndReceiver(
|
|
|
|
|
cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID", "RemoteStreamId", 1);
|
2016-11-01 03:00:17 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-01 03:00:17 -07:00
|
|
|
|
2018-01-14 09:18:58 +01:00
|
|
|
auto stats_of_track_type = report->GetStatsOfType<RTCMediaStreamTrackStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
ASSERT_EQ(1U, stats_of_track_type.size());
|
2018-01-14 09:18:58 +01:00
|
|
|
|
2016-11-01 03:00:17 -07:00
|
|
|
RTCInboundRTPStreamStats expected_audio("RTCInboundRTPAudioStream_1",
|
|
|
|
|
report->timestamp_us());
|
2017-02-07 06:28:11 -08:00
|
|
|
expected_audio.ssrc = 1;
|
2016-11-01 03:00:17 -07:00
|
|
|
expected_audio.media_type = "audio";
|
2018-08-28 14:55:03 +02:00
|
|
|
expected_audio.kind = "audio";
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_audio.track_id = stats_of_track_type[0]->id();
|
2018-02-15 15:19:50 -08:00
|
|
|
expected_audio.transport_id = "RTCTransport_TransportName_1";
|
|
|
|
|
expected_audio.codec_id = "RTCCodec_AudioMid_Inbound_42";
|
2016-11-01 03:00:17 -07:00
|
|
|
expected_audio.packets_received = 2;
|
2019-04-30 09:45:21 +02:00
|
|
|
expected_audio.fec_packets_discarded = 5566;
|
|
|
|
|
expected_audio.fec_packets_received = 6677;
|
2016-11-01 03:00:17 -07:00
|
|
|
expected_audio.bytes_received = 3;
|
2019-10-09 15:01:33 +02:00
|
|
|
expected_audio.header_bytes_received = 4;
|
2017-12-13 12:26:04 +01:00
|
|
|
expected_audio.packets_lost = -1;
|
2019-04-15 17:32:00 +02:00
|
|
|
// |expected_audio.last_packet_received_timestamp| should be undefined.
|
2016-11-01 03:00:17 -07:00
|
|
|
expected_audio.jitter = 4.5;
|
2020-07-06 14:18:07 +03:00
|
|
|
expected_audio.jitter_buffer_delay = 1.0;
|
|
|
|
|
expected_audio.jitter_buffer_emitted_count = 2;
|
|
|
|
|
expected_audio.total_samples_received = 3;
|
|
|
|
|
expected_audio.concealed_samples = 4;
|
|
|
|
|
expected_audio.silent_concealed_samples = 5;
|
|
|
|
|
expected_audio.concealment_events = 6;
|
|
|
|
|
expected_audio.inserted_samples_for_deceleration = 7;
|
|
|
|
|
expected_audio.removed_samples_for_acceleration = 8;
|
2020-10-27 09:50:36 +01:00
|
|
|
expected_audio.audio_level = 14442.0 / 32767.0; // [0,1]
|
2020-07-06 14:18:07 +03:00
|
|
|
expected_audio.total_audio_energy = 10.0;
|
|
|
|
|
expected_audio.total_samples_duration = 11.0;
|
|
|
|
|
|
2019-04-15 17:32:00 +02:00
|
|
|
ASSERT_TRUE(report->Get(expected_audio.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
report->Get(expected_audio.id())->cast_to<RTCInboundRTPStreamStats>(),
|
|
|
|
|
expected_audio);
|
|
|
|
|
|
|
|
|
|
// Set previously undefined values and "GetStats" again.
|
|
|
|
|
voice_media_info.receivers[0].last_packet_received_timestamp_ms = 3000;
|
2021-03-22 15:36:53 +01:00
|
|
|
expected_audio.last_packet_received_timestamp = 3000.0;
|
2019-10-22 15:23:44 +02:00
|
|
|
voice_media_info.receivers[0].estimated_playout_ntp_timestamp_ms = 4567;
|
|
|
|
|
expected_audio.estimated_playout_timestamp = 4567;
|
2019-04-15 17:32:00 +02:00
|
|
|
voice_media_channel->SetStats(voice_media_info);
|
|
|
|
|
|
|
|
|
|
report = stats_->GetFreshStatsReport();
|
|
|
|
|
|
2017-01-18 07:20:55 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_audio.id()));
|
2017-02-16 05:34:48 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
report->Get(expected_audio.id())->cast_to<RTCInboundRTPStreamStats>(),
|
|
|
|
|
expected_audio);
|
2017-01-27 06:35:16 -08:00
|
|
|
EXPECT_TRUE(report->Get(*expected_audio.track_id));
|
2017-01-16 06:16:44 -08:00
|
|
|
EXPECT_TRUE(report->Get(*expected_audio.transport_id));
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_audio.codec_id));
|
2016-11-01 03:00:17 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2016-11-01 03:00:17 -07:00
|
|
|
video_media_info.receivers.push_back(cricket::VideoReceiverInfo());
|
|
|
|
|
video_media_info.receivers[0].local_stats.push_back(
|
|
|
|
|
cricket::SsrcReceiverInfo());
|
|
|
|
|
video_media_info.receivers[0].local_stats[0].ssrc = 1;
|
|
|
|
|
video_media_info.receivers[0].packets_rcvd = 2;
|
2016-12-09 04:19:44 -08:00
|
|
|
video_media_info.receivers[0].packets_lost = 42;
|
2019-10-09 15:01:33 +02:00
|
|
|
video_media_info.receivers[0].payload_bytes_rcvd = 3;
|
|
|
|
|
video_media_info.receivers[0].header_and_padding_bytes_rcvd = 12;
|
2017-11-16 10:56:07 +01:00
|
|
|
video_media_info.receivers[0].codec_payload_type = 42;
|
2016-11-22 03:16:50 -08:00
|
|
|
video_media_info.receivers[0].firs_sent = 5;
|
|
|
|
|
video_media_info.receivers[0].plis_sent = 6;
|
|
|
|
|
video_media_info.receivers[0].nacks_sent = 7;
|
2020-07-06 14:18:07 +03:00
|
|
|
video_media_info.receivers[0].frames_received = 8;
|
|
|
|
|
video_media_info.receivers[0].frames_decoded = 9;
|
2019-06-27 14:29:34 +02:00
|
|
|
video_media_info.receivers[0].key_frames_decoded = 3;
|
2020-07-06 14:18:07 +03:00
|
|
|
video_media_info.receivers[0].frames_dropped = 13;
|
2018-06-19 16:47:43 +02:00
|
|
|
video_media_info.receivers[0].qp_sum = absl::nullopt;
|
2019-07-01 10:07:50 +02:00
|
|
|
video_media_info.receivers[0].total_decode_time_ms = 9000;
|
2019-11-25 10:25:42 +01:00
|
|
|
video_media_info.receivers[0].total_inter_frame_delay = 0.123;
|
|
|
|
|
video_media_info.receivers[0].total_squared_inter_frame_delay = 0.00456;
|
2021-02-19 17:34:22 -08:00
|
|
|
video_media_info.receivers[0].jitter_ms = 1199;
|
2019-11-25 10:25:42 +01:00
|
|
|
|
2019-04-15 17:32:00 +02:00
|
|
|
video_media_info.receivers[0].last_packet_received_timestamp_ms =
|
|
|
|
|
absl::nullopt;
|
2019-04-09 13:59:31 +02:00
|
|
|
video_media_info.receivers[0].content_type = VideoContentType::UNSPECIFIED;
|
2019-10-22 15:23:44 +02:00
|
|
|
video_media_info.receivers[0].estimated_playout_ntp_timestamp_ms =
|
|
|
|
|
absl::nullopt;
|
2019-08-16 13:09:51 +02:00
|
|
|
video_media_info.receivers[0].decoder_implementation_name = "";
|
2016-11-23 02:32:06 -08:00
|
|
|
|
|
|
|
|
RtpCodecParameters codec_parameters;
|
|
|
|
|
codec_parameters.payload_type = 42;
|
2017-02-04 12:09:01 -08:00
|
|
|
codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
|
|
|
|
|
codec_parameters.name = "dummy";
|
2017-11-16 10:56:07 +01:00
|
|
|
codec_parameters.clock_rate = 0;
|
2016-11-23 02:32:06 -08:00
|
|
|
video_media_info.receive_codecs.insert(
|
|
|
|
|
std::make_pair(codec_parameters.payload_type, codec_parameters));
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
|
2018-02-02 16:00:20 -08:00
|
|
|
video_media_channel->SetStats(video_media_info);
|
2018-03-19 13:52:56 +01:00
|
|
|
stats_->SetupRemoteTrackAndReceiver(
|
|
|
|
|
cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID", "RemoteStreamId", 1);
|
2016-11-01 03:00:17 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-01 03:00:17 -07:00
|
|
|
|
2016-11-22 03:16:50 -08:00
|
|
|
RTCInboundRTPStreamStats expected_video("RTCInboundRTPVideoStream_1",
|
2016-11-01 03:00:17 -07:00
|
|
|
report->timestamp_us());
|
2017-02-07 06:28:11 -08:00
|
|
|
expected_video.ssrc = 1;
|
2016-11-22 03:16:50 -08:00
|
|
|
expected_video.media_type = "video";
|
2018-08-28 14:55:03 +02:00
|
|
|
expected_video.kind = "video";
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_video.track_id = IdForType<RTCMediaStreamTrackStats>(report);
|
2018-02-15 15:19:50 -08:00
|
|
|
expected_video.transport_id = "RTCTransport_TransportName_1";
|
|
|
|
|
expected_video.codec_id = "RTCCodec_VideoMid_Inbound_42";
|
2016-11-22 03:16:50 -08:00
|
|
|
expected_video.fir_count = 5;
|
|
|
|
|
expected_video.pli_count = 6;
|
|
|
|
|
expected_video.nack_count = 7;
|
|
|
|
|
expected_video.packets_received = 2;
|
|
|
|
|
expected_video.bytes_received = 3;
|
2019-10-09 15:01:33 +02:00
|
|
|
expected_video.header_bytes_received = 12;
|
2016-12-09 04:19:44 -08:00
|
|
|
expected_video.packets_lost = 42;
|
2020-07-06 14:18:07 +03:00
|
|
|
expected_video.frames_received = 8;
|
|
|
|
|
expected_video.frames_decoded = 9;
|
2019-06-27 14:29:34 +02:00
|
|
|
expected_video.key_frames_decoded = 3;
|
2020-07-06 14:18:07 +03:00
|
|
|
expected_video.frames_dropped = 13;
|
2017-02-16 05:34:48 -08:00
|
|
|
// |expected_video.qp_sum| should be undefined.
|
2019-07-01 10:07:50 +02:00
|
|
|
expected_video.total_decode_time = 9.0;
|
2019-11-25 10:25:42 +01:00
|
|
|
expected_video.total_inter_frame_delay = 0.123;
|
|
|
|
|
expected_video.total_squared_inter_frame_delay = 0.00456;
|
2021-02-19 17:34:22 -08:00
|
|
|
expected_video.jitter = 1.199;
|
2019-04-15 17:32:00 +02:00
|
|
|
// |expected_video.last_packet_received_timestamp| should be undefined.
|
2019-04-09 13:59:31 +02:00
|
|
|
// |expected_video.content_type| should be undefined.
|
2019-08-16 13:09:51 +02:00
|
|
|
// |expected_video.decoder_implementation| should be undefined.
|
2016-11-22 03:16:50 -08:00
|
|
|
|
2017-01-18 07:20:55 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_video.id()));
|
2017-02-16 05:34:48 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
report->Get(expected_video.id())->cast_to<RTCInboundRTPStreamStats>(),
|
|
|
|
|
expected_video);
|
|
|
|
|
|
|
|
|
|
// Set previously undefined values and "GetStats" again.
|
2017-11-16 10:56:07 +01:00
|
|
|
video_media_info.receivers[0].qp_sum = 9;
|
2017-02-16 05:34:48 -08:00
|
|
|
expected_video.qp_sum = 9;
|
2019-10-22 15:23:44 +02:00
|
|
|
video_media_info.receivers[0].last_packet_received_timestamp_ms = 1000;
|
2021-03-24 08:51:26 +01:00
|
|
|
expected_video.last_packet_received_timestamp = 1000.0;
|
2019-04-09 13:59:31 +02:00
|
|
|
video_media_info.receivers[0].content_type = VideoContentType::SCREENSHARE;
|
|
|
|
|
expected_video.content_type = "screenshare";
|
2019-10-22 15:23:44 +02:00
|
|
|
video_media_info.receivers[0].estimated_playout_ntp_timestamp_ms = 1234;
|
|
|
|
|
expected_video.estimated_playout_timestamp = 1234;
|
2019-08-16 13:09:51 +02:00
|
|
|
video_media_info.receivers[0].decoder_implementation_name = "libfoodecoder";
|
|
|
|
|
expected_video.decoder_implementation = "libfoodecoder";
|
2018-02-02 16:00:20 -08:00
|
|
|
video_media_channel->SetStats(video_media_info);
|
2016-11-22 03:16:50 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
report = stats_->GetFreshStatsReport();
|
2017-02-16 05:34:48 -08:00
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_video.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
report->Get(expected_video.id())->cast_to<RTCInboundRTPStreamStats>(),
|
|
|
|
|
expected_video);
|
2017-01-27 06:35:16 -08:00
|
|
|
EXPECT_TRUE(report->Get(*expected_video.track_id));
|
2017-01-16 06:16:44 -08:00
|
|
|
EXPECT_TRUE(report->Get(*expected_video.transport_id));
|
2017-02-16 05:34:48 -08:00
|
|
|
EXPECT_TRUE(report->Get(*expected_video.codec_id));
|
2016-11-01 03:00:17 -07:00
|
|
|
}
|
|
|
|
|
|
2016-11-01 01:50:46 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
|
|
|
|
|
cricket::VoiceMediaInfo voice_media_info;
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2016-11-01 01:50:46 -07:00
|
|
|
voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
|
|
|
|
|
voice_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
voice_media_info.senders[0].local_stats[0].ssrc = 1;
|
|
|
|
|
voice_media_info.senders[0].packets_sent = 2;
|
2019-04-17 13:51:53 +02:00
|
|
|
voice_media_info.senders[0].retransmitted_packets_sent = 20;
|
2019-10-09 15:01:33 +02:00
|
|
|
voice_media_info.senders[0].payload_bytes_sent = 3;
|
|
|
|
|
voice_media_info.senders[0].header_and_padding_bytes_sent = 12;
|
2019-04-17 13:51:53 +02:00
|
|
|
voice_media_info.senders[0].retransmitted_bytes_sent = 30;
|
2017-11-16 10:56:07 +01:00
|
|
|
voice_media_info.senders[0].codec_payload_type = 42;
|
2016-11-23 02:32:06 -08:00
|
|
|
|
|
|
|
|
RtpCodecParameters codec_parameters;
|
|
|
|
|
codec_parameters.payload_type = 42;
|
2017-02-04 12:09:01 -08:00
|
|
|
codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
|
|
|
|
|
codec_parameters.name = "dummy";
|
2017-11-16 10:56:07 +01:00
|
|
|
codec_parameters.clock_rate = 0;
|
2016-11-23 02:32:06 -08:00
|
|
|
voice_media_info.send_codecs.insert(
|
|
|
|
|
std::make_pair(codec_parameters.payload_type, codec_parameters));
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
|
2018-02-02 16:00:20 -08:00
|
|
|
voice_media_channel->SetStats(voice_media_info);
|
|
|
|
|
stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_AUDIO,
|
2019-05-22 15:49:42 +02:00
|
|
|
"LocalAudioTrackID", 1, true,
|
|
|
|
|
/*attachment_id=*/50);
|
2016-11-01 01:50:46 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-01 01:50:46 -07:00
|
|
|
|
|
|
|
|
RTCOutboundRTPStreamStats expected_audio("RTCOutboundRTPAudioStream_1",
|
|
|
|
|
report->timestamp_us());
|
2019-05-22 15:49:42 +02:00
|
|
|
expected_audio.media_source_id = "RTCAudioSource_50";
|
2019-12-19 13:27:27 +01:00
|
|
|
// |expected_audio.remote_id| should be undefined.
|
2017-02-07 06:28:11 -08:00
|
|
|
expected_audio.ssrc = 1;
|
2016-11-01 01:50:46 -07:00
|
|
|
expected_audio.media_type = "audio";
|
2018-08-28 14:55:03 +02:00
|
|
|
expected_audio.kind = "audio";
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_audio.track_id = IdForType<RTCMediaStreamTrackStats>(report);
|
2018-02-15 15:19:50 -08:00
|
|
|
expected_audio.transport_id = "RTCTransport_TransportName_1";
|
|
|
|
|
expected_audio.codec_id = "RTCCodec_AudioMid_Outbound_42";
|
2016-11-01 01:50:46 -07:00
|
|
|
expected_audio.packets_sent = 2;
|
2019-04-17 13:51:53 +02:00
|
|
|
expected_audio.retransmitted_packets_sent = 20;
|
2016-11-01 01:50:46 -07:00
|
|
|
expected_audio.bytes_sent = 3;
|
2019-10-09 15:01:33 +02:00
|
|
|
expected_audio.header_bytes_sent = 12;
|
2019-04-17 13:51:53 +02:00
|
|
|
expected_audio.retransmitted_bytes_sent = 30;
|
2017-02-07 08:31:27 -08:00
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_audio.id()));
|
2017-02-16 05:34:48 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
report->Get(expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>(),
|
|
|
|
|
expected_audio);
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_audio.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
report->Get(expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>(),
|
|
|
|
|
expected_audio);
|
2017-01-27 06:35:16 -08:00
|
|
|
EXPECT_TRUE(report->Get(*expected_audio.track_id));
|
2017-01-16 06:16:44 -08:00
|
|
|
EXPECT_TRUE(report->Get(*expected_audio.transport_id));
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_audio.codec_id));
|
2016-11-01 01:50:46 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
2016-11-23 02:32:06 -08:00
|
|
|
|
2016-11-01 01:50:46 -07:00
|
|
|
video_media_info.senders.push_back(cricket::VideoSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats[0].ssrc = 1;
|
|
|
|
|
video_media_info.senders[0].firs_rcvd = 2;
|
|
|
|
|
video_media_info.senders[0].plis_rcvd = 3;
|
|
|
|
|
video_media_info.senders[0].nacks_rcvd = 4;
|
|
|
|
|
video_media_info.senders[0].packets_sent = 5;
|
2019-04-17 13:51:53 +02:00
|
|
|
video_media_info.senders[0].retransmitted_packets_sent = 50;
|
2019-10-09 15:01:33 +02:00
|
|
|
video_media_info.senders[0].payload_bytes_sent = 6;
|
|
|
|
|
video_media_info.senders[0].header_and_padding_bytes_sent = 12;
|
2019-04-17 13:51:53 +02:00
|
|
|
video_media_info.senders[0].retransmitted_bytes_sent = 60;
|
2017-11-16 10:56:07 +01:00
|
|
|
video_media_info.senders[0].codec_payload_type = 42;
|
2017-01-02 08:35:13 -08:00
|
|
|
video_media_info.senders[0].frames_encoded = 8;
|
2019-06-27 14:29:34 +02:00
|
|
|
video_media_info.senders[0].key_frames_encoded = 3;
|
2019-04-08 16:14:23 +02:00
|
|
|
video_media_info.senders[0].total_encode_time_ms = 9000;
|
2019-05-20 15:15:38 +02:00
|
|
|
video_media_info.senders[0].total_encoded_bytes_target = 1234;
|
2019-05-16 18:38:20 +02:00
|
|
|
video_media_info.senders[0].total_packet_send_delay_ms = 10000;
|
2019-05-28 17:42:38 +02:00
|
|
|
video_media_info.senders[0].quality_limitation_reason =
|
|
|
|
|
QualityLimitationReason::kBandwidth;
|
2021-05-28 21:32:04 +09:00
|
|
|
video_media_info.senders[0].quality_limitation_durations_ms
|
|
|
|
|
[webrtc::QualityLimitationReason::kBandwidth] = 300;
|
2019-09-09 11:26:45 +02:00
|
|
|
video_media_info.senders[0].quality_limitation_resolution_changes = 56u;
|
2018-06-19 16:47:43 +02:00
|
|
|
video_media_info.senders[0].qp_sum = absl::nullopt;
|
2019-04-09 13:59:31 +02:00
|
|
|
video_media_info.senders[0].content_type = VideoContentType::UNSPECIFIED;
|
2019-08-16 13:09:51 +02:00
|
|
|
video_media_info.senders[0].encoder_implementation_name = "";
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
video_media_info.senders[0].send_frame_width = 200;
|
|
|
|
|
video_media_info.senders[0].send_frame_height = 100;
|
|
|
|
|
video_media_info.senders[0].framerate_sent = 10;
|
|
|
|
|
video_media_info.senders[0].frames_sent = 5;
|
|
|
|
|
video_media_info.senders[0].huge_frames_sent = 2;
|
|
|
|
|
video_media_info.aggregated_senders.push_back(video_media_info.senders[0]);
|
2016-11-23 02:32:06 -08:00
|
|
|
RtpCodecParameters codec_parameters;
|
|
|
|
|
codec_parameters.payload_type = 42;
|
2017-02-04 12:09:01 -08:00
|
|
|
codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
|
|
|
|
|
codec_parameters.name = "dummy";
|
2017-11-16 10:56:07 +01:00
|
|
|
codec_parameters.clock_rate = 0;
|
2016-11-23 02:32:06 -08:00
|
|
|
video_media_info.send_codecs.insert(
|
|
|
|
|
std::make_pair(codec_parameters.payload_type, codec_parameters));
|
|
|
|
|
|
2018-02-15 15:19:50 -08:00
|
|
|
auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
|
2018-02-02 16:00:20 -08:00
|
|
|
video_media_channel->SetStats(video_media_info);
|
|
|
|
|
stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_VIDEO,
|
2019-05-22 15:49:42 +02:00
|
|
|
"LocalVideoTrackID", 1, true,
|
|
|
|
|
/*attachment_id=*/50);
|
2016-11-01 01:50:46 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-01 01:50:46 -07:00
|
|
|
|
2018-01-14 09:18:58 +01:00
|
|
|
auto stats_of_my_type = report->GetStatsOfType<RTCOutboundRTPStreamStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
ASSERT_EQ(1U, stats_of_my_type.size());
|
2018-01-14 09:18:58 +01:00
|
|
|
auto stats_of_track_type = report->GetStatsOfType<RTCMediaStreamTrackStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
ASSERT_EQ(1U, stats_of_track_type.size());
|
2018-01-14 09:18:58 +01:00
|
|
|
|
|
|
|
|
RTCOutboundRTPStreamStats expected_video(stats_of_my_type[0]->id(),
|
|
|
|
|
report->timestamp_us());
|
2019-05-22 15:49:42 +02:00
|
|
|
expected_video.media_source_id = "RTCVideoSource_50";
|
2019-12-19 13:27:27 +01:00
|
|
|
// |expected_video.remote_id| should be undefined.
|
2017-02-07 06:28:11 -08:00
|
|
|
expected_video.ssrc = 1;
|
2016-11-01 01:50:46 -07:00
|
|
|
expected_video.media_type = "video";
|
2018-08-28 14:55:03 +02:00
|
|
|
expected_video.kind = "video";
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_video.track_id = stats_of_track_type[0]->id();
|
2018-02-15 15:19:50 -08:00
|
|
|
expected_video.transport_id = "RTCTransport_TransportName_1";
|
|
|
|
|
expected_video.codec_id = "RTCCodec_VideoMid_Outbound_42";
|
2016-11-01 01:50:46 -07:00
|
|
|
expected_video.fir_count = 2;
|
|
|
|
|
expected_video.pli_count = 3;
|
|
|
|
|
expected_video.nack_count = 4;
|
|
|
|
|
expected_video.packets_sent = 5;
|
2019-04-17 13:51:53 +02:00
|
|
|
expected_video.retransmitted_packets_sent = 50;
|
2016-11-01 01:50:46 -07:00
|
|
|
expected_video.bytes_sent = 6;
|
2019-10-09 15:01:33 +02:00
|
|
|
expected_video.header_bytes_sent = 12;
|
2019-04-17 13:51:53 +02:00
|
|
|
expected_video.retransmitted_bytes_sent = 60;
|
2017-01-02 08:35:13 -08:00
|
|
|
expected_video.frames_encoded = 8;
|
2019-06-27 14:29:34 +02:00
|
|
|
expected_video.key_frames_encoded = 3;
|
2019-04-08 16:14:23 +02:00
|
|
|
expected_video.total_encode_time = 9.0;
|
2019-05-20 15:15:38 +02:00
|
|
|
expected_video.total_encoded_bytes_target = 1234;
|
2019-05-16 18:38:20 +02:00
|
|
|
expected_video.total_packet_send_delay = 10.0;
|
2019-05-28 17:42:38 +02:00
|
|
|
expected_video.quality_limitation_reason = "bandwidth";
|
2021-05-28 21:32:04 +09:00
|
|
|
expected_video.quality_limitation_durations = std::map<std::string, double>{
|
|
|
|
|
std::pair<std::string, double>{"bandwidth", 300.0},
|
|
|
|
|
};
|
2019-09-09 11:26:45 +02:00
|
|
|
expected_video.quality_limitation_resolution_changes = 56u;
|
2020-06-10 17:53:39 +03:00
|
|
|
expected_video.frame_width = 200u;
|
|
|
|
|
expected_video.frame_height = 100u;
|
|
|
|
|
expected_video.frames_per_second = 10.0;
|
|
|
|
|
expected_video.frames_sent = 5;
|
|
|
|
|
expected_video.huge_frames_sent = 2;
|
2019-04-09 13:59:31 +02:00
|
|
|
// |expected_video.content_type| should be undefined.
|
2017-03-01 01:02:45 -08:00
|
|
|
// |expected_video.qp_sum| should be undefined.
|
2019-08-16 13:09:51 +02:00
|
|
|
// |expected_video.encoder_implementation| should be undefined.
|
2017-01-18 07:20:55 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_video.id()));
|
2018-01-14 09:18:58 +01:00
|
|
|
|
2017-02-16 05:34:48 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
report->Get(expected_video.id())->cast_to<RTCOutboundRTPStreamStats>(),
|
|
|
|
|
expected_video);
|
2017-02-07 10:45:31 -08:00
|
|
|
|
2017-02-16 05:34:48 -08:00
|
|
|
// Set previously undefined values and "GetStats" again.
|
2017-11-16 10:56:07 +01:00
|
|
|
video_media_info.senders[0].qp_sum = 9;
|
2017-02-16 05:34:48 -08:00
|
|
|
expected_video.qp_sum = 9;
|
2019-04-09 13:59:31 +02:00
|
|
|
video_media_info.senders[0].content_type = VideoContentType::SCREENSHARE;
|
|
|
|
|
expected_video.content_type = "screenshare";
|
2019-08-16 13:09:51 +02:00
|
|
|
video_media_info.senders[0].encoder_implementation_name = "libfooencoder";
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
video_media_info.aggregated_senders[0] = video_media_info.senders[0];
|
2019-08-16 13:09:51 +02:00
|
|
|
expected_video.encoder_implementation = "libfooencoder";
|
2018-02-02 16:00:20 -08:00
|
|
|
video_media_channel->SetStats(video_media_info);
|
2016-12-15 01:54:29 -08:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
report = stats_->GetFreshStatsReport();
|
2016-12-15 01:54:29 -08:00
|
|
|
|
2017-01-18 07:20:55 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_video.id()));
|
2017-02-16 05:34:48 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
report->Get(expected_video.id())->cast_to<RTCOutboundRTPStreamStats>(),
|
|
|
|
|
expected_video);
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_video.track_id));
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_video.transport_id));
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_video.codec_id));
|
2016-12-15 01:54:29 -08:00
|
|
|
}
|
|
|
|
|
|
2016-10-24 04:00:05 -07:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCTransportStats) {
|
2018-02-02 16:00:20 -08:00
|
|
|
const char kTransportName[] = "transport";
|
|
|
|
|
|
|
|
|
|
pc_->AddVoiceChannel("audio", kTransportName);
|
|
|
|
|
|
2017-11-21 10:49:36 -08:00
|
|
|
std::unique_ptr<cricket::Candidate> rtp_local_candidate =
|
|
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_WIFI,
|
|
|
|
|
cricket::LOCAL_PORT_TYPE, 42);
|
2016-10-24 04:00:05 -07:00
|
|
|
std::unique_ptr<cricket::Candidate> rtp_remote_candidate =
|
|
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "protocol",
|
2017-11-21 10:49:36 -08:00
|
|
|
rtc::ADAPTER_TYPE_UNKNOWN, cricket::LOCAL_PORT_TYPE,
|
|
|
|
|
42);
|
2016-10-24 04:00:05 -07:00
|
|
|
std::unique_ptr<cricket::Candidate> rtcp_local_candidate =
|
2017-11-21 10:49:36 -08:00
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_WIFI,
|
2016-10-24 04:00:05 -07:00
|
|
|
cricket::LOCAL_PORT_TYPE, 42);
|
|
|
|
|
std::unique_ptr<cricket::Candidate> rtcp_remote_candidate =
|
|
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "protocol",
|
2017-11-21 10:49:36 -08:00
|
|
|
rtc::ADAPTER_TYPE_UNKNOWN, cricket::LOCAL_PORT_TYPE,
|
|
|
|
|
42);
|
2016-10-24 04:00:05 -07:00
|
|
|
|
|
|
|
|
cricket::ConnectionInfo rtp_connection_info;
|
|
|
|
|
rtp_connection_info.best_connection = false;
|
|
|
|
|
rtp_connection_info.local_candidate = *rtp_local_candidate.get();
|
|
|
|
|
rtp_connection_info.remote_candidate = *rtp_remote_candidate.get();
|
|
|
|
|
rtp_connection_info.sent_total_bytes = 42;
|
|
|
|
|
rtp_connection_info.recv_total_bytes = 1337;
|
2020-07-06 16:06:37 +02:00
|
|
|
rtp_connection_info.sent_total_packets = 3;
|
|
|
|
|
rtp_connection_info.sent_discarded_packets = 2;
|
|
|
|
|
rtp_connection_info.packets_received = 4;
|
2016-10-24 04:00:05 -07:00
|
|
|
cricket::TransportChannelStats rtp_transport_channel_stats;
|
|
|
|
|
rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
2019-08-28 08:10:27 +02:00
|
|
|
rtp_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
|
|
|
|
rtp_connection_info);
|
2021-05-21 20:46:09 +02:00
|
|
|
rtp_transport_channel_stats.dtls_state = DtlsTransportState::kNew;
|
2019-08-28 08:10:27 +02:00
|
|
|
rtp_transport_channel_stats.ice_transport_stats
|
|
|
|
|
.selected_candidate_pair_changes = 1;
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats});
|
2016-10-24 04:00:05 -07:00
|
|
|
|
|
|
|
|
// Get stats without RTCP, an active connection or certificates.
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2016-11-30 01:50:14 -08:00
|
|
|
|
|
|
|
|
RTCTransportStats expected_rtp_transport(
|
|
|
|
|
"RTCTransport_transport_" +
|
2018-07-05 11:59:48 +02:00
|
|
|
rtc::ToString(cricket::ICE_CANDIDATE_COMPONENT_RTP),
|
2016-11-30 01:50:14 -08:00
|
|
|
report->timestamp_us());
|
|
|
|
|
expected_rtp_transport.bytes_sent = 42;
|
2020-07-06 16:06:37 +02:00
|
|
|
expected_rtp_transport.packets_sent = 1;
|
2016-11-30 01:50:14 -08:00
|
|
|
expected_rtp_transport.bytes_received = 1337;
|
2020-07-06 16:06:37 +02:00
|
|
|
expected_rtp_transport.packets_received = 4;
|
2017-01-16 07:38:02 -08:00
|
|
|
expected_rtp_transport.dtls_state = RTCDtlsTransportState::kNew;
|
2019-08-28 08:10:27 +02:00
|
|
|
expected_rtp_transport.selected_candidate_pair_changes = 1;
|
2016-11-30 01:50:14 -08:00
|
|
|
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
|
2016-11-30 01:50:14 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_rtp_transport,
|
|
|
|
|
report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
|
2016-10-24 04:00:05 -07:00
|
|
|
|
|
|
|
|
cricket::ConnectionInfo rtcp_connection_info;
|
|
|
|
|
rtcp_connection_info.best_connection = false;
|
|
|
|
|
rtcp_connection_info.local_candidate = *rtcp_local_candidate.get();
|
|
|
|
|
rtcp_connection_info.remote_candidate = *rtcp_remote_candidate.get();
|
|
|
|
|
rtcp_connection_info.sent_total_bytes = 1337;
|
|
|
|
|
rtcp_connection_info.recv_total_bytes = 42;
|
2020-07-06 16:06:37 +02:00
|
|
|
rtcp_connection_info.sent_total_packets = 3;
|
|
|
|
|
rtcp_connection_info.sent_discarded_packets = 2;
|
|
|
|
|
rtcp_connection_info.packets_received = 4;
|
2016-10-24 04:00:05 -07:00
|
|
|
cricket::TransportChannelStats rtcp_transport_channel_stats;
|
|
|
|
|
rtcp_transport_channel_stats.component =
|
|
|
|
|
cricket::ICE_CANDIDATE_COMPONENT_RTCP;
|
2019-08-28 08:10:27 +02:00
|
|
|
rtcp_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
|
|
|
|
rtcp_connection_info);
|
2021-05-21 20:46:09 +02:00
|
|
|
rtcp_transport_channel_stats.dtls_state = DtlsTransportState::kConnecting;
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
|
|
|
|
|
rtcp_transport_channel_stats});
|
2016-10-24 04:00:05 -07:00
|
|
|
|
|
|
|
|
// Get stats with RTCP and without an active connection or certificates.
|
2018-02-02 16:00:20 -08:00
|
|
|
report = stats_->GetFreshStatsReport();
|
2016-11-30 01:50:14 -08:00
|
|
|
|
|
|
|
|
RTCTransportStats expected_rtcp_transport(
|
|
|
|
|
"RTCTransport_transport_" +
|
2018-07-05 11:59:48 +02:00
|
|
|
rtc::ToString(cricket::ICE_CANDIDATE_COMPONENT_RTCP),
|
2016-11-30 01:50:14 -08:00
|
|
|
report->timestamp_us());
|
|
|
|
|
expected_rtcp_transport.bytes_sent = 1337;
|
2020-07-06 16:06:37 +02:00
|
|
|
expected_rtcp_transport.packets_sent = 1;
|
2016-11-30 01:50:14 -08:00
|
|
|
expected_rtcp_transport.bytes_received = 42;
|
2020-07-06 16:06:37 +02:00
|
|
|
expected_rtcp_transport.packets_received = 4;
|
2017-01-16 07:38:02 -08:00
|
|
|
expected_rtcp_transport.dtls_state = RTCDtlsTransportState::kConnecting;
|
2019-08-28 08:10:27 +02:00
|
|
|
expected_rtcp_transport.selected_candidate_pair_changes = 0;
|
2016-11-30 01:50:14 -08:00
|
|
|
|
|
|
|
|
expected_rtp_transport.rtcp_transport_stats_id = expected_rtcp_transport.id();
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
|
2016-11-30 01:50:14 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_rtp_transport,
|
|
|
|
|
report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
|
2016-11-30 01:50:14 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_rtcp_transport,
|
|
|
|
|
report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
|
2016-10-24 04:00:05 -07:00
|
|
|
|
2017-01-16 07:38:02 -08:00
|
|
|
// Get stats with an active connection (selected candidate pair).
|
2019-08-28 08:10:27 +02:00
|
|
|
rtcp_transport_channel_stats.ice_transport_stats.connection_infos[0]
|
|
|
|
|
.best_connection = true;
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats,
|
|
|
|
|
rtcp_transport_channel_stats});
|
2016-10-24 04:00:05 -07:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
report = stats_->GetFreshStatsReport();
|
2016-11-30 01:50:14 -08:00
|
|
|
|
|
|
|
|
expected_rtcp_transport.selected_candidate_pair_id =
|
|
|
|
|
"RTCIceCandidatePair_" + rtcp_local_candidate->id() + "_" +
|
|
|
|
|
rtcp_remote_candidate->id();
|
|
|
|
|
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
|
2016-11-30 01:50:14 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_rtp_transport,
|
|
|
|
|
report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
|
2016-11-30 01:50:14 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_rtcp_transport,
|
|
|
|
|
report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
|
2016-10-24 04:00:05 -07:00
|
|
|
|
|
|
|
|
// Get stats with certificates.
|
|
|
|
|
std::unique_ptr<CertificateInfo> local_certinfo =
|
2018-02-02 16:00:20 -08:00
|
|
|
CreateFakeCertificateAndInfoFromDers({"(local) local", "(local) chain"});
|
|
|
|
|
pc_->SetLocalCertificate(kTransportName, local_certinfo->certificate);
|
2016-10-24 04:00:05 -07:00
|
|
|
std::unique_ptr<CertificateInfo> remote_certinfo =
|
|
|
|
|
CreateFakeCertificateAndInfoFromDers(
|
2018-02-02 16:00:20 -08:00
|
|
|
{"(remote) local", "(remote) chain"});
|
2018-02-23 13:04:51 -08:00
|
|
|
pc_->SetRemoteCertChain(
|
2018-10-25 01:16:26 -07:00
|
|
|
kTransportName,
|
|
|
|
|
remote_certinfo->certificate->GetSSLCertificateChain().Clone());
|
2018-02-02 16:00:20 -08:00
|
|
|
|
|
|
|
|
report = stats_->GetFreshStatsReport();
|
2016-11-30 01:50:14 -08:00
|
|
|
|
|
|
|
|
expected_rtp_transport.local_certificate_id =
|
|
|
|
|
"RTCCertificate_" + local_certinfo->fingerprints[0];
|
|
|
|
|
expected_rtp_transport.remote_certificate_id =
|
|
|
|
|
"RTCCertificate_" + remote_certinfo->fingerprints[0];
|
|
|
|
|
|
|
|
|
|
expected_rtcp_transport.local_certificate_id =
|
|
|
|
|
*expected_rtp_transport.local_certificate_id;
|
|
|
|
|
expected_rtcp_transport.remote_certificate_id =
|
|
|
|
|
*expected_rtp_transport.remote_certificate_id;
|
|
|
|
|
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
|
2016-11-30 01:50:14 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_rtp_transport,
|
|
|
|
|
report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
|
2016-12-21 01:57:46 -08:00
|
|
|
ASSERT_TRUE(report->Get(expected_rtcp_transport.id()));
|
2016-11-30 01:50:14 -08:00
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_rtcp_transport,
|
|
|
|
|
report->Get(expected_rtcp_transport.id())->cast_to<RTCTransportStats>());
|
2016-10-24 04:00:05 -07:00
|
|
|
}
|
|
|
|
|
|
2019-10-28 09:51:17 +01:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectRTCTransportStatsWithCrypto) {
|
|
|
|
|
const char kTransportName[] = "transport";
|
|
|
|
|
|
|
|
|
|
pc_->AddVoiceChannel("audio", kTransportName);
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<cricket::Candidate> rtp_local_candidate =
|
|
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_WIFI,
|
|
|
|
|
cricket::LOCAL_PORT_TYPE, 42);
|
|
|
|
|
std::unique_ptr<cricket::Candidate> rtp_remote_candidate =
|
|
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "protocol",
|
|
|
|
|
rtc::ADAPTER_TYPE_UNKNOWN, cricket::LOCAL_PORT_TYPE,
|
|
|
|
|
42);
|
|
|
|
|
std::unique_ptr<cricket::Candidate> rtcp_local_candidate =
|
|
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "protocol", rtc::ADAPTER_TYPE_WIFI,
|
|
|
|
|
cricket::LOCAL_PORT_TYPE, 42);
|
|
|
|
|
std::unique_ptr<cricket::Candidate> rtcp_remote_candidate =
|
|
|
|
|
CreateFakeCandidate("42.42.42.42", 42, "protocol",
|
|
|
|
|
rtc::ADAPTER_TYPE_UNKNOWN, cricket::LOCAL_PORT_TYPE,
|
|
|
|
|
42);
|
|
|
|
|
|
|
|
|
|
cricket::ConnectionInfo rtp_connection_info;
|
|
|
|
|
rtp_connection_info.best_connection = false;
|
|
|
|
|
rtp_connection_info.local_candidate = *rtp_local_candidate.get();
|
|
|
|
|
rtp_connection_info.remote_candidate = *rtp_remote_candidate.get();
|
|
|
|
|
rtp_connection_info.sent_total_bytes = 42;
|
|
|
|
|
rtp_connection_info.recv_total_bytes = 1337;
|
2020-07-06 16:06:37 +02:00
|
|
|
rtp_connection_info.sent_total_packets = 3;
|
|
|
|
|
rtp_connection_info.sent_discarded_packets = 2;
|
|
|
|
|
rtp_connection_info.packets_received = 4;
|
2019-10-28 09:51:17 +01:00
|
|
|
cricket::TransportChannelStats rtp_transport_channel_stats;
|
|
|
|
|
rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
|
|
|
|
rtp_transport_channel_stats.ice_transport_stats.connection_infos.push_back(
|
|
|
|
|
rtp_connection_info);
|
|
|
|
|
// The state must be connected in order for crypto parameters to show up.
|
2021-05-21 20:46:09 +02:00
|
|
|
rtp_transport_channel_stats.dtls_state = DtlsTransportState::kConnected;
|
2019-10-28 09:51:17 +01:00
|
|
|
rtp_transport_channel_stats.ice_transport_stats
|
|
|
|
|
.selected_candidate_pair_changes = 1;
|
|
|
|
|
rtp_transport_channel_stats.ssl_version_bytes = 0x0203;
|
|
|
|
|
// 0x2F is TLS_RSA_WITH_AES_128_CBC_SHA according to IANA
|
|
|
|
|
rtp_transport_channel_stats.ssl_cipher_suite = 0x2F;
|
|
|
|
|
rtp_transport_channel_stats.srtp_crypto_suite = rtc::SRTP_AES128_CM_SHA1_80;
|
|
|
|
|
pc_->SetTransportStats(kTransportName, {rtp_transport_channel_stats});
|
|
|
|
|
|
|
|
|
|
// Get stats
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
|
|
|
|
RTCTransportStats expected_rtp_transport(
|
|
|
|
|
"RTCTransport_transport_" +
|
|
|
|
|
rtc::ToString(cricket::ICE_CANDIDATE_COMPONENT_RTP),
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected_rtp_transport.bytes_sent = 42;
|
2020-07-06 16:06:37 +02:00
|
|
|
expected_rtp_transport.packets_sent = 1;
|
2019-10-28 09:51:17 +01:00
|
|
|
expected_rtp_transport.bytes_received = 1337;
|
2020-07-06 16:06:37 +02:00
|
|
|
expected_rtp_transport.packets_received = 4;
|
2019-10-28 09:51:17 +01:00
|
|
|
expected_rtp_transport.dtls_state = RTCDtlsTransportState::kConnected;
|
|
|
|
|
expected_rtp_transport.selected_candidate_pair_changes = 1;
|
|
|
|
|
// Crypto parameters
|
|
|
|
|
expected_rtp_transport.tls_version = "0203";
|
|
|
|
|
expected_rtp_transport.dtls_cipher = "TLS_RSA_WITH_AES_128_CBC_SHA";
|
|
|
|
|
expected_rtp_transport.srtp_cipher = "AES_CM_128_HMAC_SHA1_80";
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_rtp_transport.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
expected_rtp_transport,
|
|
|
|
|
report->Get(expected_rtp_transport.id())->cast_to<RTCTransportStats>());
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-02 14:08:34 +01:00
|
|
|
TEST_F(RTCStatsCollectorTest, CollectNoStreamRTCOutboundRTPStreamStats_Audio) {
|
|
|
|
|
cricket::VoiceMediaInfo voice_media_info;
|
|
|
|
|
|
|
|
|
|
voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
|
|
|
|
|
voice_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
voice_media_info.senders[0].local_stats[0].ssrc = 1;
|
|
|
|
|
voice_media_info.senders[0].packets_sent = 2;
|
2019-04-17 13:51:53 +02:00
|
|
|
voice_media_info.senders[0].retransmitted_packets_sent = 20;
|
2019-10-09 15:01:33 +02:00
|
|
|
voice_media_info.senders[0].payload_bytes_sent = 3;
|
|
|
|
|
voice_media_info.senders[0].header_and_padding_bytes_sent = 4;
|
2019-04-17 13:51:53 +02:00
|
|
|
voice_media_info.senders[0].retransmitted_bytes_sent = 30;
|
2018-01-02 14:08:34 +01:00
|
|
|
voice_media_info.senders[0].codec_payload_type = 42;
|
|
|
|
|
|
|
|
|
|
RtpCodecParameters codec_parameters;
|
|
|
|
|
codec_parameters.payload_type = 42;
|
|
|
|
|
codec_parameters.kind = cricket::MEDIA_TYPE_AUDIO;
|
|
|
|
|
codec_parameters.name = "dummy";
|
|
|
|
|
codec_parameters.clock_rate = 0;
|
|
|
|
|
voice_media_info.send_codecs.insert(
|
|
|
|
|
std::make_pair(codec_parameters.payload_type, codec_parameters));
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
// Emulates the case where AddTrack is used without an associated MediaStream
|
2018-02-15 15:19:50 -08:00
|
|
|
auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
|
2018-02-02 16:00:20 -08:00
|
|
|
voice_media_channel->SetStats(voice_media_info);
|
|
|
|
|
stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_AUDIO,
|
2019-05-22 15:49:42 +02:00
|
|
|
"LocalAudioTrackID", 1, false,
|
|
|
|
|
/*attachment_id=*/50);
|
2018-01-02 14:08:34 +01:00
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2018-01-02 14:08:34 +01:00
|
|
|
|
|
|
|
|
RTCOutboundRTPStreamStats expected_audio("RTCOutboundRTPAudioStream_1",
|
|
|
|
|
report->timestamp_us());
|
2019-05-22 15:49:42 +02:00
|
|
|
expected_audio.media_source_id = "RTCAudioSource_50";
|
2018-01-02 14:08:34 +01:00
|
|
|
expected_audio.ssrc = 1;
|
|
|
|
|
expected_audio.media_type = "audio";
|
2018-08-28 14:55:03 +02:00
|
|
|
expected_audio.kind = "audio";
|
2018-01-14 09:18:58 +01:00
|
|
|
expected_audio.track_id = IdForType<RTCMediaStreamTrackStats>(report);
|
2018-02-15 15:19:50 -08:00
|
|
|
expected_audio.transport_id = "RTCTransport_TransportName_1";
|
|
|
|
|
expected_audio.codec_id = "RTCCodec_AudioMid_Outbound_42";
|
2018-01-02 14:08:34 +01:00
|
|
|
expected_audio.packets_sent = 2;
|
2019-04-17 13:51:53 +02:00
|
|
|
expected_audio.retransmitted_packets_sent = 20;
|
2018-01-02 14:08:34 +01:00
|
|
|
expected_audio.bytes_sent = 3;
|
2019-10-09 15:01:33 +02:00
|
|
|
expected_audio.header_bytes_sent = 4;
|
2019-04-17 13:51:53 +02:00
|
|
|
expected_audio.retransmitted_bytes_sent = 30;
|
2018-01-02 14:08:34 +01:00
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_audio.id()));
|
|
|
|
|
EXPECT_EQ(
|
|
|
|
|
report->Get(expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>(),
|
|
|
|
|
expected_audio);
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_audio.track_id));
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_audio.transport_id));
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_audio.codec_id));
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-22 15:49:42 +02:00
|
|
|
TEST_F(RTCStatsCollectorTest, RTCAudioSourceStatsCollectedForSenderWithTrack) {
|
|
|
|
|
const uint32_t kSsrc = 4;
|
|
|
|
|
const int kAttachmentId = 42;
|
|
|
|
|
|
|
|
|
|
cricket::VoiceMediaInfo voice_media_info;
|
|
|
|
|
voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
|
|
|
|
|
voice_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
voice_media_info.senders[0].local_stats[0].ssrc = kSsrc;
|
[getStats] Implement "media-source" audio levels, fixing Chrome bug.
Implements RTCAudioSourceStats members:
- audioLevel
- totalAudioEnergy
- totalSamplesDuration
In this CL description these are collectively referred to as the audio
levels.
The audio levels are removed from sending "track" stats (in Chrome,
these are now reported as undefined instead of 0).
Background:
For sending tracks, audio levels were always reported as 0 in Chrome
(https://crbug.com/736403), while audio levels were correctly reported
for receiving tracks. This problem affected the standard getStats() but
not the legacy getStats(), blocking some people from migrating. This
was likely not a problem in native third_party/webrtc code because the
delivery of audio frames from device to send-stream uses a different
code path outside of chromium.
A recent PR (https://github.com/w3c/webrtc-stats/pull/451) moved the
send-side audio levels to the RTCAudioSourceStats, while keeping the
receive-side audio levels on the "track" stats. This allows an
implementation to report the audio levels even if samples are not sent
onto the network (such as if an ICE connection has not been established
yet), reflecting some of the current implementation.
Changes:
1. Audio levels are added to RTCAudioSourceStats. Send-side audio
"track" stats are left undefined. Receive-side audio "track" stats
are not changed in this CL and continue to work.
2. Audio level computation is moved from the AudioState and
AudioTransportImpl to the AudioSendStream. This is because a) the
AudioTransportImpl::RecordedDataIsAvailable() code path is not
exercised in chromium, and b) audio levels should, per-spec, not be
calculated on a per-call basis, for which the AudioState is defined.
3. The audio level computation is now performed in
AudioSendStream::SendAudioData(), a code path used by both native
and chromium code.
4. Comments are added to document behavior of existing code, such as
AudioLevel and AudioSendStream::SendAudioData().
Note:
In this CL, just like before this CL, audio level is only calculated
after an AudioSendStream has been created. This means that before an
O/A negotiation, audio levels are unavailable.
According to spec, if we have an audio source, we should have audio
levels. An immediate solution to this would have been to calculate the
audio level at pc/rtp_sender.cc. The problem is that the
LocalAudioSinkAdapter::OnData() code path, while exercised in chromium,
is not exercised in native code. The issue of calculating audio levels
on a per-source bases rather than on a per-send stream basis is left to
https://crbug.com/webrtc/10771, an existing "media-source" bug.
This CL can be verified manually in Chrome at:
https://codepen.io/anon/pen/vqRGyq
Bug: chromium:736403, webrtc:10771
Change-Id: I8036cd9984f3b187c3177470a8c0d6670a201a5a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/143789
Reviewed-by: Oskar Sundbom <ossu@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28480}
2019-07-03 17:11:10 +02:00
|
|
|
voice_media_info.senders[0].audio_level = 32767; // [0,32767]
|
|
|
|
|
voice_media_info.senders[0].total_input_energy = 2.0;
|
|
|
|
|
voice_media_info.senders[0].total_input_duration = 3.0;
|
2021-06-24 13:32:50 -07:00
|
|
|
voice_media_info.senders[0].apm_statistics.echo_return_loss = 42.0;
|
|
|
|
|
voice_media_info.senders[0].apm_statistics.echo_return_loss_enhancement =
|
|
|
|
|
52.0;
|
2019-05-22 15:49:42 +02:00
|
|
|
auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
|
|
|
|
|
voice_media_channel->SetStats(voice_media_info);
|
|
|
|
|
stats_->SetupLocalTrackAndSender(cricket::MEDIA_TYPE_AUDIO,
|
|
|
|
|
"LocalAudioTrackID", kSsrc, false,
|
|
|
|
|
kAttachmentId);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
|
|
|
|
RTCAudioSourceStats expected_audio("RTCAudioSource_42",
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected_audio.track_identifier = "LocalAudioTrackID";
|
|
|
|
|
expected_audio.kind = "audio";
|
[getStats] Implement "media-source" audio levels, fixing Chrome bug.
Implements RTCAudioSourceStats members:
- audioLevel
- totalAudioEnergy
- totalSamplesDuration
In this CL description these are collectively referred to as the audio
levels.
The audio levels are removed from sending "track" stats (in Chrome,
these are now reported as undefined instead of 0).
Background:
For sending tracks, audio levels were always reported as 0 in Chrome
(https://crbug.com/736403), while audio levels were correctly reported
for receiving tracks. This problem affected the standard getStats() but
not the legacy getStats(), blocking some people from migrating. This
was likely not a problem in native third_party/webrtc code because the
delivery of audio frames from device to send-stream uses a different
code path outside of chromium.
A recent PR (https://github.com/w3c/webrtc-stats/pull/451) moved the
send-side audio levels to the RTCAudioSourceStats, while keeping the
receive-side audio levels on the "track" stats. This allows an
implementation to report the audio levels even if samples are not sent
onto the network (such as if an ICE connection has not been established
yet), reflecting some of the current implementation.
Changes:
1. Audio levels are added to RTCAudioSourceStats. Send-side audio
"track" stats are left undefined. Receive-side audio "track" stats
are not changed in this CL and continue to work.
2. Audio level computation is moved from the AudioState and
AudioTransportImpl to the AudioSendStream. This is because a) the
AudioTransportImpl::RecordedDataIsAvailable() code path is not
exercised in chromium, and b) audio levels should, per-spec, not be
calculated on a per-call basis, for which the AudioState is defined.
3. The audio level computation is now performed in
AudioSendStream::SendAudioData(), a code path used by both native
and chromium code.
4. Comments are added to document behavior of existing code, such as
AudioLevel and AudioSendStream::SendAudioData().
Note:
In this CL, just like before this CL, audio level is only calculated
after an AudioSendStream has been created. This means that before an
O/A negotiation, audio levels are unavailable.
According to spec, if we have an audio source, we should have audio
levels. An immediate solution to this would have been to calculate the
audio level at pc/rtp_sender.cc. The problem is that the
LocalAudioSinkAdapter::OnData() code path, while exercised in chromium,
is not exercised in native code. The issue of calculating audio levels
on a per-source bases rather than on a per-send stream basis is left to
https://crbug.com/webrtc/10771, an existing "media-source" bug.
This CL can be verified manually in Chrome at:
https://codepen.io/anon/pen/vqRGyq
Bug: chromium:736403, webrtc:10771
Change-Id: I8036cd9984f3b187c3177470a8c0d6670a201a5a
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/143789
Reviewed-by: Oskar Sundbom <ossu@webrtc.org>
Reviewed-by: Stefan Holmer <stefan@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28480}
2019-07-03 17:11:10 +02:00
|
|
|
expected_audio.audio_level = 1.0; // [0,1]
|
|
|
|
|
expected_audio.total_audio_energy = 2.0;
|
|
|
|
|
expected_audio.total_samples_duration = 3.0;
|
2021-06-24 13:32:50 -07:00
|
|
|
expected_audio.echo_return_loss = 42.0;
|
|
|
|
|
expected_audio.echo_return_loss_enhancement = 52.0;
|
2019-05-22 15:49:42 +02:00
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_audio.id()));
|
|
|
|
|
EXPECT_EQ(report->Get(expected_audio.id())->cast_to<RTCAudioSourceStats>(),
|
|
|
|
|
expected_audio);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, RTCVideoSourceStatsCollectedForSenderWithTrack) {
|
|
|
|
|
const uint32_t kSsrc = 4;
|
|
|
|
|
const int kAttachmentId = 42;
|
|
|
|
|
const int kVideoSourceWidth = 12;
|
|
|
|
|
const int kVideoSourceHeight = 34;
|
|
|
|
|
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
video_media_info.aggregated_senders.push_back(cricket::VideoSenderInfo());
|
2019-05-22 15:49:42 +02:00
|
|
|
video_media_info.senders.push_back(cricket::VideoSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats[0].ssrc = kSsrc;
|
|
|
|
|
video_media_info.senders[0].framerate_input = 29;
|
Reland "Improve outbound-rtp statistics for simulcast"
This reverts commit 9a925c9ce33a6ccdd11b545b11ba68e985c2a65d.
Reason for revert: The original CL is updated in PS #2 to
fix the googRtt issue which was that when the legacy sender
stats were put in "aggregated_senders" we forgot to update
rtt_ms the same way that we do it for "senders".
Original change's description:
> Revert "Improve outbound-rtp statistics for simulcast"
>
> This reverts commit da6cda839dac7d9d18eba8d365188fa94831e0b1.
>
> Reason for revert: Breaks googRtt in legacy getStats API
>
> Original change's description:
> > Improve outbound-rtp statistics for simulcast
> >
> > Bug: webrtc:9547
> > Change-Id: Iec4eb976aa11ee743805425bedb77dcea7c2c9be
> > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/168120
> > Reviewed-by: Sebastian Jansson <srte@webrtc.org>
> > Reviewed-by: Erik Språng <sprang@webrtc.org>
> > Reviewed-by: Henrik Boström <hbos@webrtc.org>
> > Reviewed-by: Harald Alvestrand <hta@webrtc.org>
> > Commit-Queue: Eldar Rello <elrello@microsoft.com>
> > Cr-Commit-Position: refs/heads/master@{#31097}
>
> TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
>
> # Not skipping CQ checks because original CL landed > 1 day ago.
>
> Bug: webrtc:9547
> Change-Id: I06673328c2a5293a7eef03b3aaf2ded9d13df1b3
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174443
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#31165}
TBR=hbos@webrtc.org,sprang@webrtc.org,stefan@webrtc.org,srte@webrtc.org,hta@webrtc.org,elrello@microsoft.com
# Not skipping CQ checks because this is a reland.
Bug: webrtc:9547
Change-Id: I723744c496c3c65f95ab6a8940862c8b9f544338
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/174480
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#31169}
2020-05-05 15:54:46 +02:00
|
|
|
video_media_info.aggregated_senders[0].local_stats.push_back(
|
|
|
|
|
cricket::SsrcSenderInfo());
|
|
|
|
|
video_media_info.aggregated_senders[0].local_stats[0].ssrc = kSsrc;
|
|
|
|
|
video_media_info.aggregated_senders[0].framerate_input = 29;
|
2021-02-27 00:29:15 -08:00
|
|
|
video_media_info.aggregated_senders[0].frames = 10001;
|
2019-05-22 15:49:42 +02:00
|
|
|
auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
|
|
|
|
|
video_media_channel->SetStats(video_media_info);
|
|
|
|
|
|
|
|
|
|
auto video_source = FakeVideoTrackSourceForStats::Create(kVideoSourceWidth,
|
|
|
|
|
kVideoSourceHeight);
|
|
|
|
|
auto video_track = FakeVideoTrackForStats::Create(
|
|
|
|
|
"LocalVideoTrackID", MediaStreamTrackInterface::kLive, video_source);
|
|
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> sender = CreateMockSender(
|
|
|
|
|
cricket::MEDIA_TYPE_VIDEO, video_track, kSsrc, kAttachmentId, {});
|
|
|
|
|
pc_->AddSender(sender);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
|
|
|
|
RTCVideoSourceStats expected_video("RTCVideoSource_42",
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected_video.track_identifier = "LocalVideoTrackID";
|
|
|
|
|
expected_video.kind = "video";
|
|
|
|
|
expected_video.width = kVideoSourceWidth;
|
|
|
|
|
expected_video.height = kVideoSourceHeight;
|
|
|
|
|
expected_video.frames_per_second = 29;
|
2021-02-27 00:29:15 -08:00
|
|
|
expected_video.frames = 10001;
|
2019-05-22 15:49:42 +02:00
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_video.id()));
|
|
|
|
|
EXPECT_EQ(report->Get(expected_video.id())->cast_to<RTCVideoSourceStats>(),
|
|
|
|
|
expected_video);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// This test exercises the current behavior and code path, but the correct
|
|
|
|
|
// behavior is to report frame rate even if we have no SSRC.
|
|
|
|
|
// TODO(hbos): When we know the frame rate even if we have no SSRC, update the
|
|
|
|
|
// expectations of this test.
|
|
|
|
|
TEST_F(RTCStatsCollectorTest,
|
|
|
|
|
RTCVideoSourceStatsMissingFrameRateWhenSenderHasNoSsrc) {
|
|
|
|
|
// TODO(https://crbug.com/webrtc/8694): When 0 is no longer a magic value for
|
|
|
|
|
// "none", update this test.
|
|
|
|
|
const uint32_t kNoSsrc = 0;
|
|
|
|
|
const int kAttachmentId = 42;
|
|
|
|
|
const int kVideoSourceWidth = 12;
|
|
|
|
|
const int kVideoSourceHeight = 34;
|
|
|
|
|
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
|
|
|
|
video_media_info.senders.push_back(cricket::VideoSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
video_media_info.senders[0].framerate_input = 29;
|
|
|
|
|
auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
|
|
|
|
|
video_media_channel->SetStats(video_media_info);
|
|
|
|
|
|
|
|
|
|
auto video_source = FakeVideoTrackSourceForStats::Create(kVideoSourceWidth,
|
|
|
|
|
kVideoSourceHeight);
|
|
|
|
|
auto video_track = FakeVideoTrackForStats::Create(
|
|
|
|
|
"LocalVideoTrackID", MediaStreamTrackInterface::kLive, video_source);
|
|
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> sender = CreateMockSender(
|
|
|
|
|
cricket::MEDIA_TYPE_VIDEO, video_track, kNoSsrc, kAttachmentId, {});
|
|
|
|
|
pc_->AddSender(sender);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
ASSERT_TRUE(report->Get("RTCVideoSource_42"));
|
|
|
|
|
auto video_stats =
|
|
|
|
|
report->Get("RTCVideoSource_42")->cast_to<RTCVideoSourceStats>();
|
|
|
|
|
EXPECT_FALSE(video_stats.frames_per_second.is_defined());
|
2021-02-27 00:29:15 -08:00
|
|
|
EXPECT_FALSE(video_stats.frames.is_defined());
|
2019-05-22 15:49:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// The track not having a source is not expected to be true in practise, but
|
|
|
|
|
// this is true in some tests relying on fakes. This test covers that code path.
|
|
|
|
|
TEST_F(RTCStatsCollectorTest,
|
|
|
|
|
RTCVideoSourceStatsMissingResolutionWhenTrackHasNoSource) {
|
|
|
|
|
const uint32_t kSsrc = 4;
|
|
|
|
|
const int kAttachmentId = 42;
|
|
|
|
|
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
|
|
|
|
video_media_info.senders.push_back(cricket::VideoSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats[0].ssrc = kSsrc;
|
|
|
|
|
video_media_info.senders[0].framerate_input = 29;
|
|
|
|
|
auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
|
|
|
|
|
video_media_channel->SetStats(video_media_info);
|
|
|
|
|
|
|
|
|
|
auto video_track = FakeVideoTrackForStats::Create(
|
|
|
|
|
"LocalVideoTrackID", MediaStreamTrackInterface::kLive,
|
|
|
|
|
/*source=*/nullptr);
|
|
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> sender = CreateMockSender(
|
|
|
|
|
cricket::MEDIA_TYPE_VIDEO, video_track, kSsrc, kAttachmentId, {});
|
|
|
|
|
pc_->AddSender(sender);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
ASSERT_TRUE(report->Get("RTCVideoSource_42"));
|
|
|
|
|
auto video_stats =
|
|
|
|
|
report->Get("RTCVideoSource_42")->cast_to<RTCVideoSourceStats>();
|
|
|
|
|
EXPECT_FALSE(video_stats.width.is_defined());
|
|
|
|
|
EXPECT_FALSE(video_stats.height.is_defined());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest,
|
|
|
|
|
RTCAudioSourceStatsNotCollectedForSenderWithoutTrack) {
|
|
|
|
|
const uint32_t kSsrc = 4;
|
|
|
|
|
const int kAttachmentId = 42;
|
|
|
|
|
|
|
|
|
|
cricket::VoiceMediaInfo voice_media_info;
|
|
|
|
|
voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
|
|
|
|
|
voice_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
voice_media_info.senders[0].local_stats[0].ssrc = kSsrc;
|
|
|
|
|
auto* voice_media_channel = pc_->AddVoiceChannel("AudioMid", "TransportName");
|
|
|
|
|
voice_media_channel->SetStats(voice_media_info);
|
|
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> sender = CreateMockSender(
|
|
|
|
|
cricket::MEDIA_TYPE_AUDIO, /*track=*/nullptr, kSsrc, kAttachmentId, {});
|
|
|
|
|
pc_->AddSender(sender);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
EXPECT_FALSE(report->Get("RTCAudioSource_42"));
|
|
|
|
|
}
|
|
|
|
|
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
// Parameterized tests on cricket::MediaType (audio or video).
|
|
|
|
|
class RTCStatsCollectorTestWithParamKind
|
|
|
|
|
: public RTCStatsCollectorTest,
|
|
|
|
|
public ::testing::WithParamInterface<cricket::MediaType> {
|
|
|
|
|
public:
|
|
|
|
|
RTCStatsCollectorTestWithParamKind() : media_type_(GetParam()) {
|
|
|
|
|
RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO ||
|
|
|
|
|
media_type_ == cricket::MEDIA_TYPE_VIDEO);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string MediaTypeUpperCase() const {
|
|
|
|
|
switch (media_type_) {
|
|
|
|
|
case cricket::MEDIA_TYPE_AUDIO:
|
|
|
|
|
return "Audio";
|
|
|
|
|
case cricket::MEDIA_TYPE_VIDEO:
|
|
|
|
|
return "Video";
|
|
|
|
|
case cricket::MEDIA_TYPE_DATA:
|
2020-10-13 12:43:15 +02:00
|
|
|
case cricket::MEDIA_TYPE_UNSUPPORTED:
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
RTC_NOTREACHED();
|
|
|
|
|
return "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string MediaTypeLowerCase() const {
|
|
|
|
|
std::string str = MediaTypeUpperCase();
|
|
|
|
|
std::transform(str.begin(), str.end(), str.begin(), ::tolower);
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Adds a sender and channel of the appropriate kind, creating a sender info
|
|
|
|
|
// with the report block's |source_ssrc| and report block data.
|
2020-07-03 11:08:07 +03:00
|
|
|
void AddSenderInfoAndMediaChannel(
|
|
|
|
|
std::string transport_name,
|
|
|
|
|
const std::vector<ReportBlockData>& report_block_datas,
|
|
|
|
|
absl::optional<RtpCodecParameters> codec) {
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
switch (media_type_) {
|
|
|
|
|
case cricket::MEDIA_TYPE_AUDIO: {
|
|
|
|
|
cricket::VoiceMediaInfo voice_media_info;
|
2020-07-03 11:08:07 +03:00
|
|
|
for (const auto& report_block_data : report_block_datas) {
|
|
|
|
|
cricket::VoiceSenderInfo sender;
|
|
|
|
|
sender.local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
sender.local_stats[0].ssrc =
|
|
|
|
|
report_block_data.report_block().source_ssrc;
|
|
|
|
|
if (codec.has_value()) {
|
|
|
|
|
sender.codec_payload_type = codec->payload_type;
|
|
|
|
|
voice_media_info.send_codecs.insert(
|
|
|
|
|
std::make_pair(codec->payload_type, *codec));
|
|
|
|
|
}
|
|
|
|
|
sender.report_block_datas.push_back(report_block_data);
|
|
|
|
|
voice_media_info.senders.push_back(sender);
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
}
|
|
|
|
|
auto* voice_media_channel = pc_->AddVoiceChannel("mid", transport_name);
|
|
|
|
|
voice_media_channel->SetStats(voice_media_info);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case cricket::MEDIA_TYPE_VIDEO: {
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
2020-07-03 11:08:07 +03:00
|
|
|
for (const auto& report_block_data : report_block_datas) {
|
|
|
|
|
cricket::VideoSenderInfo sender;
|
|
|
|
|
sender.local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
sender.local_stats[0].ssrc =
|
|
|
|
|
report_block_data.report_block().source_ssrc;
|
|
|
|
|
if (codec.has_value()) {
|
|
|
|
|
sender.codec_payload_type = codec->payload_type;
|
|
|
|
|
video_media_info.send_codecs.insert(
|
|
|
|
|
std::make_pair(codec->payload_type, *codec));
|
|
|
|
|
}
|
|
|
|
|
sender.report_block_datas.push_back(report_block_data);
|
|
|
|
|
video_media_info.aggregated_senders.push_back(sender);
|
|
|
|
|
video_media_info.senders.push_back(sender);
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
}
|
|
|
|
|
auto* video_media_channel = pc_->AddVideoChannel("mid", transport_name);
|
|
|
|
|
video_media_channel->SetStats(video_media_info);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
case cricket::MEDIA_TYPE_DATA:
|
2020-10-13 12:43:15 +02:00
|
|
|
case cricket::MEDIA_TYPE_UNSUPPORTED:
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
RTC_NOTREACHED();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
cricket::MediaType media_type_;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Verifies RTCRemoteInboundRtpStreamStats members that don't require
|
|
|
|
|
// RTCCodecStats (codecId, jitter) and without setting up an RTCP transport.
|
|
|
|
|
TEST_P(RTCStatsCollectorTestWithParamKind,
|
|
|
|
|
RTCRemoteInboundRtpStreamStatsCollectedFromReportBlock) {
|
|
|
|
|
const int64_t kReportBlockTimestampUtcUs = 123456789;
|
2021-02-28 23:36:03 -08:00
|
|
|
const uint8_t kFractionLost = 12;
|
2021-03-01 11:22:06 -08:00
|
|
|
const int64_t kRoundTripTimeSample1Ms = 1234;
|
|
|
|
|
const double kRoundTripTimeSample1Seconds = 1.234;
|
|
|
|
|
const int64_t kRoundTripTimeSample2Ms = 13000;
|
|
|
|
|
const double kRoundTripTimeSample2Seconds = 13;
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
|
|
|
|
|
// The report block's timestamp cannot be from the future, set the fake clock
|
|
|
|
|
// to match.
|
2020-02-10 11:16:00 +01:00
|
|
|
fake_clock_.SetTime(Timestamp::Micros(kReportBlockTimestampUtcUs));
|
2020-07-03 11:08:07 +03:00
|
|
|
auto ssrcs = {12, 13};
|
|
|
|
|
std::vector<ReportBlockData> report_block_datas;
|
|
|
|
|
for (auto ssrc : ssrcs) {
|
|
|
|
|
RTCPReportBlock report_block;
|
|
|
|
|
// The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the
|
|
|
|
|
// |source_ssrc|, "SSRC of the RTP packet sender".
|
|
|
|
|
report_block.source_ssrc = ssrc;
|
|
|
|
|
report_block.packets_lost = 7;
|
2021-02-28 23:36:03 -08:00
|
|
|
report_block.fraction_lost = kFractionLost;
|
2020-07-03 11:08:07 +03:00
|
|
|
ReportBlockData report_block_data;
|
|
|
|
|
report_block_data.SetReportBlock(report_block, kReportBlockTimestampUtcUs);
|
2021-03-01 11:22:06 -08:00
|
|
|
report_block_data.AddRoundTripTimeSample(kRoundTripTimeSample1Ms);
|
2020-07-03 11:08:07 +03:00
|
|
|
// Only the last sample should be exposed as the
|
|
|
|
|
// |RTCRemoteInboundRtpStreamStats::round_trip_time|.
|
2021-03-01 11:22:06 -08:00
|
|
|
report_block_data.AddRoundTripTimeSample(kRoundTripTimeSample2Ms);
|
2020-07-03 11:08:07 +03:00
|
|
|
report_block_datas.push_back(report_block_data);
|
|
|
|
|
}
|
|
|
|
|
AddSenderInfoAndMediaChannel("TransportName", report_block_datas,
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
absl::nullopt);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
2020-07-03 11:08:07 +03:00
|
|
|
for (auto ssrc : ssrcs) {
|
|
|
|
|
std::string stream_id = "Stream_" + std::to_string(ssrc);
|
|
|
|
|
RTCRemoteInboundRtpStreamStats expected_remote_inbound_rtp(
|
|
|
|
|
"RTCRemoteInboundRtp" + MediaTypeUpperCase() + stream_id,
|
|
|
|
|
kReportBlockTimestampUtcUs);
|
|
|
|
|
expected_remote_inbound_rtp.ssrc = ssrc;
|
2021-02-28 23:36:03 -08:00
|
|
|
expected_remote_inbound_rtp.fraction_lost =
|
|
|
|
|
static_cast<double>(kFractionLost) / (1 << 8);
|
2020-07-03 11:08:07 +03:00
|
|
|
expected_remote_inbound_rtp.kind = MediaTypeLowerCase();
|
|
|
|
|
expected_remote_inbound_rtp.transport_id =
|
|
|
|
|
"RTCTransport_TransportName_1"; // 1 for RTP (we have no RTCP
|
|
|
|
|
// transport)
|
|
|
|
|
expected_remote_inbound_rtp.packets_lost = 7;
|
|
|
|
|
expected_remote_inbound_rtp.local_id =
|
|
|
|
|
"RTCOutboundRTP" + MediaTypeUpperCase() + stream_id;
|
2021-03-01 11:22:06 -08:00
|
|
|
expected_remote_inbound_rtp.round_trip_time = kRoundTripTimeSample2Seconds;
|
|
|
|
|
expected_remote_inbound_rtp.total_round_trip_time =
|
|
|
|
|
kRoundTripTimeSample1Seconds + kRoundTripTimeSample2Seconds;
|
|
|
|
|
expected_remote_inbound_rtp.round_trip_time_measurements = 2;
|
2020-07-03 11:08:07 +03:00
|
|
|
// This test does not set up RTCCodecStats, so |codec_id| and |jitter| are
|
|
|
|
|
// expected to be missing. These are tested separately.
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_remote_inbound_rtp.id()));
|
|
|
|
|
EXPECT_EQ(report->Get(expected_remote_inbound_rtp.id())
|
|
|
|
|
->cast_to<RTCRemoteInboundRtpStreamStats>(),
|
|
|
|
|
expected_remote_inbound_rtp);
|
|
|
|
|
EXPECT_TRUE(report->Get(*expected_remote_inbound_rtp.transport_id));
|
|
|
|
|
ASSERT_TRUE(report->Get(*expected_remote_inbound_rtp.local_id));
|
|
|
|
|
// Lookup works in both directions.
|
|
|
|
|
EXPECT_EQ(*report->Get(*expected_remote_inbound_rtp.local_id)
|
|
|
|
|
->cast_to<RTCOutboundRTPStreamStats>()
|
|
|
|
|
.remote_id,
|
|
|
|
|
expected_remote_inbound_rtp.id());
|
|
|
|
|
}
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_P(RTCStatsCollectorTestWithParamKind,
|
|
|
|
|
RTCRemoteInboundRtpStreamStatsWithTimestampFromReportBlock) {
|
|
|
|
|
const int64_t kReportBlockTimestampUtcUs = 123456789;
|
2020-02-10 11:16:00 +01:00
|
|
|
fake_clock_.SetTime(Timestamp::Micros(kReportBlockTimestampUtcUs));
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
|
|
|
|
|
RTCPReportBlock report_block;
|
2019-06-24 16:44:51 +02:00
|
|
|
// The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the
|
|
|
|
|
// |source_ssrc|, "SSRC of the RTP packet sender".
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
report_block.source_ssrc = 12;
|
|
|
|
|
ReportBlockData report_block_data;
|
|
|
|
|
report_block_data.SetReportBlock(report_block, kReportBlockTimestampUtcUs);
|
|
|
|
|
|
2020-07-03 11:08:07 +03:00
|
|
|
AddSenderInfoAndMediaChannel("TransportName", {report_block_data},
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
absl::nullopt);
|
|
|
|
|
|
|
|
|
|
// Advance time, it should be OK to have fresher reports than report blocks.
|
2020-02-10 11:16:00 +01:00
|
|
|
fake_clock_.AdvanceTime(TimeDelta::Micros(1234));
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
|
|
|
|
std::string remote_inbound_rtp_id =
|
2019-06-24 16:44:51 +02:00
|
|
|
"RTCRemoteInboundRtp" + MediaTypeUpperCase() + "Stream_12";
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
ASSERT_TRUE(report->Get(remote_inbound_rtp_id));
|
|
|
|
|
auto& remote_inbound_rtp = report->Get(remote_inbound_rtp_id)
|
|
|
|
|
->cast_to<RTCRemoteInboundRtpStreamStats>();
|
|
|
|
|
|
|
|
|
|
// Even though the report time is different, the remote-inbound-rtp timestamp
|
|
|
|
|
// is of the time that the report block was received.
|
|
|
|
|
EXPECT_EQ(kReportBlockTimestampUtcUs + 1234, report->timestamp_us());
|
|
|
|
|
EXPECT_EQ(kReportBlockTimestampUtcUs, remote_inbound_rtp.timestamp_us());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_P(RTCStatsCollectorTestWithParamKind,
|
|
|
|
|
RTCRemoteInboundRtpStreamStatsWithCodecBasedMembers) {
|
|
|
|
|
const int64_t kReportBlockTimestampUtcUs = 123456789;
|
2020-02-10 11:16:00 +01:00
|
|
|
fake_clock_.SetTime(Timestamp::Micros(kReportBlockTimestampUtcUs));
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
|
|
|
|
|
RTCPReportBlock report_block;
|
2019-06-24 16:44:51 +02:00
|
|
|
// The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the
|
|
|
|
|
// |source_ssrc|, "SSRC of the RTP packet sender".
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
report_block.source_ssrc = 12;
|
|
|
|
|
report_block.jitter = 5000;
|
|
|
|
|
ReportBlockData report_block_data;
|
|
|
|
|
report_block_data.SetReportBlock(report_block, kReportBlockTimestampUtcUs);
|
|
|
|
|
|
|
|
|
|
RtpCodecParameters codec;
|
|
|
|
|
codec.payload_type = 3;
|
|
|
|
|
codec.kind = media_type_;
|
|
|
|
|
codec.clock_rate = 1000;
|
|
|
|
|
|
2020-07-03 11:08:07 +03:00
|
|
|
AddSenderInfoAndMediaChannel("TransportName", {report_block_data}, codec);
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
|
|
|
|
std::string remote_inbound_rtp_id =
|
2019-06-24 16:44:51 +02:00
|
|
|
"RTCRemoteInboundRtp" + MediaTypeUpperCase() + "Stream_12";
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
ASSERT_TRUE(report->Get(remote_inbound_rtp_id));
|
|
|
|
|
auto& remote_inbound_rtp = report->Get(remote_inbound_rtp_id)
|
|
|
|
|
->cast_to<RTCRemoteInboundRtpStreamStats>();
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(remote_inbound_rtp.codec_id.is_defined());
|
|
|
|
|
EXPECT_TRUE(report->Get(*remote_inbound_rtp.codec_id));
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(remote_inbound_rtp.jitter.is_defined());
|
|
|
|
|
// The jitter (in seconds) is the report block's jitter divided by the codec's
|
|
|
|
|
// clock rate.
|
|
|
|
|
EXPECT_EQ(5.0, *remote_inbound_rtp.jitter);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_P(RTCStatsCollectorTestWithParamKind,
|
|
|
|
|
RTCRemoteInboundRtpStreamStatsWithRtcpTransport) {
|
|
|
|
|
const int64_t kReportBlockTimestampUtcUs = 123456789;
|
2020-02-10 11:16:00 +01:00
|
|
|
fake_clock_.SetTime(Timestamp::Micros(kReportBlockTimestampUtcUs));
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
|
|
|
|
|
RTCPReportBlock report_block;
|
2019-06-24 16:44:51 +02:00
|
|
|
// The remote-inbound-rtp SSRC and the outbound-rtp SSRC is the same as the
|
|
|
|
|
// |source_ssrc|, "SSRC of the RTP packet sender".
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
report_block.source_ssrc = 12;
|
|
|
|
|
ReportBlockData report_block_data;
|
|
|
|
|
report_block_data.SetReportBlock(report_block, kReportBlockTimestampUtcUs);
|
|
|
|
|
|
|
|
|
|
cricket::TransportChannelStats rtp_transport_channel_stats;
|
|
|
|
|
rtp_transport_channel_stats.component = cricket::ICE_CANDIDATE_COMPONENT_RTP;
|
2021-05-21 20:46:09 +02:00
|
|
|
rtp_transport_channel_stats.dtls_state = DtlsTransportState::kNew;
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
cricket::TransportChannelStats rtcp_transport_channel_stats;
|
|
|
|
|
rtcp_transport_channel_stats.component =
|
|
|
|
|
cricket::ICE_CANDIDATE_COMPONENT_RTCP;
|
2021-05-21 20:46:09 +02:00
|
|
|
rtcp_transport_channel_stats.dtls_state = DtlsTransportState::kNew;
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
pc_->SetTransportStats("TransportName", {rtp_transport_channel_stats,
|
|
|
|
|
rtcp_transport_channel_stats});
|
2020-07-03 11:08:07 +03:00
|
|
|
AddSenderInfoAndMediaChannel("TransportName", {report_block_data},
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
absl::nullopt);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
|
|
|
|
std::string remote_inbound_rtp_id =
|
2019-06-24 16:44:51 +02:00
|
|
|
"RTCRemoteInboundRtp" + MediaTypeUpperCase() + "Stream_12";
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
ASSERT_TRUE(report->Get(remote_inbound_rtp_id));
|
|
|
|
|
auto& remote_inbound_rtp = report->Get(remote_inbound_rtp_id)
|
|
|
|
|
->cast_to<RTCRemoteInboundRtpStreamStats>();
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(remote_inbound_rtp.transport_id.is_defined());
|
|
|
|
|
EXPECT_EQ("RTCTransport_TransportName_2", // 2 for RTCP
|
|
|
|
|
*remote_inbound_rtp.transport_id);
|
|
|
|
|
EXPECT_TRUE(report->Get(*remote_inbound_rtp.transport_id));
|
|
|
|
|
}
|
|
|
|
|
|
2019-09-23 08:34:50 +02:00
|
|
|
INSTANTIATE_TEST_SUITE_P(All,
|
Implement RTCRemoteInboundRtpStreamStats for both audio and video.
This implements the essentials of RTCRemoteInboundRtpStreamStats. This
includes:
- ssrc
- transportId
- codecId
- packetsLost
- jitter
- localId
- roundTripTime
https://w3c.github.io/webrtc-stats/#remoteinboundrtpstats-dict*
The following members are not implemented because they require more
work...
- From RTCReceivedRtpStreamStats: packetsReceived, packetsDiscarded,
packetsRepaired, burstPacketsLost, burstPacketsDiscarded,
burstLossCount, burstDiscardCount, burstLossRate, burstDiscardRate,
gapLossRate and gapDiscardRate.
- From RTCRemoteInboundRtpStreamStats: fractionLost.
Bug: webrtc:10455, webrtc:10456
Change-Id: If2ab0da7105d8c93bba58e14aa93bd22ffe57f1d
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/138067
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#28073}
2019-05-27 13:40:25 +02:00
|
|
|
RTCStatsCollectorTestWithParamKind,
|
|
|
|
|
::testing::Values(cricket::MEDIA_TYPE_AUDIO, // "/0"
|
|
|
|
|
cricket::MEDIA_TYPE_VIDEO)); // "/1"
|
|
|
|
|
|
2021-03-23 17:23:04 +01:00
|
|
|
// Checks that no remote outbound stats are collected if not available in
|
|
|
|
|
// `VoiceMediaInfo`.
|
|
|
|
|
TEST_F(RTCStatsCollectorTest,
|
|
|
|
|
RTCRemoteOutboundRtpAudioStreamStatsNotCollected) {
|
|
|
|
|
ExampleStatsGraph graph =
|
|
|
|
|
SetupExampleStatsVoiceGraph(/*add_remote_outbound_stats=*/false);
|
|
|
|
|
EXPECT_FALSE(graph.full_report->Get(graph.remote_outbound_rtp_id));
|
|
|
|
|
// Also check that no other remote outbound report is created (in case the
|
|
|
|
|
// expected ID is incorrect).
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
ASSERT_NE(report->begin(), report->end())
|
|
|
|
|
<< "No reports have been generated.";
|
|
|
|
|
for (const auto& stats : *report) {
|
|
|
|
|
SCOPED_TRACE(stats.id());
|
|
|
|
|
EXPECT_NE(stats.type(), RTCRemoteOutboundRtpStreamStats::kType);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Checks that the remote outbound stats are collected when available in
|
|
|
|
|
// `VoiceMediaInfo`.
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, RTCRemoteOutboundRtpAudioStreamStatsCollected) {
|
|
|
|
|
ExampleStatsGraph graph =
|
|
|
|
|
SetupExampleStatsVoiceGraph(/*add_remote_outbound_stats=*/true);
|
|
|
|
|
ASSERT_TRUE(graph.full_report->Get(graph.remote_outbound_rtp_id));
|
|
|
|
|
const auto& remote_outbound_rtp =
|
|
|
|
|
graph.full_report->Get(graph.remote_outbound_rtp_id)
|
|
|
|
|
->cast_to<RTCRemoteOutboundRtpStreamStats>();
|
|
|
|
|
EXPECT_EQ(remote_outbound_rtp.timestamp_us(),
|
|
|
|
|
kRemoteOutboundStatsTimestampMs * rtc::kNumMicrosecsPerMillisec);
|
|
|
|
|
EXPECT_FLOAT_EQ(*remote_outbound_rtp.remote_timestamp,
|
|
|
|
|
static_cast<double>(kRemoteOutboundStatsRemoteTimestampMs));
|
|
|
|
|
EXPECT_EQ(*remote_outbound_rtp.packets_sent, kRemoteOutboundStatsPacketsSent);
|
|
|
|
|
EXPECT_EQ(*remote_outbound_rtp.bytes_sent, kRemoteOutboundStatsBytesSent);
|
|
|
|
|
EXPECT_EQ(*remote_outbound_rtp.reports_sent,
|
|
|
|
|
kRemoteOutboundStatsReportsCount);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-22 15:49:42 +02:00
|
|
|
TEST_F(RTCStatsCollectorTest,
|
|
|
|
|
RTCVideoSourceStatsNotCollectedForSenderWithoutTrack) {
|
|
|
|
|
const uint32_t kSsrc = 4;
|
|
|
|
|
const int kAttachmentId = 42;
|
|
|
|
|
|
|
|
|
|
cricket::VideoMediaInfo video_media_info;
|
|
|
|
|
video_media_info.senders.push_back(cricket::VideoSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
video_media_info.senders[0].local_stats[0].ssrc = kSsrc;
|
|
|
|
|
video_media_info.senders[0].framerate_input = 29;
|
|
|
|
|
auto* video_media_channel = pc_->AddVideoChannel("VideoMid", "TransportName");
|
|
|
|
|
video_media_channel->SetStats(video_media_info);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> sender = CreateMockSender(
|
|
|
|
|
cricket::MEDIA_TYPE_VIDEO, /*track=*/nullptr, kSsrc, kAttachmentId, {});
|
|
|
|
|
pc_->AddSender(sender);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
EXPECT_FALSE(report->Get("RTCVideoSource_42"));
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-24 13:32:50 -07:00
|
|
|
// Test collecting echo return loss stats from the audio processor attached to
|
|
|
|
|
// the track, rather than the voice sender info.
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, CollectEchoReturnLossFromTrackAudioProcessor) {
|
|
|
|
|
rtc::scoped_refptr<MediaStream> local_stream =
|
|
|
|
|
MediaStream::Create("LocalStreamId");
|
|
|
|
|
pc_->mutable_local_streams()->AddStream(local_stream);
|
|
|
|
|
|
|
|
|
|
// Local audio track
|
|
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> local_audio_track =
|
|
|
|
|
CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "LocalAudioTrackID",
|
|
|
|
|
MediaStreamTrackInterface::kEnded,
|
|
|
|
|
/*create_fake_audio_processor=*/true);
|
|
|
|
|
local_stream->AddTrack(
|
|
|
|
|
static_cast<AudioTrackInterface*>(local_audio_track.get()));
|
|
|
|
|
|
|
|
|
|
cricket::VoiceSenderInfo voice_sender_info_ssrc1;
|
|
|
|
|
voice_sender_info_ssrc1.local_stats.push_back(cricket::SsrcSenderInfo());
|
|
|
|
|
voice_sender_info_ssrc1.local_stats[0].ssrc = 1;
|
|
|
|
|
|
|
|
|
|
stats_->CreateMockRtpSendersReceiversAndChannels(
|
|
|
|
|
{std::make_pair(local_audio_track.get(), voice_sender_info_ssrc1)}, {},
|
|
|
|
|
{}, {}, {local_stream->id()}, {});
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
|
|
|
|
RTCMediaStreamTrackStats expected_local_audio_track_ssrc1(
|
|
|
|
|
IdForType<RTCMediaStreamTrackStats>(report), report->timestamp_us(),
|
|
|
|
|
RTCMediaStreamTrackKind::kAudio);
|
|
|
|
|
expected_local_audio_track_ssrc1.track_identifier = local_audio_track->id();
|
|
|
|
|
expected_local_audio_track_ssrc1.media_source_id =
|
|
|
|
|
"RTCAudioSource_11"; // Attachment ID = SSRC + 10
|
|
|
|
|
expected_local_audio_track_ssrc1.remote_source = false;
|
|
|
|
|
expected_local_audio_track_ssrc1.ended = true;
|
|
|
|
|
expected_local_audio_track_ssrc1.detached = false;
|
|
|
|
|
expected_local_audio_track_ssrc1.echo_return_loss = 2.0;
|
|
|
|
|
expected_local_audio_track_ssrc1.echo_return_loss_enhancement = 3.0;
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_local_audio_track_ssrc1.id()))
|
|
|
|
|
<< "Did not find " << expected_local_audio_track_ssrc1.id() << " in "
|
|
|
|
|
<< report->ToJson();
|
|
|
|
|
EXPECT_EQ(expected_local_audio_track_ssrc1,
|
|
|
|
|
report->Get(expected_local_audio_track_ssrc1.id())
|
|
|
|
|
->cast_to<RTCMediaStreamTrackStats>());
|
|
|
|
|
|
|
|
|
|
RTCAudioSourceStats expected_audio("RTCAudioSource_11",
|
|
|
|
|
report->timestamp_us());
|
|
|
|
|
expected_audio.track_identifier = "LocalAudioTrackID";
|
|
|
|
|
expected_audio.kind = "audio";
|
|
|
|
|
expected_audio.audio_level = 0;
|
|
|
|
|
expected_audio.total_audio_energy = 0;
|
|
|
|
|
expected_audio.total_samples_duration = 0;
|
|
|
|
|
expected_audio.echo_return_loss = 2.0;
|
|
|
|
|
expected_audio.echo_return_loss_enhancement = 3.0;
|
|
|
|
|
|
|
|
|
|
ASSERT_TRUE(report->Get(expected_audio.id()));
|
|
|
|
|
EXPECT_EQ(report->Get(expected_audio.id())->cast_to<RTCAudioSourceStats>(),
|
|
|
|
|
expected_audio);
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-19 13:52:56 +01:00
|
|
|
TEST_F(RTCStatsCollectorTest, GetStatsWithSenderSelector) {
|
|
|
|
|
ExampleStatsGraph graph = SetupExampleStatsGraphForSelectorTests();
|
|
|
|
|
// Expected stats graph when filtered by sender:
|
|
|
|
|
//
|
2019-05-22 15:49:42 +02:00
|
|
|
// +--- track (sender)
|
|
|
|
|
// | ^
|
|
|
|
|
// | |
|
|
|
|
|
// | +--------- outbound-rtp
|
|
|
|
|
// | | | |
|
|
|
|
|
// | | v v
|
|
|
|
|
// | | codec (send) transport
|
|
|
|
|
// v v
|
|
|
|
|
// media-source
|
2018-03-19 13:52:56 +01:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> sender_report =
|
|
|
|
|
stats_->GetStatsReportWithSenderSelector(graph.sender);
|
|
|
|
|
EXPECT_TRUE(sender_report);
|
|
|
|
|
EXPECT_EQ(sender_report->timestamp_us(), graph.full_report->timestamp_us());
|
2019-05-22 15:49:42 +02:00
|
|
|
EXPECT_EQ(sender_report->size(), 5u);
|
2018-03-19 13:52:56 +01:00
|
|
|
EXPECT_TRUE(sender_report->Get(graph.send_codec_id));
|
|
|
|
|
EXPECT_FALSE(sender_report->Get(graph.recv_codec_id));
|
|
|
|
|
EXPECT_TRUE(sender_report->Get(graph.outbound_rtp_id));
|
|
|
|
|
EXPECT_FALSE(sender_report->Get(graph.inbound_rtp_id));
|
|
|
|
|
EXPECT_TRUE(sender_report->Get(graph.transport_id));
|
|
|
|
|
EXPECT_TRUE(sender_report->Get(graph.sender_track_id));
|
|
|
|
|
EXPECT_FALSE(sender_report->Get(graph.receiver_track_id));
|
|
|
|
|
EXPECT_FALSE(sender_report->Get(graph.remote_stream_id));
|
|
|
|
|
EXPECT_FALSE(sender_report->Get(graph.peer_connection_id));
|
2019-05-22 15:49:42 +02:00
|
|
|
EXPECT_TRUE(sender_report->Get(graph.media_source_id));
|
2018-03-19 13:52:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, GetStatsWithReceiverSelector) {
|
|
|
|
|
ExampleStatsGraph graph = SetupExampleStatsGraphForSelectorTests();
|
|
|
|
|
// Expected stats graph when filtered by receiver:
|
|
|
|
|
//
|
2019-05-22 15:49:42 +02:00
|
|
|
// track (receiver)
|
|
|
|
|
// ^
|
|
|
|
|
// |
|
|
|
|
|
// inbound-rtp ---------------+
|
|
|
|
|
// | |
|
|
|
|
|
// v v
|
|
|
|
|
// transport codec (recv)
|
2018-03-19 13:52:56 +01:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> receiver_report =
|
|
|
|
|
stats_->GetStatsReportWithReceiverSelector(graph.receiver);
|
|
|
|
|
EXPECT_TRUE(receiver_report);
|
|
|
|
|
EXPECT_EQ(receiver_report->size(), 4u);
|
|
|
|
|
EXPECT_EQ(receiver_report->timestamp_us(), graph.full_report->timestamp_us());
|
|
|
|
|
EXPECT_FALSE(receiver_report->Get(graph.send_codec_id));
|
|
|
|
|
EXPECT_TRUE(receiver_report->Get(graph.recv_codec_id));
|
|
|
|
|
EXPECT_FALSE(receiver_report->Get(graph.outbound_rtp_id));
|
|
|
|
|
EXPECT_TRUE(receiver_report->Get(graph.inbound_rtp_id));
|
|
|
|
|
EXPECT_TRUE(receiver_report->Get(graph.transport_id));
|
|
|
|
|
EXPECT_FALSE(receiver_report->Get(graph.sender_track_id));
|
|
|
|
|
EXPECT_TRUE(receiver_report->Get(graph.receiver_track_id));
|
|
|
|
|
EXPECT_FALSE(receiver_report->Get(graph.remote_stream_id));
|
|
|
|
|
EXPECT_FALSE(receiver_report->Get(graph.peer_connection_id));
|
2019-05-22 15:49:42 +02:00
|
|
|
EXPECT_FALSE(receiver_report->Get(graph.media_source_id));
|
2018-03-19 13:52:56 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, GetStatsWithNullSenderSelector) {
|
|
|
|
|
ExampleStatsGraph graph = SetupExampleStatsGraphForSelectorTests();
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> empty_report =
|
|
|
|
|
stats_->GetStatsReportWithSenderSelector(nullptr);
|
|
|
|
|
EXPECT_TRUE(empty_report);
|
|
|
|
|
EXPECT_EQ(empty_report->timestamp_us(), graph.full_report->timestamp_us());
|
|
|
|
|
EXPECT_EQ(empty_report->size(), 0u);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, GetStatsWithNullReceiverSelector) {
|
|
|
|
|
ExampleStatsGraph graph = SetupExampleStatsGraphForSelectorTests();
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> empty_report =
|
|
|
|
|
stats_->GetStatsReportWithReceiverSelector(nullptr);
|
|
|
|
|
EXPECT_TRUE(empty_report);
|
|
|
|
|
EXPECT_EQ(empty_report->timestamp_us(), graph.full_report->timestamp_us());
|
|
|
|
|
EXPECT_EQ(empty_report->size(), 0u);
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-02 14:08:34 +01:00
|
|
|
// When the PC has not had SetLocalDescription done, tracks all have
|
|
|
|
|
// SSRC 0, meaning "unconnected".
|
2018-01-23 15:28:16 +01:00
|
|
|
// In this state, we report on track stats, but not RTP stats.
|
|
|
|
|
TEST_F(RTCStatsCollectorTest, StatsReportedOnZeroSsrc) {
|
2018-01-02 14:08:34 +01:00
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> track =
|
|
|
|
|
CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "audioTrack",
|
|
|
|
|
MediaStreamTrackInterface::kLive);
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> sender =
|
2019-05-22 15:49:42 +02:00
|
|
|
CreateMockSender(cricket::MEDIA_TYPE_AUDIO, track, 0, 49, {});
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddSender(sender);
|
|
|
|
|
|
|
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
2018-01-02 14:08:34 +01:00
|
|
|
std::vector<const RTCMediaStreamTrackStats*> track_stats =
|
|
|
|
|
report->GetStatsOfType<RTCMediaStreamTrackStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
EXPECT_EQ(1U, track_stats.size());
|
2018-02-02 16:00:20 -08:00
|
|
|
|
2018-01-23 15:28:16 +01:00
|
|
|
std::vector<const RTCRTPStreamStats*> rtp_stream_stats =
|
|
|
|
|
report->GetStatsOfType<RTCRTPStreamStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
EXPECT_EQ(0U, rtp_stream_stats.size());
|
2018-01-02 14:08:34 +01:00
|
|
|
}
|
|
|
|
|
|
2018-01-30 14:43:29 +01:00
|
|
|
TEST_F(RTCStatsCollectorTest, DoNotCrashOnSsrcChange) {
|
|
|
|
|
rtc::scoped_refptr<MediaStreamTrackInterface> track =
|
|
|
|
|
CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "audioTrack",
|
|
|
|
|
MediaStreamTrackInterface::kLive);
|
2018-02-15 15:19:50 -08:00
|
|
|
rtc::scoped_refptr<MockRtpSenderInternal> sender =
|
2019-05-22 15:49:42 +02:00
|
|
|
CreateMockSender(cricket::MEDIA_TYPE_AUDIO, track, 4711, 49, {});
|
2018-02-02 16:00:20 -08:00
|
|
|
pc_->AddSender(sender);
|
|
|
|
|
|
2018-01-30 14:43:29 +01:00
|
|
|
// We do not generate any matching voice_sender_info stats.
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> report = stats_->GetStatsReport();
|
|
|
|
|
|
2018-01-30 14:43:29 +01:00
|
|
|
std::vector<const RTCMediaStreamTrackStats*> track_stats =
|
|
|
|
|
report->GetStatsOfType<RTCMediaStreamTrackStats>();
|
2018-07-03 12:53:23 +02:00
|
|
|
EXPECT_EQ(1U, track_stats.size());
|
2018-01-30 14:43:29 +01:00
|
|
|
}
|
|
|
|
|
|
2018-03-06 09:42:25 -08:00
|
|
|
// Used for test below, to test calling GetStatsReport during a callback.
|
2018-03-08 09:53:47 -08:00
|
|
|
class RecursiveCallback : public RTCStatsCollectorCallback {
|
2018-03-06 09:42:25 -08:00
|
|
|
public:
|
2018-03-08 09:53:47 -08:00
|
|
|
explicit RecursiveCallback(RTCStatsCollectorWrapper* stats) : stats_(stats) {}
|
2018-03-06 09:42:25 -08:00
|
|
|
|
|
|
|
|
void OnStatsDelivered(
|
|
|
|
|
const rtc::scoped_refptr<const RTCStatsReport>& report) override {
|
|
|
|
|
stats_->GetStatsReport();
|
|
|
|
|
called_ = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool called() const { return called_; }
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
RTCStatsCollectorWrapper* stats_;
|
|
|
|
|
bool called_ = false;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Test that nothing bad happens if a callback causes GetStatsReport to be
|
|
|
|
|
// called again recursively. Regression test for crbug.com/webrtc/8973.
|
2018-03-08 09:53:47 -08:00
|
|
|
TEST_F(RTCStatsCollectorTest, DoNotCrashWhenGetStatsCalledDuringCallback) {
|
|
|
|
|
rtc::scoped_refptr<RecursiveCallback> callback1(
|
|
|
|
|
new rtc::RefCountedObject<RecursiveCallback>(stats_.get()));
|
|
|
|
|
rtc::scoped_refptr<RecursiveCallback> callback2(
|
|
|
|
|
new rtc::RefCountedObject<RecursiveCallback>(stats_.get()));
|
2018-03-06 09:42:25 -08:00
|
|
|
stats_->stats_collector()->GetStatsReport(callback1);
|
|
|
|
|
stats_->stats_collector()->GetStatsReport(callback2);
|
|
|
|
|
EXPECT_TRUE_WAIT(callback1->called(), kGetStatsReportTimeoutMs);
|
|
|
|
|
EXPECT_TRUE_WAIT(callback2->called(), kGetStatsReportTimeoutMs);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
class RTCTestStats : public RTCStats {
|
2016-09-05 01:36:50 -07:00
|
|
|
public:
|
2018-02-02 16:00:20 -08:00
|
|
|
WEBRTC_RTCSTATS_DECL();
|
|
|
|
|
|
|
|
|
|
RTCTestStats(const std::string& id, int64_t timestamp_us)
|
|
|
|
|
: RTCStats(id, timestamp_us), dummy_stat("dummyStat") {}
|
|
|
|
|
|
|
|
|
|
RTCStatsMember<int32_t> dummy_stat;
|
|
|
|
|
};
|
|
|
|
|
|
2019-02-25 09:12:02 +01:00
|
|
|
WEBRTC_RTCSTATS_IMPL(RTCTestStats, RTCStats, "test-stats", &dummy_stat)
|
2018-02-02 16:00:20 -08:00
|
|
|
|
|
|
|
|
// Overrides the stats collection to verify thread usage and that the resulting
|
|
|
|
|
// partial reports are merged.
|
|
|
|
|
class FakeRTCStatsCollector : public RTCStatsCollector,
|
|
|
|
|
public RTCStatsCollectorCallback {
|
|
|
|
|
public:
|
|
|
|
|
static rtc::scoped_refptr<FakeRTCStatsCollector> Create(
|
|
|
|
|
PeerConnectionInternal* pc,
|
|
|
|
|
int64_t cache_lifetime_us) {
|
2021-04-22 18:16:35 +02:00
|
|
|
return new rtc::RefCountedObject<FakeRTCStatsCollector>(pc,
|
|
|
|
|
cache_lifetime_us);
|
2018-02-02 16:00:20 -08:00
|
|
|
}
|
|
|
|
|
|
2021-04-22 18:16:35 +02:00
|
|
|
// Since FakeRTCStatsCollector inherits twice from RefCountInterface, once via
|
|
|
|
|
// RTCStatsCollector and once via RTCStatsCollectorCallback, scoped_refptr
|
|
|
|
|
// will get confused about which AddRef()/Release() methods to call.
|
|
|
|
|
// So to remove all doubt, we declare them here again in the class that we
|
|
|
|
|
// give to scoped_refptr.
|
|
|
|
|
// Satisfying the implementation of these methods and associating them with a
|
|
|
|
|
// reference counter, will be done by RefCountedObject.
|
|
|
|
|
virtual void AddRef() const = 0;
|
|
|
|
|
virtual rtc::RefCountReleaseStatus Release() const = 0;
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
// RTCStatsCollectorCallback implementation.
|
|
|
|
|
void OnStatsDelivered(
|
|
|
|
|
const rtc::scoped_refptr<const RTCStatsReport>& report) override {
|
|
|
|
|
EXPECT_TRUE(signaling_thread_->IsCurrent());
|
2020-07-07 19:08:53 +02:00
|
|
|
MutexLock lock(&lock_);
|
2018-02-02 16:00:20 -08:00
|
|
|
delivered_report_ = report;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VerifyThreadUsageAndResultsMerging() {
|
|
|
|
|
GetStatsReport(rtc::scoped_refptr<RTCStatsCollectorCallback>(this));
|
|
|
|
|
EXPECT_TRUE_WAIT(HasVerifiedResults(), kGetStatsReportTimeoutMs);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool HasVerifiedResults() {
|
|
|
|
|
EXPECT_TRUE(signaling_thread_->IsCurrent());
|
2020-07-07 19:08:53 +02:00
|
|
|
MutexLock lock(&lock_);
|
2018-02-02 16:00:20 -08:00
|
|
|
if (!delivered_report_)
|
|
|
|
|
return false;
|
|
|
|
|
EXPECT_EQ(produced_on_signaling_thread_, 1);
|
|
|
|
|
EXPECT_EQ(produced_on_network_thread_, 1);
|
|
|
|
|
|
|
|
|
|
EXPECT_TRUE(delivered_report_->Get("SignalingThreadStats"));
|
|
|
|
|
EXPECT_TRUE(delivered_report_->Get("NetworkThreadStats"));
|
|
|
|
|
|
|
|
|
|
produced_on_signaling_thread_ = 0;
|
|
|
|
|
produced_on_network_thread_ = 0;
|
|
|
|
|
delivered_report_ = nullptr;
|
|
|
|
|
return true;
|
2016-09-05 01:36:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
2018-02-02 16:00:20 -08:00
|
|
|
FakeRTCStatsCollector(PeerConnectionInternal* pc, int64_t cache_lifetime)
|
|
|
|
|
: RTCStatsCollector(pc, cache_lifetime),
|
|
|
|
|
signaling_thread_(pc->signaling_thread()),
|
|
|
|
|
worker_thread_(pc->worker_thread()),
|
|
|
|
|
network_thread_(pc->network_thread()) {}
|
|
|
|
|
|
Reland "Fix getStats() freeze bug affecting Chromium but not WebRTC standalone."
This is a reland of 05d43c6f7fe497fed0f2c8714e2042dd07a86df2
The original CL got reverted because Chrome did not support IsQuitting() which
triggered a NOTREACHED() inside of a DCHECK. With
https://chromium-review.googlesource.com/c/chromium/src/+/1491620
it is safe to reland this CL.
The only changes between this and the original patch set is that this is now
rebased on top of https://webrtc-review.googlesource.com/c/src/+/124701, i.e.
rtc::PostMessageWithFunctor() has been replaced by rtc::Thread::PostTask().
Original change's description:
> Fix getStats() freeze bug affecting Chromium but not WebRTC standalone.
>
> PeerConnection::Close() is, per-spec, a blocking operation.
> Unfortunately, PeerConnection is implemented to own resources used by
> the network thread, and Close() - on the signaling thread - destroys
> these resources. As such, tasks run in parallel like getStats() get into
> race conditions with Close() unless synchronized. The mechanism in-place
> is RTCStatsCollector::WaitForPendingRequest(), it waits until the
> network thread is done with the in-parallel stats request.
>
> Prior to this CL, this was implemented by performing
> rtc::Thread::ProcessMessages() in a loop until the network thread had
> posted a task on the signaling thread to say that it was done which
> would then get processed by ProcessMessages(). In WebRTC this works, and
> the test is RTCStatsIntegrationTest.GetsStatsWhileClosingPeerConnection.
>
> But because Chromium's thread wrapper does no support
> ProcessMessages(), calling getStats() followed by close() in Chrome
> resulted in waiting forever (https://crbug.com/850907).
>
> In this CL, the process messages loop is removed. Instead, the shared
> resources are guarded by an rtc::Event. WaitForPendingRequest() still
> blocks the signaling thread, but only while shared resources are in use
> by the network thread. After this CL, calling WaitForPendingRequest() no
> longer has any unexpected side-effects since it no longer processes
> other messages that might have been posted on the thread.
>
> The resource ownership and threading model of WebRTC deserves to be
> revisited, but this fixes a common Chromium crash without redesigning
> PeerConnection, in a way that does not cause more blocking than what
> the other PeerConnection methods are already doing.
>
> Note: An alternative to using rtc::Event is to use resource locks and
> to not perform the stats collection on the network thread if the
> request was cancelled before the start of processing, but this has very
> little benefit in terms of performance: once the network thread starts
> collecting the stats, it would use the lock until collection is
> completed, blocking the signaling thread trying to acquire that lock
> anyway. This defeats the purpose and is a riskier change, since
> cancelling partial collection in this inherently racy edge-case would
> have observable differences from the returned stats, which may cause
> more regressions.
>
> Bug: chromium:850907
> Change-Id: Idceeee0bddc0c9d5518b58a2b263abb2bbf47cff
> Reviewed-on: https://webrtc-review.googlesource.com/c/121567
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Reviewed-by: Steve Anton <steveanton@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#26707}
TBR=steveanton@webrtc.org
Bug: chromium:850907
Change-Id: I5be7f69f0de65ff1120e4926fbf904def97ea9c0
Reviewed-on: https://webrtc-review.googlesource.com/c/124781
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26896}
2019-02-28 09:49:31 +01:00
|
|
|
void ProducePartialResultsOnSignalingThreadImpl(
|
|
|
|
|
int64_t timestamp_us,
|
|
|
|
|
RTCStatsReport* partial_report) override {
|
2018-02-02 16:00:20 -08:00
|
|
|
EXPECT_TRUE(signaling_thread_->IsCurrent());
|
|
|
|
|
{
|
2020-07-07 19:08:53 +02:00
|
|
|
MutexLock lock(&lock_);
|
2018-02-02 16:00:20 -08:00
|
|
|
EXPECT_FALSE(delivered_report_);
|
|
|
|
|
++produced_on_signaling_thread_;
|
|
|
|
|
}
|
|
|
|
|
|
Reland "Fix getStats() freeze bug affecting Chromium but not WebRTC standalone."
This is a reland of 05d43c6f7fe497fed0f2c8714e2042dd07a86df2
The original CL got reverted because Chrome did not support IsQuitting() which
triggered a NOTREACHED() inside of a DCHECK. With
https://chromium-review.googlesource.com/c/chromium/src/+/1491620
it is safe to reland this CL.
The only changes between this and the original patch set is that this is now
rebased on top of https://webrtc-review.googlesource.com/c/src/+/124701, i.e.
rtc::PostMessageWithFunctor() has been replaced by rtc::Thread::PostTask().
Original change's description:
> Fix getStats() freeze bug affecting Chromium but not WebRTC standalone.
>
> PeerConnection::Close() is, per-spec, a blocking operation.
> Unfortunately, PeerConnection is implemented to own resources used by
> the network thread, and Close() - on the signaling thread - destroys
> these resources. As such, tasks run in parallel like getStats() get into
> race conditions with Close() unless synchronized. The mechanism in-place
> is RTCStatsCollector::WaitForPendingRequest(), it waits until the
> network thread is done with the in-parallel stats request.
>
> Prior to this CL, this was implemented by performing
> rtc::Thread::ProcessMessages() in a loop until the network thread had
> posted a task on the signaling thread to say that it was done which
> would then get processed by ProcessMessages(). In WebRTC this works, and
> the test is RTCStatsIntegrationTest.GetsStatsWhileClosingPeerConnection.
>
> But because Chromium's thread wrapper does no support
> ProcessMessages(), calling getStats() followed by close() in Chrome
> resulted in waiting forever (https://crbug.com/850907).
>
> In this CL, the process messages loop is removed. Instead, the shared
> resources are guarded by an rtc::Event. WaitForPendingRequest() still
> blocks the signaling thread, but only while shared resources are in use
> by the network thread. After this CL, calling WaitForPendingRequest() no
> longer has any unexpected side-effects since it no longer processes
> other messages that might have been posted on the thread.
>
> The resource ownership and threading model of WebRTC deserves to be
> revisited, but this fixes a common Chromium crash without redesigning
> PeerConnection, in a way that does not cause more blocking than what
> the other PeerConnection methods are already doing.
>
> Note: An alternative to using rtc::Event is to use resource locks and
> to not perform the stats collection on the network thread if the
> request was cancelled before the start of processing, but this has very
> little benefit in terms of performance: once the network thread starts
> collecting the stats, it would use the lock until collection is
> completed, blocking the signaling thread trying to acquire that lock
> anyway. This defeats the purpose and is a riskier change, since
> cancelling partial collection in this inherently racy edge-case would
> have observable differences from the returned stats, which may cause
> more regressions.
>
> Bug: chromium:850907
> Change-Id: Idceeee0bddc0c9d5518b58a2b263abb2bbf47cff
> Reviewed-on: https://webrtc-review.googlesource.com/c/121567
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Reviewed-by: Steve Anton <steveanton@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#26707}
TBR=steveanton@webrtc.org
Bug: chromium:850907
Change-Id: I5be7f69f0de65ff1120e4926fbf904def97ea9c0
Reviewed-on: https://webrtc-review.googlesource.com/c/124781
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26896}
2019-02-28 09:49:31 +01:00
|
|
|
partial_report->AddStats(std::unique_ptr<const RTCStats>(
|
2018-02-02 16:00:20 -08:00
|
|
|
new RTCTestStats("SignalingThreadStats", timestamp_us)));
|
|
|
|
|
}
|
Reland "Fix getStats() freeze bug affecting Chromium but not WebRTC standalone."
This is a reland of 05d43c6f7fe497fed0f2c8714e2042dd07a86df2
The original CL got reverted because Chrome did not support IsQuitting() which
triggered a NOTREACHED() inside of a DCHECK. With
https://chromium-review.googlesource.com/c/chromium/src/+/1491620
it is safe to reland this CL.
The only changes between this and the original patch set is that this is now
rebased on top of https://webrtc-review.googlesource.com/c/src/+/124701, i.e.
rtc::PostMessageWithFunctor() has been replaced by rtc::Thread::PostTask().
Original change's description:
> Fix getStats() freeze bug affecting Chromium but not WebRTC standalone.
>
> PeerConnection::Close() is, per-spec, a blocking operation.
> Unfortunately, PeerConnection is implemented to own resources used by
> the network thread, and Close() - on the signaling thread - destroys
> these resources. As such, tasks run in parallel like getStats() get into
> race conditions with Close() unless synchronized. The mechanism in-place
> is RTCStatsCollector::WaitForPendingRequest(), it waits until the
> network thread is done with the in-parallel stats request.
>
> Prior to this CL, this was implemented by performing
> rtc::Thread::ProcessMessages() in a loop until the network thread had
> posted a task on the signaling thread to say that it was done which
> would then get processed by ProcessMessages(). In WebRTC this works, and
> the test is RTCStatsIntegrationTest.GetsStatsWhileClosingPeerConnection.
>
> But because Chromium's thread wrapper does no support
> ProcessMessages(), calling getStats() followed by close() in Chrome
> resulted in waiting forever (https://crbug.com/850907).
>
> In this CL, the process messages loop is removed. Instead, the shared
> resources are guarded by an rtc::Event. WaitForPendingRequest() still
> blocks the signaling thread, but only while shared resources are in use
> by the network thread. After this CL, calling WaitForPendingRequest() no
> longer has any unexpected side-effects since it no longer processes
> other messages that might have been posted on the thread.
>
> The resource ownership and threading model of WebRTC deserves to be
> revisited, but this fixes a common Chromium crash without redesigning
> PeerConnection, in a way that does not cause more blocking than what
> the other PeerConnection methods are already doing.
>
> Note: An alternative to using rtc::Event is to use resource locks and
> to not perform the stats collection on the network thread if the
> request was cancelled before the start of processing, but this has very
> little benefit in terms of performance: once the network thread starts
> collecting the stats, it would use the lock until collection is
> completed, blocking the signaling thread trying to acquire that lock
> anyway. This defeats the purpose and is a riskier change, since
> cancelling partial collection in this inherently racy edge-case would
> have observable differences from the returned stats, which may cause
> more regressions.
>
> Bug: chromium:850907
> Change-Id: Idceeee0bddc0c9d5518b58a2b263abb2bbf47cff
> Reviewed-on: https://webrtc-review.googlesource.com/c/121567
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Reviewed-by: Steve Anton <steveanton@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#26707}
TBR=steveanton@webrtc.org
Bug: chromium:850907
Change-Id: I5be7f69f0de65ff1120e4926fbf904def97ea9c0
Reviewed-on: https://webrtc-review.googlesource.com/c/124781
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26896}
2019-02-28 09:49:31 +01:00
|
|
|
void ProducePartialResultsOnNetworkThreadImpl(
|
|
|
|
|
int64_t timestamp_us,
|
|
|
|
|
const std::map<std::string, cricket::TransportStats>&
|
|
|
|
|
transport_stats_by_name,
|
|
|
|
|
const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
|
|
|
|
|
RTCStatsReport* partial_report) override {
|
2018-02-02 16:00:20 -08:00
|
|
|
EXPECT_TRUE(network_thread_->IsCurrent());
|
|
|
|
|
{
|
2020-07-07 19:08:53 +02:00
|
|
|
MutexLock lock(&lock_);
|
2018-02-02 16:00:20 -08:00
|
|
|
EXPECT_FALSE(delivered_report_);
|
|
|
|
|
++produced_on_network_thread_;
|
|
|
|
|
}
|
|
|
|
|
|
Reland "Fix getStats() freeze bug affecting Chromium but not WebRTC standalone."
This is a reland of 05d43c6f7fe497fed0f2c8714e2042dd07a86df2
The original CL got reverted because Chrome did not support IsQuitting() which
triggered a NOTREACHED() inside of a DCHECK. With
https://chromium-review.googlesource.com/c/chromium/src/+/1491620
it is safe to reland this CL.
The only changes between this and the original patch set is that this is now
rebased on top of https://webrtc-review.googlesource.com/c/src/+/124701, i.e.
rtc::PostMessageWithFunctor() has been replaced by rtc::Thread::PostTask().
Original change's description:
> Fix getStats() freeze bug affecting Chromium but not WebRTC standalone.
>
> PeerConnection::Close() is, per-spec, a blocking operation.
> Unfortunately, PeerConnection is implemented to own resources used by
> the network thread, and Close() - on the signaling thread - destroys
> these resources. As such, tasks run in parallel like getStats() get into
> race conditions with Close() unless synchronized. The mechanism in-place
> is RTCStatsCollector::WaitForPendingRequest(), it waits until the
> network thread is done with the in-parallel stats request.
>
> Prior to this CL, this was implemented by performing
> rtc::Thread::ProcessMessages() in a loop until the network thread had
> posted a task on the signaling thread to say that it was done which
> would then get processed by ProcessMessages(). In WebRTC this works, and
> the test is RTCStatsIntegrationTest.GetsStatsWhileClosingPeerConnection.
>
> But because Chromium's thread wrapper does no support
> ProcessMessages(), calling getStats() followed by close() in Chrome
> resulted in waiting forever (https://crbug.com/850907).
>
> In this CL, the process messages loop is removed. Instead, the shared
> resources are guarded by an rtc::Event. WaitForPendingRequest() still
> blocks the signaling thread, but only while shared resources are in use
> by the network thread. After this CL, calling WaitForPendingRequest() no
> longer has any unexpected side-effects since it no longer processes
> other messages that might have been posted on the thread.
>
> The resource ownership and threading model of WebRTC deserves to be
> revisited, but this fixes a common Chromium crash without redesigning
> PeerConnection, in a way that does not cause more blocking than what
> the other PeerConnection methods are already doing.
>
> Note: An alternative to using rtc::Event is to use resource locks and
> to not perform the stats collection on the network thread if the
> request was cancelled before the start of processing, but this has very
> little benefit in terms of performance: once the network thread starts
> collecting the stats, it would use the lock until collection is
> completed, blocking the signaling thread trying to acquire that lock
> anyway. This defeats the purpose and is a riskier change, since
> cancelling partial collection in this inherently racy edge-case would
> have observable differences from the returned stats, which may cause
> more regressions.
>
> Bug: chromium:850907
> Change-Id: Idceeee0bddc0c9d5518b58a2b263abb2bbf47cff
> Reviewed-on: https://webrtc-review.googlesource.com/c/121567
> Commit-Queue: Henrik Boström <hbos@webrtc.org>
> Reviewed-by: Steve Anton <steveanton@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#26707}
TBR=steveanton@webrtc.org
Bug: chromium:850907
Change-Id: I5be7f69f0de65ff1120e4926fbf904def97ea9c0
Reviewed-on: https://webrtc-review.googlesource.com/c/124781
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#26896}
2019-02-28 09:49:31 +01:00
|
|
|
partial_report->AddStats(std::unique_ptr<const RTCStats>(
|
2018-02-02 16:00:20 -08:00
|
|
|
new RTCTestStats("NetworkThreadStats", timestamp_us)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
rtc::Thread* const signaling_thread_;
|
|
|
|
|
rtc::Thread* const worker_thread_;
|
|
|
|
|
rtc::Thread* const network_thread_;
|
|
|
|
|
|
2020-07-07 19:08:53 +02:00
|
|
|
Mutex lock_;
|
2018-02-02 16:00:20 -08:00
|
|
|
rtc::scoped_refptr<const RTCStatsReport> delivered_report_;
|
|
|
|
|
int produced_on_signaling_thread_ = 0;
|
|
|
|
|
int produced_on_network_thread_ = 0;
|
2016-09-05 01:36:50 -07:00
|
|
|
};
|
|
|
|
|
|
2018-02-02 16:00:20 -08:00
|
|
|
TEST(RTCStatsCollectorTestWithFakeCollector, ThreadUsageAndResultsMerging) {
|
|
|
|
|
rtc::scoped_refptr<FakePeerConnectionForStats> pc(
|
|
|
|
|
new rtc::RefCountedObject<FakePeerConnectionForStats>());
|
|
|
|
|
rtc::scoped_refptr<FakeRTCStatsCollector> stats_collector(
|
|
|
|
|
FakeRTCStatsCollector::Create(pc, 50 * rtc::kNumMicrosecsPerMillisec));
|
|
|
|
|
stats_collector->VerifyThreadUsageAndResultsMerging();
|
2016-09-05 01:36:50 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
2016-08-30 14:04:35 -07:00
|
|
|
} // namespace webrtc
|