RTC[In/Out]boundRTPStreamStats.mediaTrackId collected.

Based on the mapping between [Audio/Video]TrackInterface and
[Voice/Video][Sender/Receiver]Info.

The IDs of RTCMediaStreamTrackStats are updated to distinguish between
local and remote cases. Previously, if local and remote cases had the
same label only one of them would be included in the report (bug).

BUG=webrtc:6758, chromium:657854, chromium:657855, chromium:657856, chromium:627816

Review-Url: https://codereview.webrtc.org/2610843003
Cr-Commit-Position: refs/heads/master@{#16095}
This commit is contained in:
hbos 2017-01-16 06:16:44 -08:00 committed by Commit bot
parent 93f16d74fc
commit 84abeb1d37
7 changed files with 275 additions and 68 deletions

View File

@ -490,7 +490,8 @@ class RTCStatsReportVerifier {
verifier->TestMemberIsUndefined(stream.associate_stats_id);
verifier->TestMemberIsDefined(stream.is_remote);
verifier->TestMemberIsDefined(stream.media_type);
verifier->TestMemberIsUndefined(stream.media_track_id);
verifier->TestMemberIsIDReference(
stream.media_track_id, RTCMediaStreamTrackStats::kType);
verifier->TestMemberIsIDReference(
stream.transport_id, RTCTransportStats::kType);
verifier->TestMemberIsIDReference(stream.codec_id, RTCCodecStats::kType);

View File

@ -53,9 +53,10 @@ std::string RTCIceCandidatePairStatsIDFromConnectionInfo(
info.remote_candidate.id();
}
std::string RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface(
const MediaStreamTrackInterface& track) {
return "RTCMediaStreamTrack_" + track.id();
std::string RTCMediaStreamTrackStatsIDFromTrackID(
const std::string& id, bool is_local) {
return (is_local ? "RTCMediaStreamTrack_local_" + id
: "RTCMediaStreamTrack_remote_" + id);
}
std::string RTCTransportStatsIDFromTransportChannel(
@ -327,8 +328,8 @@ void ProduceMediaStreamAndTrackStats(
// Audio Tracks
for (const rtc::scoped_refptr<AudioTrackInterface>& audio_track :
stream->GetAudioTracks()) {
std::string id = RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface(
*audio_track.get());
std::string id = RTCMediaStreamTrackStatsIDFromTrackID(
audio_track->id(), is_local);
if (report->Get(id)) {
// Skip track, stats already exist for it.
continue;
@ -365,8 +366,8 @@ void ProduceMediaStreamAndTrackStats(
// Video Tracks
for (const rtc::scoped_refptr<VideoTrackInterface>& video_track :
stream->GetVideoTracks()) {
std::string id = RTCMediaStreamTrackStatsIDFromMediaStreamTrackInterface(
*video_track.get());
std::string id = RTCMediaStreamTrackStatsIDFromTrackID(
video_track->id(), is_local);
if (report->Get(id)) {
// Skip track, stats already exist for it.
continue;
@ -450,7 +451,7 @@ void RTCStatsCollector::GetStatsReport(
num_pending_partial_reports_ = 2;
partial_report_timestamp_us_ = cache_now_us;
// Prepare |channel_names_| and |media_info_| for use in
// Prepare |channel_name_pairs_| for use in
// |ProducePartialResultsOnNetworkThread|.
channel_name_pairs_.reset(new ChannelNamePairs());
if (pc_->session()->voice_channel()) {
@ -474,7 +475,14 @@ void RTCStatsCollector::GetStatsReport(
ChannelNamePair(*pc_->session()->sctp_content_name(),
*pc_->session()->sctp_transport_name()));
}
media_info_.reset(PrepareMediaInfo_s().release());
// Prepare |track_media_info_map_| for use in
// |ProducePartialResultsOnNetworkThread| and
// |ProducePartialResultsOnSignalingThread|.
track_media_info_map_.reset(PrepareTrackMediaInfoMap_s().release());
// Prepare |track_to_id_| for use in |ProducePartialResultsOnNetworkThread|.
// This avoids a possible deadlock if |MediaStreamTrackInterface::id| is
// implemented to invoke on the signaling thread.
track_to_id_ = PrepareTrackToID_s();
invoker_.AsyncInvoke<void>(RTC_FROM_HERE, network_thread_,
rtc::Bind(&RTCStatsCollector::ProducePartialResultsOnNetworkThread,
@ -527,11 +535,11 @@ void RTCStatsCollector::ProducePartialResultsOnNetworkThread(
ProduceCertificateStats_n(
timestamp_us, transport_cert_stats, report.get());
ProduceCodecStats_n(
timestamp_us, *media_info_, report.get());
timestamp_us, *track_media_info_map_, report.get());
ProduceIceCandidateAndPairStats_n(
timestamp_us, *session_stats, report.get());
ProduceRTPStreamStats_n(
timestamp_us, *session_stats, *media_info_, report.get());
timestamp_us, *session_stats, *track_media_info_map_, report.get());
ProduceTransportStats_n(
timestamp_us, *session_stats, transport_cert_stats, report.get());
}
@ -564,6 +572,9 @@ void RTCStatsCollector::AddPartialResults_s(
cache_timestamp_us_ = partial_report_timestamp_us_;
cached_report_ = partial_report_;
partial_report_ = nullptr;
channel_name_pairs_.reset();
track_media_info_map_.reset();
track_to_id_.clear();
DeliverCachedReport();
}
}
@ -597,31 +608,35 @@ void RTCStatsCollector::ProduceCertificateStats_n(
}
void RTCStatsCollector::ProduceCodecStats_n(
int64_t timestamp_us, const MediaInfo& media_info,
int64_t timestamp_us, const TrackMediaInfoMap& track_media_info_map,
RTCStatsReport* report) const {
RTC_DCHECK(network_thread_->IsCurrent());
// Audio
if (media_info.voice) {
if (track_media_info_map.voice_media_info()) {
// Inbound
for (const auto& pair : media_info.voice->receive_codecs) {
for (const auto& pair :
track_media_info_map.voice_media_info()->receive_codecs) {
report->AddStats(CodecStatsFromRtpCodecParameters(
timestamp_us, true, true, pair.second));
}
// Outbound
for (const auto& pair : media_info.voice->send_codecs) {
for (const auto& pair :
track_media_info_map.voice_media_info()->send_codecs) {
report->AddStats(CodecStatsFromRtpCodecParameters(
timestamp_us, false, true, pair.second));
}
}
// Video
if (media_info.video) {
if (track_media_info_map.video_media_info()) {
// Inbound
for (const auto& pair : media_info.video->receive_codecs) {
for (const auto& pair :
track_media_info_map.video_media_info()->receive_codecs) {
report->AddStats(CodecStatsFromRtpCodecParameters(
timestamp_us, true, false, pair.second));
}
// Outbound
for (const auto& pair : media_info.video->send_codecs) {
for (const auto& pair :
track_media_info_map.video_media_info()->send_codecs) {
report->AddStats(CodecStatsFromRtpCodecParameters(
timestamp_us, false, false, pair.second));
}
@ -731,17 +746,18 @@ void RTCStatsCollector::ProducePeerConnectionStats_s(
void RTCStatsCollector::ProduceRTPStreamStats_n(
int64_t timestamp_us, const SessionStats& session_stats,
const MediaInfo& media_info, RTCStatsReport* report) const {
const TrackMediaInfoMap& track_media_info_map,
RTCStatsReport* report) const {
RTC_DCHECK(network_thread_->IsCurrent());
// Audio
if (media_info.voice) {
if (track_media_info_map.voice_media_info()) {
std::string transport_id = RTCTransportStatsIDFromBaseChannel(
session_stats.proxy_to_transport, *pc_->session()->voice_channel());
RTC_DCHECK(!transport_id.empty());
// Inbound
for (const cricket::VoiceReceiverInfo& voice_receiver_info :
media_info.voice->receivers) {
track_media_info_map.voice_media_info()->receivers) {
// TODO(nisse): SSRC == 0 currently means none. Delete check when that
// is fixed.
if (voice_receiver_info.ssrc() == 0)
@ -753,6 +769,14 @@ void RTCStatsCollector::ProduceRTPStreamStats_n(
timestamp_us));
SetInboundRTPStreamStatsFromVoiceReceiverInfo(
voice_receiver_info, inbound_audio.get());
rtc::scoped_refptr<AudioTrackInterface> audio_track =
track_media_info_map_->GetAudioTrack(voice_receiver_info);
if (audio_track) {
RTC_DCHECK(track_to_id_.find(audio_track.get()) != track_to_id_.end());
inbound_audio->media_track_id =
RTCMediaStreamTrackStatsIDFromTrackID(
track_to_id_.find(audio_track.get())->second, false);
}
inbound_audio->transport_id = transport_id;
if (voice_receiver_info.codec_payload_type) {
inbound_audio->codec_id =
@ -763,7 +787,7 @@ void RTCStatsCollector::ProduceRTPStreamStats_n(
}
// Outbound
for (const cricket::VoiceSenderInfo& voice_sender_info :
media_info.voice->senders) {
track_media_info_map.voice_media_info()->senders) {
// TODO(nisse): SSRC == 0 currently means none. Delete check when that
// is fixed.
if (voice_sender_info.ssrc() == 0)
@ -775,6 +799,14 @@ void RTCStatsCollector::ProduceRTPStreamStats_n(
timestamp_us));
SetOutboundRTPStreamStatsFromVoiceSenderInfo(
voice_sender_info, outbound_audio.get());
rtc::scoped_refptr<AudioTrackInterface> audio_track =
track_media_info_map_->GetAudioTrack(voice_sender_info);
if (audio_track) {
RTC_DCHECK(track_to_id_.find(audio_track.get()) != track_to_id_.end());
outbound_audio->media_track_id =
RTCMediaStreamTrackStatsIDFromTrackID(
track_to_id_.find(audio_track.get())->second, true);
}
outbound_audio->transport_id = transport_id;
if (voice_sender_info.codec_payload_type) {
outbound_audio->codec_id =
@ -785,13 +817,13 @@ void RTCStatsCollector::ProduceRTPStreamStats_n(
}
}
// Video
if (media_info.video) {
if (track_media_info_map.video_media_info()) {
std::string transport_id = RTCTransportStatsIDFromBaseChannel(
session_stats.proxy_to_transport, *pc_->session()->video_channel());
RTC_DCHECK(!transport_id.empty());
// Inbound
for (const cricket::VideoReceiverInfo& video_receiver_info :
media_info.video->receivers) {
track_media_info_map.video_media_info()->receivers) {
// TODO(nisse): SSRC == 0 currently means none. Delete check when that
// is fixed.
if (video_receiver_info.ssrc() == 0)
@ -803,6 +835,14 @@ void RTCStatsCollector::ProduceRTPStreamStats_n(
timestamp_us));
SetInboundRTPStreamStatsFromVideoReceiverInfo(
video_receiver_info, inbound_video.get());
rtc::scoped_refptr<VideoTrackInterface> video_track =
track_media_info_map_->GetVideoTrack(video_receiver_info);
if (video_track) {
RTC_DCHECK(track_to_id_.find(video_track.get()) != track_to_id_.end());
inbound_video->media_track_id =
RTCMediaStreamTrackStatsIDFromTrackID(
track_to_id_.find(video_track.get())->second, false);
}
inbound_video->transport_id = transport_id;
if (video_receiver_info.codec_payload_type) {
inbound_video->codec_id =
@ -813,7 +853,7 @@ void RTCStatsCollector::ProduceRTPStreamStats_n(
}
// Outbound
for (const cricket::VideoSenderInfo& video_sender_info :
media_info.video->senders) {
track_media_info_map.video_media_info()->senders) {
// TODO(nisse): SSRC == 0 currently means none. Delete check when that
// is fixed.
if (video_sender_info.ssrc() == 0)
@ -825,6 +865,14 @@ void RTCStatsCollector::ProduceRTPStreamStats_n(
timestamp_us));
SetOutboundRTPStreamStatsFromVideoSenderInfo(
video_sender_info, outbound_video.get());
rtc::scoped_refptr<VideoTrackInterface> video_track =
track_media_info_map_->GetVideoTrack(video_sender_info);
if (video_track) {
RTC_DCHECK(track_to_id_.find(video_track.get()) != track_to_id_.end());
outbound_video->media_track_id =
RTCMediaStreamTrackStatsIDFromTrackID(
track_to_id_.find(video_track.get())->second, true);
}
outbound_video->transport_id = transport_id;
if (video_sender_info.codec_payload_type) {
outbound_video->codec_id =
@ -928,25 +976,53 @@ RTCStatsCollector::PrepareTransportCertificateStats_n(
return transport_cert_stats;
}
std::unique_ptr<RTCStatsCollector::MediaInfo>
RTCStatsCollector::PrepareMediaInfo_s() const {
std::unique_ptr<TrackMediaInfoMap>
RTCStatsCollector::PrepareTrackMediaInfoMap_s() const {
RTC_DCHECK(signaling_thread_->IsCurrent());
std::unique_ptr<MediaInfo> media_info(new MediaInfo());
std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info;
if (pc_->session()->voice_channel()) {
cricket::VoiceMediaInfo voice_media_info;
if (pc_->session()->voice_channel()->GetStats(&voice_media_info)) {
media_info->voice = rtc::Optional<cricket::VoiceMediaInfo>(
std::move(voice_media_info));
voice_media_info.reset(new cricket::VoiceMediaInfo());
if (!pc_->session()->voice_channel()->GetStats(voice_media_info.get())) {
voice_media_info.reset();
}
}
std::unique_ptr<cricket::VideoMediaInfo> video_media_info;
if (pc_->session()->video_channel()) {
cricket::VideoMediaInfo video_media_info;
if (pc_->session()->video_channel()->GetStats(&video_media_info)) {
media_info->video = rtc::Optional<cricket::VideoMediaInfo>(
std::move(video_media_info));
video_media_info.reset(new cricket::VideoMediaInfo());
if (!pc_->session()->video_channel()->GetStats(video_media_info.get())) {
video_media_info.reset();
}
}
return media_info;
std::unique_ptr<TrackMediaInfoMap> track_media_info_map(
new TrackMediaInfoMap(std::move(voice_media_info),
std::move(video_media_info),
pc_->GetSenders(),
pc_->GetReceivers()));
return track_media_info_map;
}
std::map<MediaStreamTrackInterface*, std::string>
RTCStatsCollector::PrepareTrackToID_s() const {
RTC_DCHECK(signaling_thread_->IsCurrent());
std::map<MediaStreamTrackInterface*, std::string> track_to_id;
StreamCollectionInterface* local_and_remote_streams[] =
{ pc_->local_streams().get(), pc_->remote_streams().get() };
for (auto& streams : local_and_remote_streams) {
if (streams) {
for (size_t i = 0; i < streams->count(); ++i) {
MediaStreamInterface* stream = streams->at(i);
for (const rtc::scoped_refptr<AudioTrackInterface>& audio_track :
stream->GetAudioTracks()) {
track_to_id[audio_track.get()] = audio_track->id();
}
for (const rtc::scoped_refptr<VideoTrackInterface>& video_track :
stream->GetVideoTracks()) {
track_to_id[video_track.get()] = video_track->id();
}
}
}
}
return track_to_id;
}
void RTCStatsCollector::OnDataChannelCreated(DataChannel* channel) {

View File

@ -20,6 +20,7 @@
#include "webrtc/api/datachannelinterface.h"
#include "webrtc/api/stats/rtcstats_objects.h"
#include "webrtc/api/stats/rtcstatsreport.h"
#include "webrtc/api/trackmediainfomap.h"
#include "webrtc/base/asyncinvoker.h"
#include "webrtc/base/optional.h"
#include "webrtc/base/refcount.h"
@ -93,10 +94,6 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
std::unique_ptr<rtc::SSLCertificateStats> local;
std::unique_ptr<rtc::SSLCertificateStats> remote;
};
struct MediaInfo {
rtc::Optional<cricket::VoiceMediaInfo> voice;
rtc::Optional<cricket::VideoMediaInfo> video;
};
void AddPartialResults_s(rtc::scoped_refptr<RTCStatsReport> partial_report);
void DeliverCachedReport();
@ -108,7 +105,7 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
RTCStatsReport* report) const;
// Produces |RTCCodecStats|.
void ProduceCodecStats_n(
int64_t timestamp_us, const MediaInfo& media_info,
int64_t timestamp_us, const TrackMediaInfoMap& track_media_info_map,
RTCStatsReport* report) const;
// Produces |RTCDataChannelStats|.
void ProduceDataChannelStats_s(
@ -126,7 +123,8 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
// Produces |RTCInboundRTPStreamStats| and |RTCOutboundRTPStreamStats|.
void ProduceRTPStreamStats_n(
int64_t timestamp_us, const SessionStats& session_stats,
const MediaInfo& media_info, RTCStatsReport* report) const;
const TrackMediaInfoMap& track_media_info_map,
RTCStatsReport* report) const;
// Produces |RTCTransportStats|.
void ProduceTransportStats_n(
int64_t timestamp_us, const SessionStats& session_stats,
@ -136,7 +134,8 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
// Helper function to stats-producing functions.
std::map<std::string, CertificateStatsPair>
PrepareTransportCertificateStats_n(const SessionStats& session_stats) const;
std::unique_ptr<MediaInfo> PrepareMediaInfo_s() const;
std::unique_ptr<TrackMediaInfoMap> PrepareTrackMediaInfoMap_s() const;
std::map<MediaStreamTrackInterface*, std::string> PrepareTrackToID_s() const;
// Slots for signals (sigslot) that are wired up to |pc_|.
void OnDataChannelCreated(DataChannel* channel);
@ -155,12 +154,13 @@ class RTCStatsCollector : public virtual rtc::RefCountInterface,
rtc::scoped_refptr<RTCStatsReport> partial_report_;
std::vector<rtc::scoped_refptr<RTCStatsCollectorCallback>> callbacks_;
// Set in |GetStatsReport|, used in |ProducePartialResultsOnNetworkThread|
// (not passed as arguments to avoid copies). This is thread safe - it is set
// at the start of |GetStatsReport| after making sure there are no pending
// stats requests in progress.
// Set in |GetStatsReport|, read in |ProducePartialResultsOnNetworkThread| and
// |ProducePartialResultsOnSignalingThread|, reset after work is complete. Not
// passed as arguments to avoid copies. This is thread safe - when we
// set/reset we know there are no pending stats requests in progress.
std::unique_ptr<ChannelNamePairs> channel_name_pairs_;
std::unique_ptr<MediaInfo> media_info_;
std::unique_ptr<TrackMediaInfoMap> track_media_info_map_;
std::map<MediaStreamTrackInterface*, std::string> track_to_id_;
// A timestamp, in microseconds, that is based on a timer that is
// monotonically increasing. That is, even if the system clock is modified the

View File

@ -23,6 +23,8 @@
#include "webrtc/api/stats/rtcstatsreport.h"
#include "webrtc/api/test/mock_datachannel.h"
#include "webrtc/api/test/mock_peerconnection.h"
#include "webrtc/api/test/mock_rtpreceiver.h"
#include "webrtc/api/test/mock_rtpsender.h"
#include "webrtc/api/test/mock_webrtcsession.h"
#include "webrtc/api/test/rtcstatsobtainer.h"
#include "webrtc/base/checks.h"
@ -288,6 +290,26 @@ class FakeVideoTrackForStats
rtc::scoped_refptr<VideoTrackSourceInterface> source_;
};
rtc::scoped_refptr<MediaStreamTrackInterface> CreateFakeTrack(
cricket::MediaType media_type,
const std::string& track_id) {
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
return FakeAudioTrackForStats::Create(
track_id,
MediaStreamTrackInterface::TrackState::kLive,
32767,
new FakeAudioProcessorForStats(
AudioProcessorInterface::AudioProcessorStats()));
} else {
RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO);
return FakeVideoTrackForStats::Create(
track_id,
MediaStreamTrackInterface::TrackState::kLive,
new FakeVideoTrackSourceForStats(
VideoTrackSourceInterface::Stats()));
}
}
class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver {
public:
RTCStatsCollectorTestHelper()
@ -309,6 +331,10 @@ class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver {
EXPECT_CALL(pc_, local_streams()).WillRepeatedly(Return(nullptr));
EXPECT_CALL(pc_, remote_streams()).WillRepeatedly(Return(nullptr));
EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_));
EXPECT_CALL(pc_, GetSenders()).WillRepeatedly(Return(
std::vector<rtc::scoped_refptr<RtpSenderInterface>>()));
EXPECT_CALL(pc_, GetReceivers()).WillRepeatedly(Return(
std::vector<rtc::scoped_refptr<RtpReceiverInterface>>()));
EXPECT_CALL(pc_, sctp_data_channels()).WillRepeatedly(
ReturnRef(data_channels_));
EXPECT_CALL(session_, video_channel()).WillRepeatedly(ReturnNull());
@ -336,6 +362,81 @@ class RTCStatsCollectorTestHelper : public SetSessionDescriptionObserver {
RTC_NOTREACHED() << error;
}
void SetupLocalTrackAndSender(cricket::MediaType media_type,
const std::string& track_id,
uint32_t ssrc) {
rtc::scoped_refptr<StreamCollection> local_streams =
StreamCollection::Create();
EXPECT_CALL(pc_, local_streams())
.WillRepeatedly(Return(local_streams));
rtc::scoped_refptr<MediaStream> local_stream =
MediaStream::Create("LocalStreamLabel");
local_streams->AddStream(local_stream);
rtc::scoped_refptr<MediaStreamTrackInterface> track;
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
track = CreateFakeTrack(media_type, track_id);
local_stream->AddTrack(static_cast<AudioTrackInterface*>(track.get()));
} else {
track = CreateFakeTrack(media_type, track_id);
local_stream->AddTrack(static_cast<VideoTrackInterface*>(track.get()));
}
rtc::scoped_refptr<MockRtpSender> sender(
new rtc::RefCountedObject<MockRtpSender>());
EXPECT_CALL(*sender, track()).WillRepeatedly(Return(track));
EXPECT_CALL(*sender, ssrc()).WillRepeatedly(Return(ssrc));
EXPECT_CALL(*sender, media_type()).WillRepeatedly(Return(media_type));
EXPECT_CALL(*sender, GetParameters()).WillRepeatedly(Invoke(
[ssrc]() {
RtpParameters params;
params.encodings.push_back(RtpEncodingParameters());
params.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc);
return params;
}));
EXPECT_CALL(pc_, GetSenders()).WillRepeatedly(Return(
std::vector<rtc::scoped_refptr<RtpSenderInterface>>({
rtc::scoped_refptr<RtpSenderInterface>(sender.get()) })));
}
void SetupRemoteTrackAndReceiver(cricket::MediaType media_type,
const std::string& track_id,
uint32_t ssrc) {
rtc::scoped_refptr<StreamCollection> remote_streams =
StreamCollection::Create();
EXPECT_CALL(pc_, remote_streams())
.WillRepeatedly(Return(remote_streams));
rtc::scoped_refptr<MediaStream> remote_stream =
MediaStream::Create("RemoteStreamLabel");
remote_streams->AddStream(remote_stream);
rtc::scoped_refptr<MediaStreamTrackInterface> track;
if (media_type == cricket::MEDIA_TYPE_AUDIO) {
track = CreateFakeTrack(media_type, track_id);
remote_stream->AddTrack(static_cast<AudioTrackInterface*>(track.get()));
} else {
track = CreateFakeTrack(media_type, track_id);
remote_stream->AddTrack(static_cast<VideoTrackInterface*>(track.get()));
}
rtc::scoped_refptr<MockRtpReceiver> receiver(
new rtc::RefCountedObject<MockRtpReceiver>());
EXPECT_CALL(*receiver, track()).WillRepeatedly(Return(track));
EXPECT_CALL(*receiver, media_type()).WillRepeatedly(Return(media_type));
EXPECT_CALL(*receiver, GetParameters()).WillRepeatedly(Invoke(
[ssrc]() {
RtpParameters params;
params.encodings.push_back(RtpEncodingParameters());
params.encodings[0].ssrc = rtc::Optional<uint32_t>(ssrc);
return params;
}));
EXPECT_CALL(pc_, GetReceivers()).WillRepeatedly(Return(
std::vector<rtc::scoped_refptr<RtpReceiverInterface>>({
rtc::scoped_refptr<RtpReceiverInterface>(receiver.get()) })));
}
private:
rtc::ScopedFakeClock fake_clock_;
RtcEventLogNullImpl event_log_;
@ -1260,7 +1361,7 @@ TEST_F(RTCStatsCollectorTest,
expected_local_stream.stream_identifier = local_stream->label();
expected_local_stream.track_ids = std::vector<std::string>();
expected_local_stream.track_ids->push_back(
"RTCMediaStreamTrack_LocalAudioTrackID");
"RTCMediaStreamTrack_local_LocalAudioTrackID");
ASSERT_TRUE(report->Get(expected_local_stream.id()));
EXPECT_EQ(expected_local_stream,
report->Get(expected_local_stream.id())->cast_to<
@ -1271,14 +1372,14 @@ TEST_F(RTCStatsCollectorTest,
expected_remote_stream.stream_identifier = remote_stream->label();
expected_remote_stream.track_ids = std::vector<std::string>();
expected_remote_stream.track_ids->push_back(
"RTCMediaStreamTrack_RemoteAudioTrackID");
"RTCMediaStreamTrack_remote_RemoteAudioTrackID");
ASSERT_TRUE(report->Get(expected_remote_stream.id()));
EXPECT_EQ(expected_remote_stream,
report->Get(expected_remote_stream.id())->cast_to<
RTCMediaStreamStats>());
RTCMediaStreamTrackStats expected_local_audio_track(
"RTCMediaStreamTrack_LocalAudioTrackID", report->timestamp_us());
"RTCMediaStreamTrack_local_LocalAudioTrackID", report->timestamp_us());
expected_local_audio_track.track_identifier = local_audio_track->id();
expected_local_audio_track.remote_source = false;
expected_local_audio_track.ended = true;
@ -1292,7 +1393,7 @@ TEST_F(RTCStatsCollectorTest,
RTCMediaStreamTrackStats>());
RTCMediaStreamTrackStats expected_remote_audio_track(
"RTCMediaStreamTrack_RemoteAudioTrackID", report->timestamp_us());
"RTCMediaStreamTrack_remote_RemoteAudioTrackID", report->timestamp_us());
expected_remote_audio_track.track_identifier = remote_audio_track->id();
expected_remote_audio_track.remote_source = true;
expected_remote_audio_track.ended = false;
@ -1332,7 +1433,7 @@ TEST_F(RTCStatsCollectorTest,
rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
RTCMediaStreamTrackStats expected_local_audio_track(
"RTCMediaStreamTrack_LocalAudioTrackID", report->timestamp_us());
"RTCMediaStreamTrack_local_LocalAudioTrackID", report->timestamp_us());
expected_local_audio_track.track_identifier = local_audio_track->id();
expected_local_audio_track.remote_source = false;
expected_local_audio_track.ended = true;
@ -1397,7 +1498,7 @@ TEST_F(RTCStatsCollectorTest,
expected_local_stream.stream_identifier = local_stream->label();
expected_local_stream.track_ids = std::vector<std::string>();
expected_local_stream.track_ids->push_back(
"RTCMediaStreamTrack_LocalVideoTrackID");
"RTCMediaStreamTrack_local_LocalVideoTrackID");
ASSERT_TRUE(report->Get(expected_local_stream.id()));
EXPECT_EQ(expected_local_stream,
report->Get(expected_local_stream.id())->cast_to<
@ -1408,14 +1509,14 @@ TEST_F(RTCStatsCollectorTest,
expected_remote_stream.stream_identifier = remote_stream->label();
expected_remote_stream.track_ids = std::vector<std::string>();
expected_remote_stream.track_ids->push_back(
"RTCMediaStreamTrack_RemoteVideoTrackID");
"RTCMediaStreamTrack_remote_RemoteVideoTrackID");
ASSERT_TRUE(report->Get(expected_remote_stream.id()));
EXPECT_EQ(expected_remote_stream,
report->Get(expected_remote_stream.id())->cast_to<
RTCMediaStreamStats>());
RTCMediaStreamTrackStats expected_local_video_track(
"RTCMediaStreamTrack_LocalVideoTrackID", report->timestamp_us());
"RTCMediaStreamTrack_local_LocalVideoTrackID", report->timestamp_us());
expected_local_video_track.track_identifier = local_video_track->id();
expected_local_video_track.remote_source = false;
expected_local_video_track.ended = false;
@ -1428,7 +1529,7 @@ TEST_F(RTCStatsCollectorTest,
RTCMediaStreamTrackStats>());
RTCMediaStreamTrackStats expected_remote_video_track(
"RTCMediaStreamTrack_RemoteVideoTrackID", report->timestamp_us());
"RTCMediaStreamTrack_remote_RemoteVideoTrackID", report->timestamp_us());
expected_remote_video_track.track_identifier = remote_video_track->id();
expected_remote_video_track.remote_source = true;
expected_remote_video_track.ended = true;
@ -1448,6 +1549,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
test_->media_engine(), voice_media_channel, "VoiceContentName",
kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
test_->SetupRemoteTrackAndReceiver(
cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID", 1);
cricket::VoiceMediaInfo voice_media_info;
voice_media_info.receivers.push_back(cricket::VoiceReceiverInfo());
@ -1496,6 +1600,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
expected_audio.ssrc = "1";
expected_audio.is_remote = false;
expected_audio.media_type = "audio";
expected_audio.media_track_id =
"RTCMediaStreamTrack_remote_RemoteAudioTrackID";
expected_audio.transport_id = "RTCTransport_TransportName_" +
rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
expected_audio.codec_id = "RTCCodec_InboundAudio_42";
@ -1510,8 +1616,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
expected_audio.id())->cast_to<RTCInboundRTPStreamStats>();
EXPECT_EQ(audio, expected_audio);
ASSERT_TRUE(report->Get(*expected_audio.transport_id));
ASSERT_TRUE(report->Get(*expected_audio.codec_id));
EXPECT_TRUE(report->Get(*expected_audio.media_track_id));
EXPECT_TRUE(report->Get(*expected_audio.transport_id));
EXPECT_TRUE(report->Get(*expected_audio.codec_id));
}
TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
@ -1521,6 +1628,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
video_media_channel, "VideoContentName", kDefaultRtcpMuxRequired,
kDefaultSrtpRequired);
test_->SetupRemoteTrackAndReceiver(
cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID", 1);
cricket::VideoMediaInfo video_media_info;
video_media_info.receivers.push_back(cricket::VideoReceiverInfo());
@ -1572,6 +1682,8 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
expected_video.ssrc = "1";
expected_video.is_remote = false;
expected_video.media_type = "video";
expected_video.media_track_id =
"RTCMediaStreamTrack_remote_RemoteVideoTrackID";
expected_video.transport_id = "RTCTransport_TransportName_" +
rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
expected_video.codec_id = "RTCCodec_InboundVideo_42";
@ -1589,8 +1701,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Video) {
expected_video.id())->cast_to<RTCInboundRTPStreamStats>();
EXPECT_EQ(video, expected_video);
ASSERT_TRUE(report->Get(*expected_video.transport_id));
ASSERT_TRUE(report->Get(*video.codec_id));
EXPECT_TRUE(report->Get(*expected_video.media_track_id));
EXPECT_TRUE(report->Get(*expected_video.transport_id));
EXPECT_TRUE(report->Get(*video.codec_id));
}
TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
@ -1600,6 +1713,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
test_->media_engine(), voice_media_channel, "VoiceContentName",
kDefaultRtcpMuxRequired, kDefaultSrtpRequired);
test_->SetupLocalTrackAndSender(
cricket::MEDIA_TYPE_AUDIO, "LocalAudioTrackID", 1);
cricket::VoiceMediaInfo voice_media_info;
voice_media_info.senders.push_back(cricket::VoiceSenderInfo());
@ -1645,6 +1761,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
expected_audio.ssrc = "1";
expected_audio.is_remote = false;
expected_audio.media_type = "audio";
expected_audio.media_track_id = "RTCMediaStreamTrack_local_LocalAudioTrackID";
expected_audio.transport_id = "RTCTransport_TransportName_" +
rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
expected_audio.codec_id = "RTCCodec_OutboundAudio_42";
@ -1657,8 +1774,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Audio) {
expected_audio.id())->cast_to<RTCOutboundRTPStreamStats>();
EXPECT_EQ(audio, expected_audio);
ASSERT_TRUE(report->Get(*expected_audio.transport_id));
ASSERT_TRUE(report->Get(*expected_audio.codec_id));
EXPECT_TRUE(report->Get(*expected_audio.media_track_id));
EXPECT_TRUE(report->Get(*expected_audio.transport_id));
EXPECT_TRUE(report->Get(*expected_audio.codec_id));
}
TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
@ -1668,6 +1786,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
video_media_channel, "VideoContentName", kDefaultRtcpMuxRequired,
kDefaultSrtpRequired);
test_->SetupLocalTrackAndSender(
cricket::MEDIA_TYPE_VIDEO, "LocalVideoTrackID", 1);
cricket::VideoMediaInfo video_media_info;
video_media_info.senders.push_back(cricket::VideoSenderInfo());
@ -1718,6 +1839,7 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
expected_video.ssrc = "1";
expected_video.is_remote = false;
expected_video.media_type = "video";
expected_video.media_track_id = "RTCMediaStreamTrack_local_LocalVideoTrackID";
expected_video.transport_id = "RTCTransport_TransportName_" +
rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
expected_video.codec_id = "RTCCodec_OutboundVideo_42";
@ -1735,8 +1857,9 @@ TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Video) {
expected_video.id())->cast_to<RTCOutboundRTPStreamStats>();
EXPECT_EQ(video, expected_video);
ASSERT_TRUE(report->Get(*expected_video.transport_id));
ASSERT_TRUE(report->Get(*expected_video.codec_id));
EXPECT_TRUE(report->Get(*expected_video.media_track_id));
EXPECT_TRUE(report->Get(*expected_video.transport_id));
EXPECT_TRUE(report->Get(*expected_video.codec_id));
}
TEST_F(RTCStatsCollectorTest, CollectRTCOutboundRTPStreamStats_Default) {

View File

@ -295,7 +295,6 @@ class RTCRTPStreamStats : public RTCStats {
// crbug.com/657855, 657856
RTCStatsMember<bool> is_remote; // = false
RTCStatsMember<std::string> media_type;
// TODO(hbos): Not collected by |RTCStatsCollector|. crbug.com/657854, 659137
RTCStatsMember<std::string> media_track_id;
RTCStatsMember<std::string> transport_id;
RTCStatsMember<std::string> codec_id;

View File

@ -522,6 +522,10 @@ class StatsCollectorTest : public testing::Test {
EXPECT_CALL(pc_, session()).WillRepeatedly(Return(&session_));
EXPECT_CALL(pc_, sctp_data_channels())
.WillRepeatedly(ReturnRef(data_channels_));
EXPECT_CALL(pc_, GetSenders()).WillRepeatedly(Return(
std::vector<rtc::scoped_refptr<RtpSenderInterface>>()));
EXPECT_CALL(pc_, GetReceivers()).WillRepeatedly(Return(
std::vector<rtc::scoped_refptr<RtpReceiverInterface>>()));
}
~StatsCollectorTest() {}

View File

@ -33,6 +33,10 @@ class MockPeerConnection
MOCK_METHOD0(remote_streams,
rtc::scoped_refptr<StreamCollectionInterface>());
MOCK_METHOD0(session, WebRtcSession*());
MOCK_CONST_METHOD0(GetSenders,
std::vector<rtc::scoped_refptr<RtpSenderInterface>>());
MOCK_CONST_METHOD0(GetReceivers,
std::vector<rtc::scoped_refptr<RtpReceiverInterface>>());
MOCK_CONST_METHOD0(sctp_data_channels,
const std::vector<rtc::scoped_refptr<DataChannel>>&());
};