Include duration of pauses into sum of squared frames duration.
Bug: webrtc:10502 Change-Id: Ie905c0c9e8ca8fe07be585ce5a0d75e9eed6e865 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/130499 Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org> Cr-Commit-Position: refs/heads/master@{#27435}
This commit is contained in:
parent
78a5e96001
commit
fc6f3e5873
@ -1263,30 +1263,41 @@ TEST_P(ReceiveStatisticsProxyTestWithContent, FreezesAreReported) {
|
||||
}
|
||||
|
||||
TEST_P(ReceiveStatisticsProxyTestWithContent, HarmonicFrameRateIsReported) {
|
||||
const int kInterFrameDelayMs = 33;
|
||||
const int kFreezeDelayMs = 200;
|
||||
const int kCallDurationMs =
|
||||
kMinRequiredSamples * kInterFrameDelayMs + kFreezeDelayMs;
|
||||
const int kFrameDurationMs = 33;
|
||||
const int kFreezeDurationMs = 200;
|
||||
const int kPauseDurationMs = 10000;
|
||||
const int kCallDurationMs = kMinRequiredSamples * kFrameDurationMs +
|
||||
kFreezeDurationMs + kPauseDurationMs;
|
||||
webrtc::VideoFrame frame = CreateFrame(kWidth, kHeight);
|
||||
|
||||
for (int i = 0; i < kMinRequiredSamples; ++i) {
|
||||
fake_clock_.AdvanceTimeMilliseconds(kInterFrameDelayMs);
|
||||
fake_clock_.AdvanceTimeMilliseconds(kFrameDurationMs);
|
||||
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type_);
|
||||
statistics_proxy_->OnRenderedFrame(frame);
|
||||
}
|
||||
// Add extra freeze.
|
||||
fake_clock_.AdvanceTimeMilliseconds(kFreezeDelayMs);
|
||||
|
||||
// Freezes and pauses should be included into harmonic frame rate.
|
||||
// Add freeze.
|
||||
fake_clock_.AdvanceTimeMilliseconds(kFreezeDurationMs);
|
||||
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type_);
|
||||
statistics_proxy_->OnRenderedFrame(frame);
|
||||
|
||||
// Add pause.
|
||||
fake_clock_.AdvanceTimeMilliseconds(kPauseDurationMs);
|
||||
statistics_proxy_->OnStreamInactive();
|
||||
statistics_proxy_->OnDecodedFrame(frame, absl::nullopt, content_type_);
|
||||
statistics_proxy_->OnRenderedFrame(frame);
|
||||
|
||||
statistics_proxy_.reset();
|
||||
double kSumSquaredInterframeDelaysSecs =
|
||||
double kSumSquaredFrameDurationSecs =
|
||||
(kMinRequiredSamples - 1) *
|
||||
(kInterFrameDelayMs / 1000.0 * kInterFrameDelayMs / 1000.0);
|
||||
kSumSquaredInterframeDelaysSecs +=
|
||||
kFreezeDelayMs / 1000.0 * kFreezeDelayMs / 1000.0;
|
||||
(kFrameDurationMs / 1000.0 * kFrameDurationMs / 1000.0);
|
||||
kSumSquaredFrameDurationSecs +=
|
||||
kFreezeDurationMs / 1000.0 * kFreezeDurationMs / 1000.0;
|
||||
kSumSquaredFrameDurationSecs +=
|
||||
kPauseDurationMs / 1000.0 * kPauseDurationMs / 1000.0;
|
||||
const int kExpectedHarmonicFrameRateFps =
|
||||
std::round(kCallDurationMs / (1000 * kSumSquaredInterframeDelaysSecs));
|
||||
std::round(kCallDurationMs / (1000 * kSumSquaredFrameDurationSecs));
|
||||
if (videocontenttypehelpers::IsScreenshare(content_type_)) {
|
||||
EXPECT_EQ(kExpectedHarmonicFrameRateFps,
|
||||
metrics::MinSample("WebRTC.Video.Screenshare.HarmonicFrameRate"));
|
||||
|
||||
@ -146,35 +146,42 @@ void VideoQualityObserver::OnRenderedFrame(const VideoFrame& frame,
|
||||
|
||||
auto blocky_frame_it = blocky_frames_.find(frame.timestamp());
|
||||
|
||||
if (!is_paused_ && num_frames_rendered_ > 0) {
|
||||
if (num_frames_rendered_ > 0) {
|
||||
// Process inter-frame delay.
|
||||
const int64_t interframe_delay_ms = now_ms - last_frame_rendered_ms_;
|
||||
const double interframe_delays_secs = interframe_delay_ms / 1000.0;
|
||||
|
||||
// Sum of squared inter frame intervals is used to calculate the harmonic
|
||||
// frame rate metric. The metric aims to reflect overall experience related
|
||||
// to smoothness of video playback and includes both freezes and pauses.
|
||||
sum_squared_interframe_delays_secs_ +=
|
||||
interframe_delays_secs * interframe_delays_secs;
|
||||
render_interframe_delays_.AddSample(interframe_delay_ms);
|
||||
|
||||
bool was_freeze = false;
|
||||
if (render_interframe_delays_.Size() >= kMinFrameSamplesToDetectFreeze) {
|
||||
const absl::optional<int64_t> avg_interframe_delay =
|
||||
render_interframe_delays_.GetAverageRoundedDown();
|
||||
RTC_DCHECK(avg_interframe_delay);
|
||||
was_freeze = interframe_delay_ms >=
|
||||
std::max(3 * *avg_interframe_delay,
|
||||
*avg_interframe_delay + kMinIncreaseForFreezeMs);
|
||||
}
|
||||
if (!is_paused_) {
|
||||
render_interframe_delays_.AddSample(interframe_delay_ms);
|
||||
|
||||
if (was_freeze) {
|
||||
freezes_durations_.Add(interframe_delay_ms);
|
||||
smooth_playback_durations_.Add(last_frame_rendered_ms_ -
|
||||
last_unfreeze_time_ms_);
|
||||
last_unfreeze_time_ms_ = now_ms;
|
||||
} else {
|
||||
// Count spatial metrics if there were no freeze.
|
||||
time_in_resolution_ms_[current_resolution_] += interframe_delay_ms;
|
||||
bool was_freeze = false;
|
||||
if (render_interframe_delays_.Size() >= kMinFrameSamplesToDetectFreeze) {
|
||||
const absl::optional<int64_t> avg_interframe_delay =
|
||||
render_interframe_delays_.GetAverageRoundedDown();
|
||||
RTC_DCHECK(avg_interframe_delay);
|
||||
was_freeze = interframe_delay_ms >=
|
||||
std::max(3 * *avg_interframe_delay,
|
||||
*avg_interframe_delay + kMinIncreaseForFreezeMs);
|
||||
}
|
||||
|
||||
if (is_last_frame_blocky_) {
|
||||
time_in_blocky_video_ms_ += interframe_delay_ms;
|
||||
if (was_freeze) {
|
||||
freezes_durations_.Add(interframe_delay_ms);
|
||||
smooth_playback_durations_.Add(last_frame_rendered_ms_ -
|
||||
last_unfreeze_time_ms_);
|
||||
last_unfreeze_time_ms_ = now_ms;
|
||||
} else {
|
||||
// Count spatial metrics if there were no freeze.
|
||||
time_in_resolution_ms_[current_resolution_] += interframe_delay_ms;
|
||||
|
||||
if (is_last_frame_blocky_) {
|
||||
time_in_blocky_video_ms_ += interframe_delay_ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user