Add resolution and fps stats to histograms:
- "WebRTC.Video.InputWidthInPixels" - "WebRTC.Video.InputHeightInPixels" - "WebRTC.Video.SentWidthInPixels" - "WebRTC.Video.SentHeightInPixels" - "WebRTC.Video.ReceivedWidthInPixels" - "WebRTC.Video.ReceivedHeightInPixels" - "WebRTC.Video.RenderFramesPerSecond" BUG=chromium:512752 Review URL: https://codereview.webrtc.org/1228393008 Cr-Commit-Position: refs/heads/master@{#9611}
This commit is contained in:
parent
65eb1c3df9
commit
d89920b74a
@ -97,6 +97,8 @@ int32_t FakeEncoder::Encode(const VideoFrame& input_image,
|
||||
encoded._timeStamp = input_image.timestamp();
|
||||
encoded.capture_time_ms_ = input_image.render_time_ms();
|
||||
encoded._frameType = (*frame_types)[i];
|
||||
encoded._encodedWidth = config_.simulcastStream[i].width;
|
||||
encoded._encodedHeight = config_.simulcastStream[i].height;
|
||||
// Always encode something on the first frame.
|
||||
if (min_stream_bits > bits_available && i > 0) {
|
||||
encoded._length = 0;
|
||||
|
||||
@ -1634,10 +1634,32 @@ void EndToEndTest::VerifyHistogramStats(bool use_rtx, bool use_red) {
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.ReceivedPacketsLostInPercent"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputWidthInPixels"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputHeightInPixels"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SentWidthInPixels"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SentHeightInPixels"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.ReceivedWidthInPixels"));
|
||||
EXPECT_EQ(1,
|
||||
test::NumHistogramSamples("WebRTC.Video.ReceivedHeightInPixels"));
|
||||
|
||||
EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].width),
|
||||
test::LastHistogramSample("WebRTC.Video.InputWidthInPixels"));
|
||||
EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].height),
|
||||
test::LastHistogramSample("WebRTC.Video.InputHeightInPixels"));
|
||||
EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].width),
|
||||
test::LastHistogramSample("WebRTC.Video.SentWidthInPixels"));
|
||||
EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].height),
|
||||
test::LastHistogramSample("WebRTC.Video.SentHeightInPixels"));
|
||||
EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].width),
|
||||
test::LastHistogramSample("WebRTC.Video.ReceivedWidthInPixels"));
|
||||
EXPECT_EQ(static_cast<int>(encoder_config_.streams[0].height),
|
||||
test::LastHistogramSample("WebRTC.Video.ReceivedHeightInPixels"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.InputFramesPerSecond"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.SentFramesPerSecond"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.DecodedFramesPerSecond"));
|
||||
EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.RenderFramesPerSecond"));
|
||||
|
||||
EXPECT_EQ(1, test::NumHistogramSamples(
|
||||
"WebRTC.Video.BitrateSentInKbps"));
|
||||
|
||||
@ -28,16 +28,24 @@ ReceiveStatisticsProxy::~ReceiveStatisticsProxy() {
|
||||
UpdateHistograms();
|
||||
}
|
||||
|
||||
void ReceiveStatisticsProxy::UpdateHistograms() const {
|
||||
int fraction_lost;
|
||||
{
|
||||
rtc::CritScope lock(&crit_);
|
||||
fraction_lost = report_block_stats_.FractionLostInPercent();
|
||||
}
|
||||
void ReceiveStatisticsProxy::UpdateHistograms() {
|
||||
int fraction_lost = report_block_stats_.FractionLostInPercent();
|
||||
if (fraction_lost != -1) {
|
||||
RTC_HISTOGRAM_PERCENTAGE("WebRTC.Video.ReceivedPacketsLostInPercent",
|
||||
fraction_lost);
|
||||
}
|
||||
|
||||
int render_fps = static_cast<int>(render_fps_tracker_total_.units_second());
|
||||
if (render_fps > 0)
|
||||
RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.RenderFramesPerSecond", render_fps);
|
||||
|
||||
const int kMinRequiredSamples = 100;
|
||||
int width = render_width_counter_.Avg(kMinRequiredSamples);
|
||||
int height = render_height_counter_.Avg(kMinRequiredSamples);
|
||||
if (width != -1) {
|
||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedWidthInPixels", width);
|
||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.ReceivedHeightInPixels", height);
|
||||
}
|
||||
}
|
||||
|
||||
VideoReceiveStream::Stats ReceiveStatisticsProxy::GetStats() const {
|
||||
@ -117,12 +125,15 @@ void ReceiveStatisticsProxy::OnDecodedFrame() {
|
||||
stats_.decode_frame_rate = decode_fps_estimator_.Rate(now);
|
||||
}
|
||||
|
||||
void ReceiveStatisticsProxy::OnRenderedFrame() {
|
||||
void ReceiveStatisticsProxy::OnRenderedFrame(int width, int height) {
|
||||
uint64_t now = clock_->TimeInMilliseconds();
|
||||
|
||||
rtc::CritScope lock(&crit_);
|
||||
renders_fps_estimator_.Update(1, now);
|
||||
stats_.render_frame_rate = renders_fps_estimator_.Rate(now);
|
||||
render_width_counter_.Add(width);
|
||||
render_height_counter_.Add(height);
|
||||
render_fps_tracker_total_.Update(1);
|
||||
}
|
||||
|
||||
void ReceiveStatisticsProxy::OnReceiveRatesUpdated(uint32_t bitRate,
|
||||
@ -140,4 +151,15 @@ void ReceiveStatisticsProxy::OnDiscardedPacketsUpdated(int discarded_packets) {
|
||||
stats_.discarded_packets = discarded_packets;
|
||||
}
|
||||
|
||||
void ReceiveStatisticsProxy::SampleCounter::Add(int sample) {
|
||||
sum += sample;
|
||||
++num_samples;
|
||||
}
|
||||
|
||||
int ReceiveStatisticsProxy::SampleCounter::Avg(int min_required_samples) const {
|
||||
if (num_samples < min_required_samples || num_samples == 0)
|
||||
return -1;
|
||||
return sum / num_samples;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include <string>
|
||||
|
||||
#include "webrtc/base/criticalsection.h"
|
||||
#include "webrtc/base/ratetracker.h"
|
||||
#include "webrtc/base/thread_annotations.h"
|
||||
#include "webrtc/common_types.h"
|
||||
#include "webrtc/frame_callback.h"
|
||||
@ -42,9 +43,9 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver,
|
||||
VideoReceiveStream::Stats GetStats() const;
|
||||
|
||||
void OnDecodedFrame();
|
||||
void OnRenderedFrame();
|
||||
void OnRenderedFrame(int width, int height);
|
||||
|
||||
// Overrides VCMReceiveStatisticsCallback
|
||||
// Overrides VCMReceiveStatisticsCallback.
|
||||
void OnReceiveRatesUpdated(uint32_t bitRate, uint32_t frameRate) override;
|
||||
void OnFrameCountsUpdated(const FrameCounts& frame_counts) override;
|
||||
void OnDiscardedPacketsUpdated(int discarded_packets) override;
|
||||
@ -68,7 +69,7 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver,
|
||||
uint32_t ssrc) override;
|
||||
void CNameChanged(const char* cname, uint32_t ssrc) override;
|
||||
|
||||
// Overrides RtcpPacketTypeCounterObserver
|
||||
// Overrides RtcpPacketTypeCounterObserver.
|
||||
void RtcpPacketTypesCounterUpdated(
|
||||
uint32_t ssrc,
|
||||
const RtcpPacketTypeCounter& packet_counter) override;
|
||||
@ -77,13 +78,27 @@ class ReceiveStatisticsProxy : public ViEDecoderObserver,
|
||||
uint32_t ssrc) override;
|
||||
|
||||
private:
|
||||
void UpdateHistograms() const;
|
||||
struct SampleCounter {
|
||||
SampleCounter() : sum(0), num_samples(0) {}
|
||||
void Add(int sample);
|
||||
int Avg(int min_required_samples) const;
|
||||
|
||||
private:
|
||||
int sum;
|
||||
int num_samples;
|
||||
};
|
||||
|
||||
void UpdateHistograms() EXCLUSIVE_LOCKS_REQUIRED(crit_);
|
||||
|
||||
Clock* const clock_;
|
||||
|
||||
mutable rtc::CriticalSection crit_;
|
||||
VideoReceiveStream::Stats stats_ GUARDED_BY(crit_);
|
||||
RateStatistics decode_fps_estimator_ GUARDED_BY(crit_);
|
||||
RateStatistics renders_fps_estimator_ GUARDED_BY(crit_);
|
||||
rtc::RateTracker render_fps_tracker_total_ GUARDED_BY(crit_);
|
||||
SampleCounter render_width_counter_ GUARDED_BY(crit_);
|
||||
SampleCounter render_height_counter_ GUARDED_BY(crit_);
|
||||
ReportBlockStats report_block_stats_ GUARDED_BY(crit_);
|
||||
};
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
|
||||
#include "webrtc/video/send_statistics_proxy.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
#include "webrtc/base/checks.h"
|
||||
@ -24,7 +25,11 @@ const int SendStatisticsProxy::kStatsTimeoutMs = 5000;
|
||||
|
||||
SendStatisticsProxy::SendStatisticsProxy(Clock* clock,
|
||||
const VideoSendStream::Config& config)
|
||||
: clock_(clock), config_(config), last_sent_frame_timestamp_(0) {
|
||||
: clock_(clock),
|
||||
config_(config),
|
||||
last_sent_frame_timestamp_(0),
|
||||
max_sent_width_per_timestamp_(0),
|
||||
max_sent_height_per_timestamp_(0) {
|
||||
}
|
||||
|
||||
SendStatisticsProxy::~SendStatisticsProxy() {
|
||||
@ -34,13 +39,26 @@ SendStatisticsProxy::~SendStatisticsProxy() {
|
||||
void SendStatisticsProxy::UpdateHistograms() {
|
||||
int input_fps =
|
||||
static_cast<int>(input_frame_rate_tracker_total_.units_second());
|
||||
int sent_fps =
|
||||
static_cast<int>(sent_frame_rate_tracker_total_.units_second());
|
||||
|
||||
if (input_fps > 0)
|
||||
RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.InputFramesPerSecond", input_fps);
|
||||
int sent_fps =
|
||||
static_cast<int>(sent_frame_rate_tracker_total_.units_second());
|
||||
if (sent_fps > 0)
|
||||
RTC_HISTOGRAM_COUNTS_100("WebRTC.Video.SentFramesPerSecond", sent_fps);
|
||||
|
||||
const int kMinRequiredSamples = 100;
|
||||
int in_width = input_width_counter_.Avg(kMinRequiredSamples);
|
||||
int in_height = input_height_counter_.Avg(kMinRequiredSamples);
|
||||
if (in_width != -1) {
|
||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InputWidthInPixels", in_width);
|
||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.InputHeightInPixels", in_height);
|
||||
}
|
||||
int sent_width = sent_width_counter_.Avg(kMinRequiredSamples);
|
||||
int sent_height = sent_height_counter_.Avg(kMinRequiredSamples);
|
||||
if (sent_width != -1) {
|
||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SentWidthInPixels", sent_width);
|
||||
RTC_HISTOGRAM_COUNTS_10000("WebRTC.Video.SentHeightInPixels", sent_height);
|
||||
}
|
||||
}
|
||||
|
||||
void SendStatisticsProxy::OutgoingRate(const int video_channel,
|
||||
@ -139,16 +157,33 @@ void SendStatisticsProxy::OnSendEncodedImage(
|
||||
stats->width = encoded_image._encodedWidth;
|
||||
stats->height = encoded_image._encodedHeight;
|
||||
update_times_[ssrc].resolution_update_ms = clock_->TimeInMilliseconds();
|
||||
if (encoded_image._timeStamp != last_sent_frame_timestamp_) {
|
||||
last_sent_frame_timestamp_ = encoded_image._timeStamp;
|
||||
|
||||
// TODO(asapersson): This is incorrect if simulcast layers are encoded on
|
||||
// different threads and there is no guarantee that one frame of all layers
|
||||
// are encoded before the next start.
|
||||
if (last_sent_frame_timestamp_ > 0 &&
|
||||
encoded_image._timeStamp != last_sent_frame_timestamp_) {
|
||||
sent_frame_rate_tracker_total_.Update(1);
|
||||
sent_width_counter_.Add(max_sent_width_per_timestamp_);
|
||||
sent_height_counter_.Add(max_sent_height_per_timestamp_);
|
||||
max_sent_width_per_timestamp_ = 0;
|
||||
max_sent_height_per_timestamp_ = 0;
|
||||
}
|
||||
last_sent_frame_timestamp_ = encoded_image._timeStamp;
|
||||
max_sent_width_per_timestamp_ =
|
||||
std::max(max_sent_width_per_timestamp_,
|
||||
static_cast<int>(encoded_image._encodedWidth));
|
||||
max_sent_height_per_timestamp_ =
|
||||
std::max(max_sent_height_per_timestamp_,
|
||||
static_cast<int>(encoded_image._encodedHeight));
|
||||
}
|
||||
|
||||
void SendStatisticsProxy::OnIncomingFrame() {
|
||||
void SendStatisticsProxy::OnIncomingFrame(int width, int height) {
|
||||
rtc::CritScope lock(&crit_);
|
||||
input_frame_rate_tracker_.Update(1);
|
||||
input_frame_rate_tracker_total_.Update(1);
|
||||
input_width_counter_.Add(width);
|
||||
input_height_counter_.Add(height);
|
||||
}
|
||||
|
||||
void SendStatisticsProxy::RtcpPacketTypesCounterUpdated(
|
||||
@ -219,4 +254,15 @@ void SendStatisticsProxy::SendSideDelayUpdated(int avg_delay_ms,
|
||||
stats->max_delay_ms = max_delay_ms;
|
||||
}
|
||||
|
||||
void SendStatisticsProxy::SampleCounter::Add(int sample) {
|
||||
sum += sample;
|
||||
++num_samples;
|
||||
}
|
||||
|
||||
int SendStatisticsProxy::SampleCounter::Avg(int min_required_samples) const {
|
||||
if (num_samples < min_required_samples || num_samples == 0)
|
||||
return -1;
|
||||
return sum / num_samples;
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -47,7 +47,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
virtual void OnSendEncodedImage(const EncodedImage& encoded_image,
|
||||
const RTPVideoHeader* rtp_video_header);
|
||||
// Used to update incoming frame rate.
|
||||
void OnIncomingFrame();
|
||||
void OnIncomingFrame(int width, int height);
|
||||
|
||||
// From VideoEncoderRateObserver.
|
||||
void OnSetRates(uint32_t bitrate_bps, int framerate) override;
|
||||
@ -61,7 +61,7 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
void StatisticsUpdated(const RtcpStatistics& statistics,
|
||||
uint32_t ssrc) override;
|
||||
void CNameChanged(const char* cname, uint32_t ssrc) override;
|
||||
// From RtcpPacketTypeCounterObserver
|
||||
// From RtcpPacketTypeCounterObserver.
|
||||
void RtcpPacketTypesCounterUpdated(
|
||||
uint32_t ssrc,
|
||||
const RtcpPacketTypeCounter& packet_counter) override;
|
||||
@ -90,6 +90,15 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
uint32_t ssrc) override;
|
||||
|
||||
private:
|
||||
struct SampleCounter {
|
||||
SampleCounter() : sum(0), num_samples(0) {}
|
||||
void Add(int sample);
|
||||
int Avg(int min_required_samples) const;
|
||||
|
||||
private:
|
||||
int sum;
|
||||
int num_samples;
|
||||
};
|
||||
struct StatsUpdateTimes {
|
||||
StatsUpdateTimes() : resolution_update_ms(0) {}
|
||||
int64_t resolution_update_ms;
|
||||
@ -109,6 +118,13 @@ class SendStatisticsProxy : public CpuOveruseMetricsObserver,
|
||||
rtc::RateTracker sent_frame_rate_tracker_total_ GUARDED_BY(crit_);
|
||||
uint32_t last_sent_frame_timestamp_ GUARDED_BY(crit_);
|
||||
std::map<uint32_t, StatsUpdateTimes> update_times_ GUARDED_BY(crit_);
|
||||
|
||||
int max_sent_width_per_timestamp_ GUARDED_BY(crit_);
|
||||
int max_sent_height_per_timestamp_ GUARDED_BY(crit_);
|
||||
SampleCounter input_width_counter_ GUARDED_BY(crit_);
|
||||
SampleCounter input_height_counter_ GUARDED_BY(crit_);
|
||||
SampleCounter sent_width_counter_ GUARDED_BY(crit_);
|
||||
SampleCounter sent_height_counter_ GUARDED_BY(crit_);
|
||||
};
|
||||
|
||||
} // namespace webrtc
|
||||
|
||||
@ -78,7 +78,7 @@ void VideoCaptureInput::IncomingCapturedFrame(const VideoFrame& video_frame) {
|
||||
if (local_renderer_)
|
||||
local_renderer_->RenderFrame(video_frame, 0);
|
||||
|
||||
stats_proxy_->OnIncomingFrame();
|
||||
stats_proxy_->OnIncomingFrame(video_frame.width(), video_frame.height());
|
||||
|
||||
VideoFrame incoming_frame = video_frame;
|
||||
|
||||
|
||||
@ -318,7 +318,7 @@ int VideoReceiveStream::RenderFrame(const uint32_t /*stream_id*/,
|
||||
video_frame,
|
||||
video_frame.render_time_ms() - clock_->TimeInMilliseconds());
|
||||
|
||||
stats_proxy_->OnRenderedFrame();
|
||||
stats_proxy_->OnRenderedFrame(video_frame.width(), video_frame.height());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user