[DVQA] Tolerate receiving frames which were considerer as dropped before
It can happen that SFU will resend the frame which was before
considered as dropped during stream switching.
Bug: b/197740434
Change-Id: I95a67e6e637f6005a24df15875b50133a6e8eaaf
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/230423
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#34865}
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
index b8c8a67..da4a81a 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
@@ -33,6 +33,10 @@
constexpr int kMicrosPerSecond = 1000000;
constexpr int kBitsInByte = 8;
+constexpr absl::string_view kSkipRenderedFrameReasonProcessed = "processed";
+constexpr absl::string_view kSkipRenderedFrameReasonRendered = "rendered";
+constexpr absl::string_view kSkipRenderedFrameReasonDropped =
+ "considered dropped";
void LogFrameCounters(const std::string& name, const FrameCounters& counters) {
RTC_LOG(INFO) << "[" << name << "] Captured : " << counters.captured;
@@ -387,12 +391,25 @@
auto frame_it = captured_frames_in_flight_.find(frame.id());
if (frame_it == captured_frames_in_flight_.end() ||
- frame_it->second.HasRenderedTime(peer_index)) {
- // It means this frame was rendered before, so we can skip it. It may happen
- // when we have multiple simulcast streams in one track and received
- // the same picture from two different streams because SFU can't reliably
- // correlate two simulcast streams and started relaying the second stream
- // from the same frame it has relayed right before for the first stream.
+ frame_it->second.HasRenderedTime(peer_index) ||
+ frame_it->second.IsDropped(peer_index)) {
+ // It means this frame was rendered or dropped before, so we can skip it.
+ // It may happen when we have multiple simulcast streams in one track and
+ // received the same frame from two different streams because SFU can't
+ // reliably correlate two simulcast streams and started relaying the second
+ // stream from the same frame it has relayed right before for the first
+ // stream.
+ absl::string_view reason = kSkipRenderedFrameReasonProcessed;
+ if (frame_it != captured_frames_in_flight_.end()) {
+ if (frame_it->second.HasRenderedTime(peer_index)) {
+ reason = kSkipRenderedFrameReasonRendered;
+ } else if (frame_it->second.IsDropped(peer_index)) {
+ reason = kSkipRenderedFrameReasonDropped;
+ }
+ }
+ RTC_LOG(WARNING) << "Peer " << peer_name
+ << "; Received frame out of order: received frame with id "
+ << frame.id() << " which was " << reason << " before";
return;
}
@@ -1030,6 +1047,14 @@
return it->second.rendered_time.IsFinite();
}
+bool DefaultVideoQualityAnalyzer::FrameInFlight::IsDropped(size_t peer) const {
+ auto it = receiver_stats_.find(peer);
+ if (it == receiver_stats_.end()) {
+ return false;
+ }
+ return it->second.dropped;
+}
+
FrameStats DefaultVideoQualityAnalyzer::FrameInFlight::GetStatsForPeer(
size_t peer) const {
FrameStats stats(captured_time_);
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h
index 2091edf..d7365cb 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h
@@ -243,6 +243,7 @@
}
void MarkDropped(size_t peer) { receiver_stats_[peer].dropped = true; }
+ bool IsDropped(size_t peer) const;
void SetPrevFrameRenderedTime(size_t peer, webrtc::Timestamp time) {
receiver_stats_[peer].prev_frame_rendered_time = time;