Get VideoCapturer stats via VideoTrackSourceInterface in StatsCollector,
without involving the VideoMediaChannel.
BUG=webrtc:5426
Review URL: https://codereview.webrtc.org/1827023002
Cr-Commit-Position: refs/heads/master@{#12193}
diff --git a/webrtc/api/mediastreaminterface.h b/webrtc/api/mediastreaminterface.h
index 349fcc0..f1730c5 100644
--- a/webrtc/api/mediastreaminterface.h
+++ b/webrtc/api/mediastreaminterface.h
@@ -88,6 +88,10 @@
static const char kAudioKind[];
static const char kVideoKind[];
+ // The kind() method must return kAudioKind only if the object is a
+ // subclass of AudioTrackInterface, and kVideoKind only if the
+ // object is a subclass of VideoTrackInterface. It is typically used
+ // to protect a static_cast<> to the corresponding subclass.
virtual std::string kind() const = 0;
virtual std::string id() const = 0;
virtual bool enabled() const = 0;
@@ -106,6 +110,11 @@
: public MediaSourceInterface,
public rtc::VideoSourceInterface<cricket::VideoFrame> {
public:
+ struct Stats {
+ // Original size of captured frame, before video adaptation.
+ int input_width;
+ int input_height;
+ };
// Get access to the source implementation of cricket::VideoCapturer.
// This can be used for receiving frames and state notifications.
// But it should not be used for starting or stopping capturing.
@@ -132,6 +141,11 @@
// the encoder.
virtual rtc::Optional<bool> needs_denoising() const = 0;
+ // Returns false if no stats are available, e.g, for a remote
+ // source, or a source which has not seen its first frame yet.
+ // Should avoid blocking.
+ virtual bool GetStats(Stats* stats) = 0;
+
protected:
virtual ~VideoTrackSourceInterface() {}
};
diff --git a/webrtc/api/rtpsender.h b/webrtc/api/rtpsender.h
index 879a332..3919e07 100644
--- a/webrtc/api/rtpsender.h
+++ b/webrtc/api/rtpsender.h
@@ -101,6 +101,8 @@
bool SetParameters(const RtpParameters& parameters);
private:
+ // TODO(nisse): Since SSRC == 0 is technically valid, figure out
+ // some other way to test if we have a valid SSRC.
bool can_send_track() const { return track_ && ssrc_; }
// Helper function to construct options for
// AudioProviderInterface::SetAudioSend.
diff --git a/webrtc/api/statscollector.cc b/webrtc/api/statscollector.cc
index d77953b..0182a37 100644
--- a/webrtc/api/statscollector.cc
+++ b/webrtc/api/statscollector.cc
@@ -236,11 +236,9 @@
{ StatsReport::kStatsValueNameEncodeUsagePercent,
info.encode_usage_percent },
{ StatsReport::kStatsValueNameFirsReceived, info.firs_rcvd },
- { StatsReport::kStatsValueNameFrameHeightInput, info.input_frame_height },
{ StatsReport::kStatsValueNameFrameHeightSent, info.send_frame_height },
{ StatsReport::kStatsValueNameFrameRateInput, info.framerate_input },
{ StatsReport::kStatsValueNameFrameRateSent, info.framerate_sent },
- { StatsReport::kStatsValueNameFrameWidthInput, info.input_frame_width },
{ StatsReport::kStatsValueNameFrameWidthSent, info.send_frame_width },
{ StatsReport::kStatsValueNameNacksReceived, info.nacks_rcvd },
{ StatsReport::kStatsValueNamePacketsLost, info.packets_lost },
@@ -474,6 +472,7 @@
ExtractSessionInfo();
ExtractVoiceInfo();
ExtractVideoInfo(level);
+ ExtractSenderInfo();
ExtractDataInfo();
UpdateTrackReports();
}
@@ -828,6 +827,39 @@
}
}
+void StatsCollector::ExtractSenderInfo() {
+ RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent());
+
+ for (const auto& sender : pc_->GetSenders()) {
+ // TODO(nisse): SSRC == 0 currently means none. Delete check when
+ // that is fixed.
+ if (!sender->ssrc()) {
+ continue;
+ }
+ const rtc::scoped_refptr<MediaStreamTrackInterface> track(sender->track());
+ if (!track || track->kind() != MediaStreamTrackInterface::kVideoKind) {
+ continue;
+ }
+ // Safe, because kind() == kVideoKind implies a subclass of
+ // VideoTrackInterface; see mediastreaminterface.h.
+ VideoTrackSourceInterface* source =
+ static_cast<VideoTrackInterface*>(track.get())->GetSource();
+
+ VideoTrackSourceInterface::Stats stats;
+ if (!source->GetStats(&stats)) {
+ continue;
+ }
+ const StatsReport::Id stats_id = StatsReport::NewIdWithDirection(
+ StatsReport::kStatsReportTypeSsrc,
+ rtc::ToString<uint32_t>(sender->ssrc()), StatsReport::kSend);
+ StatsReport* report = reports_.FindOrAddNew(stats_id);
+ report->AddInt(StatsReport::kStatsValueNameFrameWidthInput,
+ stats.input_width);
+ report->AddInt(StatsReport::kStatsValueNameFrameHeightInput,
+ stats.input_height);
+ }
+}
+
void StatsCollector::ExtractDataInfo() {
RTC_DCHECK(pc_->session()->signaling_thread()->IsCurrent());
diff --git a/webrtc/api/statscollector.h b/webrtc/api/statscollector.h
index 3757279..8c359e4 100644
--- a/webrtc/api/statscollector.h
+++ b/webrtc/api/statscollector.h
@@ -113,6 +113,7 @@
void ExtractSessionInfo();
void ExtractVoiceInfo();
void ExtractVideoInfo(PeerConnectionInterface::StatsOutputLevel level);
+ void ExtractSenderInfo();
void BuildSsrcToTransportId();
webrtc::StatsReport* GetReport(const StatsReport::StatsType& type,
const std::string& id,
diff --git a/webrtc/api/videocapturertracksource.cc b/webrtc/api/videocapturertracksource.cc
index 0543dff..cb53961 100644
--- a/webrtc/api/videocapturertracksource.cc
+++ b/webrtc/api/videocapturertracksource.cc
@@ -360,6 +360,11 @@
// Initialize hasn't succeeded until a successful state change has occurred.
}
+bool VideoCapturerTrackSource::GetStats(Stats* stats) {
+ return video_capturer_->GetInputSize(&stats->input_width,
+ &stats->input_height);
+}
+
void VideoCapturerTrackSource::Stop() {
if (!started_) {
return;
diff --git a/webrtc/api/videocapturertracksource.h b/webrtc/api/videocapturertracksource.h
index 3673bf7..0d1142d 100644
--- a/webrtc/api/videocapturertracksource.h
+++ b/webrtc/api/videocapturertracksource.h
@@ -58,6 +58,8 @@
return needs_denoising_;
}
+ bool GetStats(Stats* stats) override;
+
void Stop() override;
void Restart() override;
diff --git a/webrtc/api/videosourceproxy.h b/webrtc/api/videosourceproxy.h
index fa6c428..f43c0db 100644
--- a/webrtc/api/videosourceproxy.h
+++ b/webrtc/api/videosourceproxy.h
@@ -28,6 +28,7 @@
PROXY_METHOD0(void, Restart)
PROXY_CONSTMETHOD0(bool, is_screencast)
PROXY_CONSTMETHOD0(rtc::Optional<bool>, needs_denoising)
+PROXY_METHOD1(bool, GetStats, Stats*)
PROXY_METHOD2(void,
AddOrUpdateSink,
rtc::VideoSinkInterface<cricket::VideoFrame>*,
diff --git a/webrtc/api/videotracksource.h b/webrtc/api/videotracksource.h
index 6d23d2e..108209d 100644
--- a/webrtc/api/videotracksource.h
+++ b/webrtc/api/videotracksource.h
@@ -40,6 +40,8 @@
virtual rtc::Optional<bool> needs_denoising() const {
return rtc::Optional<bool>(); }
+ bool GetStats(Stats* stats) override { return false; }
+
void AddOrUpdateSink(rtc::VideoSinkInterface<cricket::VideoFrame>* sink,
const rtc::VideoSinkWants& wants) override;
void RemoveSink(rtc::VideoSinkInterface<cricket::VideoFrame>* sink) override;