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:
parent
93f16d74fc
commit
84abeb1d37
@ -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);
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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() {}
|
||||
|
||||
@ -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>>&());
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user