[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}
This commit is contained in:
parent
44b919c10a
commit
6eb30e40af
@ -33,6 +33,10 @@ namespace {
|
||||
|
||||
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 @@ void DefaultVideoQualityAnalyzer::OnFrameRendered(
|
||||
|
||||
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 @@ bool DefaultVideoQualityAnalyzer::FrameInFlight::HasRenderedTime(
|
||||
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_);
|
||||
|
||||
@ -243,6 +243,7 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user