Reland "Move stats ID generation from SSRC to local ID"
This is a reland of e357a4dd4e3b015f8281813f246de793589bd537
Original change's description:
> Move stats ID generation from SSRC to local ID
>
> This generates stats IDs for Track stats (which
> represents stats on the attachment of a track to
> a PeerConnection) from being SSRC-based to being
> based on an ID that is allocated when connecting the
> track to the PC.
>
> This is a prerequisite to generating stats before
> the PeerConnection is connected.
>
> Bug: webrtc:8673
> Change-Id: I82f6e521646b0c92b3af4dffb2cdee75e6dc10d4
> Reviewed-on: https://webrtc-review.googlesource.com/38360
> Commit-Queue: Harald Alvestrand <hta@webrtc.org>
> Reviewed-by: Fredrik Solenberg <solenberg@webrtc.org>
> Reviewed-by: Henrik Boström <hbos@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#21582}
TBR=solenberg@webrtc.org
Bug: webrtc:8673
Change-Id: I610302efc5393919569b77e3b59aa3384a9b88a5
Reviewed-on: https://webrtc-review.googlesource.com/38842
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21589}
diff --git a/api/rtpreceiverinterface.h b/api/rtpreceiverinterface.h
index 311971d..ac2e090 100644
--- a/api/rtpreceiverinterface.h
+++ b/api/rtpreceiverinterface.h
@@ -127,6 +127,13 @@
virtual std::vector<RtpSource> GetSources() const {
return std::vector<RtpSource>();
}
+ // TODO(hta): Remove default implementation or move function to
+ // an internal interface. content::FakeRtpReceiver in Chromium needs this.
+
+ // Returns an ID that changes if the attached track changes, but
+ // otherwise remains constant. Used to generate IDs for stats.
+ // The special value zero means that no track is attached.
+ virtual int AttachmentId() const { return 0; }
protected:
virtual ~RtpReceiverInterface() {}
@@ -146,6 +153,7 @@
PROXY_METHOD1(bool, SetParameters, const RtpParameters&)
PROXY_METHOD1(void, SetObserver, RtpReceiverObserverInterface*);
PROXY_CONSTMETHOD0(std::vector<RtpSource>, GetSources);
+ PROXY_CONSTMETHOD0(int, AttachmentId);
END_PROXY_MAP()
} // namespace webrtc
diff --git a/api/rtpsenderinterface.h b/api/rtpsenderinterface.h
index a7fbbda..a7d7edc 100644
--- a/api/rtpsenderinterface.h
+++ b/api/rtpsenderinterface.h
@@ -59,6 +59,13 @@
// Returns null for a video sender.
virtual rtc::scoped_refptr<DtmfSenderInterface> GetDtmfSender() const = 0;
+ // Returns an ID that changes every time SetTrack() is called, but
+ // otherwise remains constant. Used to generate IDs for stats.
+ // The special value zero means that no track is attached.
+ // TODO(hta): Remove default implementation when callers have updated,
+ // or move function to an internal interface.
+ virtual int AttachmentId() const { return 0; }
+
protected:
virtual ~RtpSenderInterface() {}
};
@@ -77,7 +84,8 @@
PROXY_CONSTMETHOD0(RtpParameters, GetParameters);
PROXY_METHOD1(bool, SetParameters, const RtpParameters&)
PROXY_CONSTMETHOD0(rtc::scoped_refptr<DtmfSenderInterface>, GetDtmfSender);
-END_PROXY_MAP()
+ PROXY_CONSTMETHOD0(int, AttachmentId);
+ END_PROXY_MAP()
} // namespace webrtc
diff --git a/api/test/mock_rtpreceiver.h b/api/test/mock_rtpreceiver.h
index 7097adc..53c04b9 100644
--- a/api/test/mock_rtpreceiver.h
+++ b/api/test/mock_rtpreceiver.h
@@ -29,6 +29,7 @@
MOCK_METHOD1(SetParameters, bool(const RtpParameters&));
MOCK_METHOD1(SetObserver, void(RtpReceiverObserverInterface*));
MOCK_CONST_METHOD0(GetSources, std::vector<RtpSource>());
+ MOCK_CONST_METHOD0(AttachmentId, int());
};
} // namespace webrtc
diff --git a/api/test/mock_rtpsender.h b/api/test/mock_rtpsender.h
index a89fa92..35d048c 100644
--- a/api/test/mock_rtpsender.h
+++ b/api/test/mock_rtpsender.h
@@ -30,6 +30,7 @@
MOCK_CONST_METHOD0(GetParameters, RtpParameters());
MOCK_METHOD1(SetParameters, bool(const RtpParameters&));
MOCK_CONST_METHOD0(GetDtmfSender, rtc::scoped_refptr<DtmfSenderInterface>());
+ MOCK_CONST_METHOD0(AttachmentId, int());
};
} // namespace webrtc
diff --git a/pc/peerconnectioninterface_unittest.cc b/pc/peerconnectioninterface_unittest.cc
index bc6b5e5..a06ed50 100644
--- a/pc/peerconnectioninterface_unittest.cc
+++ b/pc/peerconnectioninterface_unittest.cc
@@ -1506,6 +1506,31 @@
EXPECT_TRUE(DoGetStats(nullptr));
}
+TEST_F(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddTrack) {
+ CreatePeerConnectionWithoutDtls();
+ rtc::scoped_refptr<AudioTrackInterface> audio_track(
+ pc_factory_->CreateAudioTrack("audio_track", nullptr));
+ rtc::scoped_refptr<VideoTrackInterface> video_track(
+ pc_factory_->CreateVideoTrack(
+ "video_track", pc_factory_->CreateVideoSource(
+ std::unique_ptr<cricket::VideoCapturer>(
+ new cricket::FakeVideoCapturer()))));
+ auto audio_sender = pc_->AddTrack(audio_track, std::vector<std::string>());
+ auto video_sender = pc_->AddTrack(video_track, std::vector<std::string>());
+ EXPECT_TRUE(audio_sender.ok());
+ EXPECT_TRUE(video_sender.ok());
+ EXPECT_NE(0, video_sender.value()->AttachmentId());
+ EXPECT_NE(0, audio_sender.value()->AttachmentId());
+}
+
+TEST_F(PeerConnectionInterfaceTest, AttachmentIdIsSetOnAddStream) {
+ CreatePeerConnectionWithoutDtls();
+ AddVideoStream(kStreamLabel1);
+ auto senders = pc_->GetSenders();
+ EXPECT_EQ(1u, senders.size());
+ EXPECT_NE(0, senders[0]->AttachmentId());
+}
+
TEST_F(PeerConnectionInterfaceTest, CreateOfferReceiveAnswer) {
InitiateCall();
WaitAndVerifyOnAddStream(kStreamLabel1);
diff --git a/pc/rtcstatscollector.cc b/pc/rtcstatscollector.cc
index e777a26..0f4dc3d 100644
--- a/pc/rtcstatscollector.cc
+++ b/pc/rtcstatscollector.cc
@@ -57,8 +57,11 @@
info.remote_candidate.id();
}
-std::string RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
- bool is_local, const char* kind, const std::string& id, uint32_t ssrc) {
+std::string RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
+ bool is_local,
+ const char* kind,
+ const std::string& id,
+ int attachment_id) {
RTC_DCHECK(kind == MediaStreamTrackInterface::kAudioKind ||
kind == MediaStreamTrackInterface::kVideoKind);
std::ostringstream oss;
@@ -66,7 +69,7 @@
: "RTCMediaStreamTrack_remote_");
oss << kind << "_";
oss << id << "_";
- oss << ssrc;
+ oss << attachment_id;
return oss.str();
}
@@ -375,14 +378,14 @@
ProduceMediaStreamTrackStatsFromVoiceSenderInfo(
int64_t timestamp_us,
const AudioTrackInterface& audio_track,
- const cricket::VoiceSenderInfo& voice_sender_info) {
+ const cricket::VoiceSenderInfo& voice_sender_info,
+ int attachment_id) {
std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats(
new RTCMediaStreamTrackStats(
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
+ RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
true, MediaStreamTrackInterface::kAudioKind, audio_track.id(),
- voice_sender_info.ssrc()),
- timestamp_us,
- RTCMediaStreamTrackKind::kAudio));
+ attachment_id),
+ timestamp_us, RTCMediaStreamTrackKind::kAudio));
SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
audio_track, audio_track_stats.get());
audio_track_stats->remote_source = false;
@@ -409,14 +412,16 @@
ProduceMediaStreamTrackStatsFromVoiceReceiverInfo(
int64_t timestamp_us,
const AudioTrackInterface& audio_track,
- const cricket::VoiceReceiverInfo& voice_receiver_info) {
+ const cricket::VoiceReceiverInfo& voice_receiver_info,
+ int attachment_id) {
+ // Since receiver tracks can't be reattached, we use the SSRC as
+ // an attachment identifier.
std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats(
new RTCMediaStreamTrackStats(
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
+ RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
false, MediaStreamTrackInterface::kAudioKind, audio_track.id(),
- voice_receiver_info.ssrc()),
- timestamp_us,
- RTCMediaStreamTrackKind::kAudio));
+ attachment_id),
+ timestamp_us, RTCMediaStreamTrackKind::kAudio));
SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
audio_track, audio_track_stats.get());
audio_track_stats->remote_source = true;
@@ -443,14 +448,14 @@
ProduceMediaStreamTrackStatsFromVideoSenderInfo(
int64_t timestamp_us,
const VideoTrackInterface& video_track,
- const cricket::VideoSenderInfo& video_sender_info) {
+ const cricket::VideoSenderInfo& video_sender_info,
+ int attachment_id) {
std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats(
new RTCMediaStreamTrackStats(
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
+ RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
true, MediaStreamTrackInterface::kVideoKind, video_track.id(),
- video_sender_info.ssrc()),
- timestamp_us,
- RTCMediaStreamTrackKind::kVideo));
+ attachment_id),
+ timestamp_us, RTCMediaStreamTrackKind::kVideo));
SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
video_track, video_track_stats.get());
video_track_stats->remote_source = false;
@@ -469,14 +474,16 @@
ProduceMediaStreamTrackStatsFromVideoReceiverInfo(
int64_t timestamp_us,
const VideoTrackInterface& video_track,
- const cricket::VideoReceiverInfo& video_receiver_info) {
+ const cricket::VideoReceiverInfo& video_receiver_info,
+ int attachment_id) {
+ // Since receiver tracks can't be reattached, we use the SSRC as
+ // attachment ID.
std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats(
new RTCMediaStreamTrackStats(
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
+ RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
false, MediaStreamTrackInterface::kVideoKind, video_track.id(),
- video_receiver_info.ssrc()),
- timestamp_us,
- RTCMediaStreamTrackKind::kVideo));
+ attachment_id),
+ timestamp_us, RTCMediaStreamTrackKind::kVideo));
SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
video_track, video_track_stats.get());
video_track_stats->remote_source = true;
@@ -526,8 +533,8 @@
RTC_CHECK(voice_sender_info)
<< "No voice sender info for sender with ssrc " << sender->ssrc();
std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats =
- ProduceMediaStreamTrackStatsFromVoiceSenderInfo(timestamp_us, *track,
- *voice_sender_info);
+ ProduceMediaStreamTrackStatsFromVoiceSenderInfo(
+ timestamp_us, *track, *voice_sender_info, sender->AttachmentId());
report->AddStats(std::move(audio_track_stats));
} else if (sender->media_type() == cricket::MEDIA_TYPE_VIDEO) {
VideoTrackInterface* track =
@@ -539,8 +546,8 @@
RTC_CHECK(video_sender_info)
<< "No video sender info for sender with ssrc " << sender->ssrc();
std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats =
- ProduceMediaStreamTrackStatsFromVideoSenderInfo(timestamp_us, *track,
- *video_sender_info);
+ ProduceMediaStreamTrackStatsFromVideoSenderInfo(
+ timestamp_us, *track, *video_sender_info, sender->AttachmentId());
report->AddStats(std::move(video_track_stats));
} else {
RTC_NOTREACHED();
@@ -565,7 +572,8 @@
}
std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats =
ProduceMediaStreamTrackStatsFromVoiceReceiverInfo(
- timestamp_us, *track, *voice_receiver_info);
+ timestamp_us, *track, *voice_receiver_info,
+ receiver->AttachmentId());
report->AddStats(std::move(audio_track_stats));
} else if (receiver->media_type() == cricket::MEDIA_TYPE_VIDEO) {
VideoTrackInterface* track =
@@ -577,7 +585,8 @@
}
std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats =
ProduceMediaStreamTrackStatsFromVideoReceiverInfo(
- timestamp_us, *track, *video_receiver_info);
+ timestamp_us, *track, *video_receiver_info,
+ receiver->AttachmentId());
report->AddStats(std::move(video_track_stats));
} else {
RTC_NOTREACHED();
@@ -608,59 +617,37 @@
// TODO(hta): Revisit in conjunction with https://bugs.webrtc.org/8674
if (is_local) {
for (auto audio_track : stream->GetAudioTracks()) {
- auto sender_infos =
- track_media_info_map.GetVoiceSenderInfos(*audio_track);
- // There is no map entry on unconnected tracks.
- // https://bugs.webrtc.org/8673
- if (!sender_infos)
- continue;
- for (const auto& sender_info : *sender_infos) {
- // In the WebRTC implementation, SSRC 0 means unconnected,
- // and should not occur in the map.
- // https://bugs.webrtc.org/8694
- RTC_DCHECK_NE(0, sender_info->ssrc());
- stream_stats->track_ids->push_back(
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
- is_local, MediaStreamTrackInterface::kAudioKind,
- audio_track->id(), sender_info->ssrc()));
- }
+ stream_stats->track_ids->push_back(
+ RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
+ is_local, MediaStreamTrackInterface::kAudioKind,
+ audio_track->id(),
+ track_media_info_map.GetAttachmentIdByTrack(audio_track)
+ .value()));
}
for (auto video_track : stream->GetVideoTracks()) {
- auto sender_infos =
- track_media_info_map.GetVideoSenderInfos(*video_track);
- // There is no map entry on unconnected tracks.
- // https://bugs.webrtc.org/8673
- if (!sender_infos)
- continue;
- for (const auto& sender_info : *sender_infos) {
- // SSRC must not be zero. https://bugs.webrtc.org/8694
- RTC_DCHECK_NE(0, sender_info->ssrc());
- stream_stats->track_ids->push_back(
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
- is_local, MediaStreamTrackInterface::kVideoKind,
- video_track->id(), sender_info->ssrc()));
- }
+ stream_stats->track_ids->push_back(
+ RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
+ is_local, MediaStreamTrackInterface::kVideoKind,
+ video_track->id(),
+ track_media_info_map.GetAttachmentIdByTrack(video_track)
+ .value()));
}
} else {
for (auto audio_track : stream->GetAudioTracks()) {
- auto receiver_info =
- track_media_info_map.GetVoiceReceiverInfo(*audio_track);
- if (receiver_info) {
- stream_stats->track_ids->push_back(
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
- is_local, MediaStreamTrackInterface::kAudioKind,
- audio_track->id(), receiver_info->ssrc()));
- }
+ stream_stats->track_ids->push_back(
+ RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
+ is_local, MediaStreamTrackInterface::kAudioKind,
+ audio_track->id(),
+ track_media_info_map.GetAttachmentIdByTrack(audio_track)
+ .value()));
}
for (auto video_track : stream->GetVideoTracks()) {
- auto receiver_info =
- track_media_info_map.GetVideoReceiverInfo(*video_track);
- if (receiver_info) {
- stream_stats->track_ids->push_back(
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
- is_local, MediaStreamTrackInterface::kVideoKind,
- video_track->id(), receiver_info->ssrc()));
- }
+ stream_stats->track_ids->push_back(
+ RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
+ is_local, MediaStreamTrackInterface::kVideoKind,
+ video_track->id(),
+ track_media_info_map.GetAttachmentIdByTrack(video_track)
+ .value()));
}
}
report->AddStats(std::move(stream_stats));
@@ -1077,22 +1064,21 @@
if (voice_receiver_info.ssrc() == 0)
continue;
std::unique_ptr<RTCInboundRTPStreamStats> inbound_audio(
- new RTCInboundRTPStreamStats(
- RTCInboundRTPStreamStatsIDFromSSRC(
- true, voice_receiver_info.ssrc()),
- timestamp_us));
+ new RTCInboundRTPStreamStats(RTCInboundRTPStreamStatsIDFromSSRC(
+ true, voice_receiver_info.ssrc()),
+ timestamp_us));
SetInboundRTPStreamStatsFromVoiceReceiverInfo(
voice_receiver_info, inbound_audio.get());
+ // TODO(hta): This lookup should look for the sender, not the track.
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->track_id =
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
- false,
- MediaStreamTrackInterface::kAudioKind,
- track_to_id_.find(audio_track.get())->second,
- voice_receiver_info.ssrc());
+ inbound_audio
+ ->track_id = RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
+ false, MediaStreamTrackInterface::kAudioKind,
+ track_to_id_.find(audio_track.get())->second,
+ track_media_info_map_->GetAttachmentIdByTrack(audio_track).value());
}
inbound_audio->transport_id = transport_id;
report->AddStats(std::move(inbound_audio));
@@ -1115,12 +1101,11 @@
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->track_id =
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
- true,
- MediaStreamTrackInterface::kAudioKind,
- track_to_id_.find(audio_track.get())->second,
- voice_sender_info.ssrc());
+ outbound_audio
+ ->track_id = RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
+ true, MediaStreamTrackInterface::kAudioKind,
+ track_to_id_.find(audio_track.get())->second,
+ track_media_info_map.GetAttachmentIdByTrack(audio_track).value());
}
outbound_audio->transport_id = transport_id;
report->AddStats(std::move(outbound_audio));
@@ -1151,12 +1136,11 @@
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->track_id =
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
- false,
- MediaStreamTrackInterface::kVideoKind,
- track_to_id_.find(video_track.get())->second,
- video_receiver_info.ssrc());
+ inbound_video
+ ->track_id = RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
+ false, MediaStreamTrackInterface::kVideoKind,
+ track_to_id_.find(video_track.get())->second,
+ track_media_info_map_->GetAttachmentIdByTrack(video_track).value());
}
inbound_video->transport_id = transport_id;
report->AddStats(std::move(inbound_video));
@@ -1169,22 +1153,20 @@
if (video_sender_info.ssrc() == 0)
continue;
std::unique_ptr<RTCOutboundRTPStreamStats> outbound_video(
- new RTCOutboundRTPStreamStats(
- RTCOutboundRTPStreamStatsIDFromSSRC(
- false, video_sender_info.ssrc()),
- timestamp_us));
+ new RTCOutboundRTPStreamStats(RTCOutboundRTPStreamStatsIDFromSSRC(
+ false, video_sender_info.ssrc()),
+ 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->track_id =
- RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
- true,
- MediaStreamTrackInterface::kVideoKind,
- track_to_id_.find(video_track.get())->second,
- video_sender_info.ssrc());
+ outbound_video
+ ->track_id = RTCMediaStreamTrackStatsIDFromTrackKindIDAndAttachment(
+ true, MediaStreamTrackInterface::kVideoKind,
+ track_to_id_.find(video_track.get())->second,
+ track_media_info_map_->GetAttachmentIdByTrack(video_track).value());
}
outbound_video->transport_id = transport_id;
report->AddStats(std::move(outbound_video));
@@ -1310,6 +1292,9 @@
std::map<MediaStreamTrackInterface*, std::string>
RTCStatsCollector::PrepareTrackToID_s() const {
+ // TODO(hta): Remove this method, and vector its callers via
+ // senders / receivers instead.
+ // It ignores tracks that are multiply connected to the PC.
RTC_DCHECK(signaling_thread_->IsCurrent());
std::map<MediaStreamTrackInterface*, std::string> track_to_id;
for (auto sender : pc_->GetSenders()) {
diff --git a/pc/rtcstatscollector_unittest.cc b/pc/rtcstatscollector_unittest.cc
index 2149695..141a3cf 100644
--- a/pc/rtcstatscollector_unittest.cc
+++ b/pc/rtcstatscollector_unittest.cc
@@ -238,7 +238,8 @@
rtc::scoped_refptr<MockRtpSender> CreateMockSender(
const rtc::scoped_refptr<MediaStreamTrackInterface>& track,
- uint32_t ssrc) {
+ uint32_t ssrc,
+ int attachment_id) {
rtc::scoped_refptr<MockRtpSender> sender(
new rtc::RefCountedObject<MockRtpSender>());
EXPECT_CALL(*sender, track()).WillRepeatedly(Return(track));
@@ -253,12 +254,14 @@
params.encodings[0].ssrc = ssrc;
return params;
}));
+ EXPECT_CALL(*sender, AttachmentId()).WillRepeatedly(Return(attachment_id));
return sender;
}
rtc::scoped_refptr<MockRtpReceiver> CreateMockReceiver(
const rtc::scoped_refptr<MediaStreamTrackInterface>& track,
- uint32_t ssrc) {
+ uint32_t ssrc,
+ int attachment_id) {
rtc::scoped_refptr<MockRtpReceiver> receiver(
new rtc::RefCountedObject<MockRtpReceiver>());
EXPECT_CALL(*receiver, track()).WillRepeatedly(Return(track));
@@ -272,6 +275,7 @@
params.encodings[0].ssrc = ssrc;
return params;
}));
+ EXPECT_CALL(*receiver, AttachmentId()).WillRepeatedly(Return(attachment_id));
return receiver;
}
@@ -349,7 +353,8 @@
}
}
- rtc::scoped_refptr<MockRtpSender> sender = CreateMockSender(track, ssrc);
+ rtc::scoped_refptr<MockRtpSender> sender =
+ CreateMockSender(track, ssrc, 50);
EXPECT_CALL(pc_, GetSenders()).WillRepeatedly(Return(
std::vector<rtc::scoped_refptr<RtpSenderInterface>>({
rtc::scoped_refptr<RtpSenderInterface>(sender.get()) })));
@@ -379,7 +384,7 @@
}
rtc::scoped_refptr<MockRtpReceiver> receiver =
- CreateMockReceiver(track, ssrc);
+ CreateMockReceiver(track, ssrc, 62);
EXPECT_CALL(pc_, GetReceivers()).WillRepeatedly(Return(
std::vector<rtc::scoped_refptr<RtpReceiverInterface>>({
rtc::scoped_refptr<RtpReceiverInterface>(receiver.get()) })));
@@ -404,6 +409,7 @@
rtp_senders_.clear();
rtp_receivers_.clear();
// Local audio tracks and voice sender infos
+ int attachment_id = 147;
for (auto& pair : local_audio_track_info_pairs) {
MediaStreamTrackInterface* local_audio_track = pair.first;
const cricket::VoiceSenderInfo& voice_sender_info = pair.second;
@@ -411,14 +417,14 @@
MediaStreamTrackInterface::kAudioKind);
voice_media_info_->senders.push_back(voice_sender_info);
- rtc::scoped_refptr<MockRtpSender> rtp_sender =
- CreateMockSender(rtc::scoped_refptr<MediaStreamTrackInterface>(
- local_audio_track),
- voice_sender_info.local_stats[0].ssrc);
+ rtc::scoped_refptr<MockRtpSender> rtp_sender = CreateMockSender(
+ rtc::scoped_refptr<MediaStreamTrackInterface>(local_audio_track),
+ voice_sender_info.local_stats[0].ssrc, attachment_id++);
rtp_senders_.push_back(rtc::scoped_refptr<RtpSenderInterface>(
rtp_sender.get()));
}
// Remote audio tracks and voice receiver infos
+ attachment_id = 181;
for (auto& pair : remote_audio_track_info_pairs) {
MediaStreamTrackInterface* remote_audio_track = pair.first;
const cricket::VoiceReceiverInfo& voice_receiver_info = pair.second;
@@ -426,14 +432,14 @@
MediaStreamTrackInterface::kAudioKind);
voice_media_info_->receivers.push_back(voice_receiver_info);
- rtc::scoped_refptr<MockRtpReceiver> rtp_receiver =
- CreateMockReceiver(rtc::scoped_refptr<MediaStreamTrackInterface>(
- remote_audio_track),
- voice_receiver_info.local_stats[0].ssrc);
+ rtc::scoped_refptr<MockRtpReceiver> rtp_receiver = CreateMockReceiver(
+ rtc::scoped_refptr<MediaStreamTrackInterface>(remote_audio_track),
+ voice_receiver_info.local_stats[0].ssrc, attachment_id++);
rtp_receivers_.push_back(rtc::scoped_refptr<RtpReceiverInterface>(
rtp_receiver.get()));
}
// Local video tracks and video sender infos
+ attachment_id = 151;
for (auto& pair : local_video_track_info_pairs) {
MediaStreamTrackInterface* local_video_track = pair.first;
const cricket::VideoSenderInfo& video_sender_info = pair.second;
@@ -441,14 +447,14 @@
MediaStreamTrackInterface::kVideoKind);
video_media_info_->senders.push_back(video_sender_info);
- rtc::scoped_refptr<MockRtpSender> rtp_sender =
- CreateMockSender(rtc::scoped_refptr<MediaStreamTrackInterface>(
- local_video_track),
- video_sender_info.local_stats[0].ssrc);
+ rtc::scoped_refptr<MockRtpSender> rtp_sender = CreateMockSender(
+ rtc::scoped_refptr<MediaStreamTrackInterface>(local_video_track),
+ video_sender_info.local_stats[0].ssrc, attachment_id++);
rtp_senders_.push_back(rtc::scoped_refptr<RtpSenderInterface>(
rtp_sender.get()));
}
// Remote video tracks and video receiver infos
+ attachment_id = 191;
for (auto& pair : remote_video_track_info_pairs) {
MediaStreamTrackInterface* remote_video_track = pair.first;
const cricket::VideoReceiverInfo& video_receiver_info = pair.second;
@@ -456,10 +462,9 @@
MediaStreamTrackInterface::kVideoKind);
video_media_info_->receivers.push_back(video_receiver_info);
- rtc::scoped_refptr<MockRtpReceiver> rtp_receiver =
- CreateMockReceiver(rtc::scoped_refptr<MediaStreamTrackInterface>(
- remote_video_track),
- video_receiver_info.local_stats[0].ssrc);
+ rtc::scoped_refptr<MockRtpReceiver> rtp_receiver = CreateMockReceiver(
+ rtc::scoped_refptr<MediaStreamTrackInterface>(remote_video_track),
+ video_receiver_info.local_stats[0].ssrc, attachment_id++);
rtp_receivers_.push_back(rtc::scoped_refptr<RtpReceiverInterface>(
rtp_receiver.get()));
}
@@ -1524,15 +1529,6 @@
voice_sender_info_ssrc1.apm_statistics.echo_return_loss = 42.0;
voice_sender_info_ssrc1.apm_statistics.echo_return_loss_enhancement = 52.0;
- // Uses default values, the corresponding stats object should contain
- // undefined members.
- cricket::VoiceSenderInfo voice_sender_info_ssrc2;
- voice_sender_info_ssrc2.local_stats.push_back(cricket::SsrcSenderInfo());
- voice_sender_info_ssrc2.local_stats[0].ssrc = 2;
- voice_sender_info_ssrc2.audio_level = 0;
- voice_sender_info_ssrc2.total_input_energy = 0.0;
- voice_sender_info_ssrc2.total_input_duration = 0.0;
-
// Remote audio track
rtc::scoped_refptr<MediaStreamTrackInterface> remote_audio_track =
CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "RemoteAudioTrackID",
@@ -1552,10 +1548,8 @@
voice_receiver_info.jitter_buffer_delay_seconds = 3456;
test_->CreateMockRtpSendersReceiversAndChannels(
- { std::make_pair(local_audio_track.get(), voice_sender_info_ssrc1),
- std::make_pair(local_audio_track.get(), voice_sender_info_ssrc2) },
- { std::make_pair(remote_audio_track.get(), voice_receiver_info) },
- {}, {});
+ {std::make_pair(local_audio_track.get(), voice_sender_info_ssrc1)},
+ {std::make_pair(remote_audio_track.get(), voice_receiver_info)}, {}, {});
rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
@@ -1563,8 +1557,7 @@
"RTCMediaStream_local_LocalStreamLabel", report->timestamp_us());
expected_local_stream.stream_identifier = local_stream->label();
expected_local_stream.track_ids = std::vector<std::string>(
- { "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_1",
- "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_2" });
+ {"RTCMediaStreamTrack_local_audio_LocalAudioTrackID_147"});
ASSERT_TRUE(report->Get(expected_local_stream.id()));
EXPECT_EQ(expected_local_stream,
report->Get(expected_local_stream.id())->cast_to<
@@ -1573,15 +1566,17 @@
RTCMediaStreamStats expected_remote_stream(
"RTCMediaStream_remote_RemoteStreamLabel", report->timestamp_us());
expected_remote_stream.stream_identifier = remote_stream->label();
- expected_remote_stream.track_ids = std::vector<std::string>({
- "RTCMediaStreamTrack_remote_audio_RemoteAudioTrackID_3" });
+ expected_remote_stream.track_ids = std::vector<std::string>(
+ {"RTCMediaStreamTrack_remote_audio_RemoteAudioTrackID_181"});
ASSERT_TRUE(report->Get(expected_remote_stream.id()));
EXPECT_EQ(expected_remote_stream,
report->Get(expected_remote_stream.id())->cast_to<
RTCMediaStreamStats>());
+ // TODO(hta): Remove hardcoded stats IDs from the tests
+ // We should verify that they link properly rather than hardcoding them.
RTCMediaStreamTrackStats expected_local_audio_track_ssrc1(
- "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_1",
+ "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_147",
report->timestamp_us(), RTCMediaStreamTrackKind::kAudio);
expected_local_audio_track_ssrc1.track_identifier = local_audio_track->id();
expected_local_audio_track_ssrc1.remote_source = false;
@@ -1597,25 +1592,8 @@
report->Get(expected_local_audio_track_ssrc1.id())->cast_to<
RTCMediaStreamTrackStats>());
- RTCMediaStreamTrackStats expected_local_audio_track_ssrc2(
- "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_2",
- report->timestamp_us(), RTCMediaStreamTrackKind::kAudio);
- expected_local_audio_track_ssrc2.track_identifier = local_audio_track->id();
- expected_local_audio_track_ssrc2.remote_source = false;
- expected_local_audio_track_ssrc2.ended = true;
- expected_local_audio_track_ssrc2.detached = false;
- expected_local_audio_track_ssrc2.audio_level = 0.0;
- expected_local_audio_track_ssrc2.total_audio_energy = 0.0;
- expected_local_audio_track_ssrc2.total_samples_duration = 0.0;
- // Should be undefined: |expected_local_audio_track_ssrc2.echo_return_loss|
- // and |expected_local_audio_track_ssrc2.echo_return_loss_enhancement|.
- ASSERT_TRUE(report->Get(expected_local_audio_track_ssrc2.id()));
- EXPECT_EQ(expected_local_audio_track_ssrc2,
- report->Get(expected_local_audio_track_ssrc2.id())->cast_to<
- RTCMediaStreamTrackStats>());
-
RTCMediaStreamTrackStats expected_remote_audio_track(
- "RTCMediaStreamTrack_remote_audio_RemoteAudioTrackID_3",
+ "RTCMediaStreamTrack_remote_audio_RemoteAudioTrackID_181",
report->timestamp_us(), RTCMediaStreamTrackKind::kAudio);
expected_remote_audio_track.track_identifier = remote_audio_track->id();
expected_remote_audio_track.remote_source = true;
@@ -1666,13 +1644,6 @@
video_sender_info_ssrc1.send_frame_height = 4321;
video_sender_info_ssrc1.frames_encoded = 11;
- cricket::VideoSenderInfo video_sender_info_ssrc2;
- video_sender_info_ssrc2.local_stats.push_back(cricket::SsrcSenderInfo());
- video_sender_info_ssrc2.local_stats[0].ssrc = 2;
- video_sender_info_ssrc2.send_frame_width = 4321;
- video_sender_info_ssrc2.send_frame_height = 1234;
- video_sender_info_ssrc2.frames_encoded = 22;
-
// Remote video track with values
rtc::scoped_refptr<MediaStreamTrackInterface> remote_video_track_ssrc3 =
CreateFakeTrack(cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID3",
@@ -1689,39 +1660,19 @@
video_receiver_info_ssrc3.frames_decoded = 995;
video_receiver_info_ssrc3.frames_rendered = 990;
- // Remote video track with undefined (default) values
- rtc::scoped_refptr<MediaStreamTrackInterface> remote_video_track_ssrc4 =
- CreateFakeTrack(cricket::MEDIA_TYPE_VIDEO, "RemoteVideoTrackID4",
- MediaStreamTrackInterface::kLive);
- remote_stream->AddTrack(static_cast<VideoTrackInterface*>(
- remote_video_track_ssrc4.get()));
-
- cricket::VideoReceiverInfo video_receiver_info_ssrc4;
- video_receiver_info_ssrc4.local_stats.push_back(cricket::SsrcReceiverInfo());
- video_receiver_info_ssrc4.local_stats[0].ssrc = 4;
- video_receiver_info_ssrc4.frame_width = 0;
- video_receiver_info_ssrc4.frame_height = 0;
- video_receiver_info_ssrc4.frames_received = 0;
- video_receiver_info_ssrc4.frames_decoded = 0;
- video_receiver_info_ssrc4.frames_rendered = 0;
-
test_->CreateMockRtpSendersReceiversAndChannels(
{}, {},
- { std::make_pair(local_video_track.get(), video_sender_info_ssrc1),
- std::make_pair(local_video_track.get(), video_sender_info_ssrc2) },
- { std::make_pair(remote_video_track_ssrc3.get(),
- video_receiver_info_ssrc3),
- std::make_pair(remote_video_track_ssrc4.get(),
- video_receiver_info_ssrc4) });
+ {std::make_pair(local_video_track.get(), video_sender_info_ssrc1)},
+ {std::make_pair(remote_video_track_ssrc3.get(),
+ video_receiver_info_ssrc3)});
rtc::scoped_refptr<const RTCStatsReport> report = GetStatsReport();
RTCMediaStreamStats expected_local_stream(
"RTCMediaStream_local_LocalStreamLabel", report->timestamp_us());
expected_local_stream.stream_identifier = local_stream->label();
- expected_local_stream.track_ids = std::vector<std::string>({
- "RTCMediaStreamTrack_local_video_LocalVideoTrackID_1",
- "RTCMediaStreamTrack_local_video_LocalVideoTrackID_2" });
+ expected_local_stream.track_ids = std::vector<std::string>(
+ {"RTCMediaStreamTrack_local_video_LocalVideoTrackID_151"});
ASSERT_TRUE(report->Get(expected_local_stream.id()));
EXPECT_EQ(expected_local_stream,
report->Get(expected_local_stream.id())->cast_to<
@@ -1730,16 +1681,15 @@
RTCMediaStreamStats expected_remote_stream(
"RTCMediaStream_remote_RemoteStreamLabel", report->timestamp_us());
expected_remote_stream.stream_identifier = remote_stream->label();
- expected_remote_stream.track_ids = std::vector<std::string>({
- "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID3_3",
- "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID4_4" });
+ expected_remote_stream.track_ids = std::vector<std::string>(
+ {"RTCMediaStreamTrack_remote_video_RemoteVideoTrackID3_191"});
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_ssrc1(
- "RTCMediaStreamTrack_local_video_LocalVideoTrackID_1",
+ "RTCMediaStreamTrack_local_video_LocalVideoTrackID_151",
report->timestamp_us(), RTCMediaStreamTrackKind::kVideo);
expected_local_video_track_ssrc1.track_identifier = local_video_track->id();
expected_local_video_track_ssrc1.remote_source = false;
@@ -1753,23 +1703,8 @@
report->Get(expected_local_video_track_ssrc1.id())->cast_to<
RTCMediaStreamTrackStats>());
- RTCMediaStreamTrackStats expected_local_video_track_ssrc2(
- "RTCMediaStreamTrack_local_video_LocalVideoTrackID_2",
- report->timestamp_us(), RTCMediaStreamTrackKind::kVideo);
- expected_local_video_track_ssrc2.track_identifier = local_video_track->id();
- expected_local_video_track_ssrc2.remote_source = false;
- expected_local_video_track_ssrc2.ended = false;
- expected_local_video_track_ssrc2.detached = false;
- expected_local_video_track_ssrc2.frame_width = 4321;
- expected_local_video_track_ssrc2.frame_height = 1234;
- expected_local_video_track_ssrc2.frames_sent = 22;
- ASSERT_TRUE(report->Get(expected_local_video_track_ssrc2.id()));
- EXPECT_EQ(expected_local_video_track_ssrc2,
- report->Get(expected_local_video_track_ssrc2.id())->cast_to<
- RTCMediaStreamTrackStats>());
-
RTCMediaStreamTrackStats expected_remote_video_track_ssrc3(
- "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID3_3",
+ "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID3_191",
report->timestamp_us(), RTCMediaStreamTrackKind::kVideo);
expected_remote_video_track_ssrc3.track_identifier =
remote_video_track_ssrc3->id();
@@ -1785,24 +1720,6 @@
EXPECT_EQ(expected_remote_video_track_ssrc3,
report->Get(expected_remote_video_track_ssrc3.id())->cast_to<
RTCMediaStreamTrackStats>());
-
- RTCMediaStreamTrackStats expected_remote_video_track_ssrc4(
- "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID4_4",
- report->timestamp_us(), RTCMediaStreamTrackKind::kVideo);
- expected_remote_video_track_ssrc4.track_identifier =
- remote_video_track_ssrc4->id();
- expected_remote_video_track_ssrc4.remote_source = true;
- expected_remote_video_track_ssrc4.ended = false;
- expected_remote_video_track_ssrc4.detached = false;
- expected_remote_video_track_ssrc4.frames_received = 0;
- expected_remote_video_track_ssrc4.frames_decoded = 0;
- expected_remote_video_track_ssrc4.frames_dropped = 0;
- // Should be undefined: |expected_remote_video_track_ssrc4.frame_width| and
- // |expected_remote_video_track_ssrc4.frame_height|.
- ASSERT_TRUE(report->Get(expected_remote_video_track_ssrc4.id()));
- EXPECT_EQ(expected_remote_video_track_ssrc4,
- report->Get(expected_remote_video_track_ssrc4.id())->cast_to<
- RTCMediaStreamTrackStats>());
}
TEST_F(RTCStatsCollectorTest, CollectRTCInboundRTPStreamStats_Audio) {
@@ -1866,7 +1783,7 @@
expected_audio.is_remote = false;
expected_audio.media_type = "audio";
expected_audio.track_id =
- "RTCMediaStreamTrack_remote_audio_RemoteAudioTrackID_1";
+ "RTCMediaStreamTrack_remote_audio_RemoteAudioTrackID_62";
expected_audio.transport_id = "RTCTransport_TransportName_" +
rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
expected_audio.codec_id = "RTCCodec_InboundAudio_42";
@@ -1875,7 +1792,6 @@
expected_audio.packets_lost = -1;
expected_audio.jitter = 4.5;
expected_audio.fraction_lost = 5.5;
-
ASSERT_TRUE(report->Get(expected_audio.id()));
EXPECT_EQ(
report->Get(expected_audio.id())->cast_to<RTCInboundRTPStreamStats>(),
@@ -1949,7 +1865,7 @@
expected_video.is_remote = false;
expected_video.media_type = "video";
expected_video.track_id =
- "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID_1";
+ "RTCMediaStreamTrack_remote_video_RemoteVideoTrackID_62";
expected_video.transport_id = "RTCTransport_TransportName_" +
rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
expected_video.codec_id = "RTCCodec_InboundVideo_42";
@@ -2043,7 +1959,7 @@
expected_audio.is_remote = false;
expected_audio.media_type = "audio";
expected_audio.track_id =
- "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_1";
+ "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_50";
expected_audio.transport_id = "RTCTransport_TransportName_" +
rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
expected_audio.codec_id = "RTCCodec_OutboundAudio_42";
@@ -2125,7 +2041,7 @@
expected_video.is_remote = false;
expected_video.media_type = "video";
expected_video.track_id =
- "RTCMediaStreamTrack_local_video_LocalVideoTrackID_1";
+ "RTCMediaStreamTrack_local_video_LocalVideoTrackID_50";
expected_video.transport_id = "RTCTransport_TransportName_" +
rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
expected_video.codec_id = "RTCCodec_OutboundVideo_42";
@@ -2381,7 +2297,7 @@
expected_audio.is_remote = false;
expected_audio.media_type = "audio";
expected_audio.track_id =
- "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_1";
+ "RTCMediaStreamTrack_local_audio_LocalAudioTrackID_50";
expected_audio.transport_id =
"RTCTransport_TransportName_" +
rtc::ToString<>(cricket::ICE_CANDIDATE_COMPONENT_RTP);
@@ -2410,7 +2326,7 @@
rtc::scoped_refptr<MediaStreamTrackInterface> track =
CreateFakeTrack(cricket::MEDIA_TYPE_AUDIO, "audioTrack",
MediaStreamTrackInterface::kLive);
- rtc::scoped_refptr<MockRtpSender> sender = CreateMockSender(track, 0);
+ rtc::scoped_refptr<MockRtpSender> sender = CreateMockSender(track, 0, 49);
EXPECT_CALL(test_->pc(), GetSenders())
.WillRepeatedly(
Return(std::vector<rtc::scoped_refptr<RtpSenderInterface>>(
diff --git a/pc/rtpreceiver.cc b/pc/rtpreceiver.cc
index 98c501c..e318c17 100644
--- a/pc/rtpreceiver.cc
+++ b/pc/rtpreceiver.cc
@@ -21,6 +21,17 @@
namespace webrtc {
+namespace {
+
+// This function is only expected to be called on the signalling thread.
+int GenerateUniqueId() {
+ static int g_unique_id = 0;
+
+ return ++g_unique_id;
+}
+
+} // namespace
+
AudioRtpReceiver::AudioRtpReceiver(
rtc::Thread* worker_thread,
const std::string& receiver_id,
@@ -35,7 +46,8 @@
AudioTrack::Create(
receiver_id,
RemoteAudioSource::Create(worker_thread, media_channel, ssrc)))),
- cached_track_enabled_(track_->enabled()) {
+ cached_track_enabled_(track_->enabled()),
+ attachment_id_(GenerateUniqueId()) {
RTC_DCHECK(worker_thread_);
RTC_DCHECK(track_->GetSource()->remote());
track_->RegisterObserver(this);
@@ -207,7 +219,8 @@
VideoTrackSourceProxy::Create(rtc::Thread::Current(),
worker_thread,
source_),
- worker_thread))) {
+ worker_thread))),
+ attachment_id_(GenerateUniqueId()) {
RTC_DCHECK(worker_thread_);
SetStreams(streams);
source_->SetState(MediaSourceInterface::kLive);
diff --git a/pc/rtpreceiver.h b/pc/rtpreceiver.h
index e3848a7..82c3134 100644
--- a/pc/rtpreceiver.h
+++ b/pc/rtpreceiver.h
@@ -107,6 +107,7 @@
void SetMediaChannel(cricket::VoiceMediaChannel* media_channel);
std::vector<RtpSource> GetSources() const override;
+ int AttachmentId() const override { return attachment_id_; }
private:
void Reconfigure();
@@ -123,6 +124,7 @@
bool stopped_ = false;
RtpReceiverObserverInterface* observer_ = nullptr;
bool received_first_packet_ = false;
+ int attachment_id_ = 0;
};
class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInternal> {
@@ -192,6 +194,7 @@
bool stopped_ = false;
RtpReceiverObserverInterface* observer_ = nullptr;
bool received_first_packet_ = false;
+ int attachment_id_ = 0;
};
} // namespace webrtc
diff --git a/pc/rtpsender.cc b/pc/rtpsender.cc
index 91e84d7..cad86f2 100644
--- a/pc/rtpsender.cc
+++ b/pc/rtpsender.cc
@@ -20,6 +20,17 @@
namespace webrtc {
+namespace {
+
+// This function is only expected to be called on the signalling thread.
+int GenerateUniqueId() {
+ static int g_unique_id = 0;
+
+ return ++g_unique_id;
+}
+
+} // namespace
+
LocalAudioSinkAdapter::LocalAudioSinkAdapter() : sink_(nullptr) {}
LocalAudioSinkAdapter::~LocalAudioSinkAdapter() {
@@ -60,7 +71,8 @@
rtc::Thread::Current(),
DtmfSender::Create(track_, rtc::Thread::Current(), this))),
cached_track_enabled_(track ? track->enabled() : false),
- sink_adapter_(new LocalAudioSinkAdapter()) {
+ sink_adapter_(new LocalAudioSinkAdapter()),
+ attachment_id_(track ? GenerateUniqueId() : 0) {
// TODO(bugs.webrtc.org/7932): Remove once zero or multiple streams are
// supported.
RTC_DCHECK_EQ(stream_labels.size(), 1u);
@@ -165,6 +177,7 @@
} else if (prev_can_send_track) {
ClearAudioSend();
}
+ attachment_id_ = GenerateUniqueId();
return true;
}
@@ -276,9 +289,10 @@
stream_ids_(stream_labels),
track_(track),
cached_track_enabled_(track ? track->enabled() : false),
- cached_track_content_hint_(
- track ? track->content_hint()
- : VideoTrackInterface::ContentHint::kNone) {
+ cached_track_content_hint_(track
+ ? track->content_hint()
+ : VideoTrackInterface::ContentHint::kNone),
+ attachment_id_(track ? GenerateUniqueId() : 0) {
// TODO(bugs.webrtc.org/7932): Remove once zero or multiple streams are
// supported.
RTC_DCHECK_EQ(stream_labels.size(), 1u);
@@ -340,6 +354,7 @@
} else if (prev_can_send_track) {
ClearVideoSend();
}
+ attachment_id_ = GenerateUniqueId();
return true;
}
diff --git a/pc/rtpsender.h b/pc/rtpsender.h
index a0c759a..eb09d0b 100644
--- a/pc/rtpsender.h
+++ b/pc/rtpsender.h
@@ -137,6 +137,8 @@
void Stop() override;
+ int AttachmentId() const override { return attachment_id_; }
+
// Does not take ownership.
// Should call SetChannel(nullptr) before |channel| is destroyed.
void SetChannel(cricket::VoiceChannel* channel) { channel_ = channel; }
@@ -168,6 +170,7 @@
// Used to pass the data callback from the |track_| to the other end of
// cricket::AudioSource.
std::unique_ptr<LocalAudioSinkAdapter> sink_adapter_;
+ int attachment_id_ = 0;
};
class VideoRtpSender : public ObserverInterface,
@@ -220,6 +223,7 @@
}
void Stop() override;
+ int AttachmentId() const override { return attachment_id_; }
// Does not take ownership.
// Should call SetChannel(nullptr) before |channel| is destroyed.
@@ -244,6 +248,7 @@
VideoTrackInterface::ContentHint cached_track_content_hint_ =
VideoTrackInterface::ContentHint::kNone;
bool stopped_ = false;
+ int attachment_id_ = 0;
};
} // namespace webrtc
diff --git a/pc/trackmediainfomap.cc b/pc/trackmediainfomap.cc
index 3fbe3fa..36e4eb3 100644
--- a/pc/trackmediainfomap.cc
+++ b/pc/trackmediainfomap.cc
@@ -125,6 +125,14 @@
&local_video_track_by_ssrc, &remote_audio_track_by_ssrc,
&remote_video_track_by_ssrc, &unsignaled_audio_track,
&unsignaled_video_track);
+
+ for (auto& sender : rtp_senders) {
+ attachment_id_by_track_[sender->track()] = sender->AttachmentId();
+ }
+ for (auto& receiver : rtp_receivers) {
+ attachment_id_by_track_[receiver->track()] = receiver->AttachmentId();
+ }
+
if (voice_media_info_) {
for (auto& sender_info : voice_media_info_->senders) {
AudioTrackInterface* associated_track =
@@ -258,4 +266,11 @@
return FindValueOrNull(video_track_by_receiver_info_, &video_receiver_info);
}
+rtc::Optional<int> TrackMediaInfoMap::GetAttachmentIdByTrack(
+ const MediaStreamTrackInterface* track) const {
+ auto it = attachment_id_by_track_.find(track);
+ return it != attachment_id_by_track_.end() ? rtc::Optional<int>(it->second)
+ : rtc::nullopt;
+}
+
} // namespace webrtc
diff --git a/pc/trackmediainfomap.h b/pc/trackmediainfomap.h
index fd9a98e..c427c47 100644
--- a/pc/trackmediainfomap.h
+++ b/pc/trackmediainfomap.h
@@ -74,6 +74,13 @@
rtc::scoped_refptr<VideoTrackInterface> GetVideoTrack(
const cricket::VideoReceiverInfo& video_receiver_info) const;
+ // TODO(hta): Remove this function, and redesign the callers not to need it.
+ // It is not going to work if a track is attached multiple times, and
+ // it is not going to work if a received track is attached as a sending
+ // track (loopback).
+ rtc::Optional<int> GetAttachmentIdByTrack(
+ const MediaStreamTrackInterface* track) const;
+
private:
std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info_;
std::unique_ptr<cricket::VideoMediaInfo> video_media_info_;
@@ -102,6 +109,12 @@
std::map<const cricket::VideoReceiverInfo*,
rtc::scoped_refptr<VideoTrackInterface>>
video_track_by_receiver_info_;
+ // Map of tracks to attachment IDs.
+ // Necessary because senders and receivers live on the signaling thread,
+ // but the attachment IDs are needed while building stats on the networking
+ // thread, so we can't look them up in the senders/receivers without
+ // thread jumping.
+ std::map<const MediaStreamTrackInterface*, int> attachment_id_by_track_;
// These maps map SSRCs to the corresponding voice or video info objects.
std::map<uint32_t, cricket::VoiceSenderInfo*> voice_info_by_sender_ssrc_;
std::map<uint32_t, cricket::VoiceReceiverInfo*> voice_info_by_receiver_ssrc_;
diff --git a/pc/trackmediainfomap_unittest.cc b/pc/trackmediainfomap_unittest.cc
index c05abe1..583aa89 100644
--- a/pc/trackmediainfomap_unittest.cc
+++ b/pc/trackmediainfomap_unittest.cc
@@ -60,6 +60,7 @@
.WillRepeatedly(testing::Return(media_type));
EXPECT_CALL(*sender, GetParameters())
.WillRepeatedly(testing::Return(CreateRtpParametersWithSsrcs(ssrcs)));
+ EXPECT_CALL(*sender, AttachmentId()).WillRepeatedly(testing::Return(1));
return sender;
}
@@ -75,6 +76,7 @@
.WillRepeatedly(testing::Return(media_type));
EXPECT_CALL(*receiver, GetParameters())
.WillRepeatedly(testing::Return(CreateRtpParametersWithSsrcs(ssrcs)));
+ EXPECT_CALL(*receiver, AttachmentId()).WillRepeatedly(testing::Return(1));
return receiver;
}
@@ -400,6 +402,14 @@
EXPECT_FALSE(map_->GetVoiceSenderInfoBySsrc(1024));
}
+TEST_F(TrackMediaInfoMapTest, GetAttachmentIdByTrack) {
+ AddRtpSenderWithSsrcs({1}, local_audio_track_);
+ CreateMap();
+ EXPECT_EQ(rtp_senders_[0]->AttachmentId(),
+ map_->GetAttachmentIdByTrack(local_audio_track_));
+ EXPECT_EQ(rtc::nullopt, map_->GetAttachmentIdByTrack(local_video_track_));
+}
+
// Death tests.
// Disabled on Android because death tests misbehave on Android, see
// base/test/gtest_util.h.