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 9af65e24be..d3a8df49f1 100644 --- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc +++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc @@ -237,6 +237,7 @@ uint16_t DefaultVideoQualityAnalyzer::OnFrameCaptured( it->second.erase(frame_id); } stream_to_frame_id_history_[stream_index].insert(frame_id); + stream_to_frame_id_full_history_[stream_index].push_back(frame_id); // If state has too many frames that are in flight => remove the oldest // queued frame in order to avoid to use too much memory. @@ -870,6 +871,16 @@ double DefaultVideoQualityAnalyzer::GetCpuUsagePercent() { return cpu_measurer_.GetCpuUsagePercent(); } +std::map> +DefaultVideoQualityAnalyzer::GetStreamFrames() const { + MutexLock lock(&mutex_); + std::map> out; + for (auto entry_it : stream_to_frame_id_full_history_) { + out.insert({streams_.name(entry_it.first), entry_it.second}); + } + return out; +} + uint16_t DefaultVideoQualityAnalyzer::StreamState::PopFront(size_t peer) { size_t peer_queue = GetPeerQueueIndex(peer); size_t alive_frames_queue = GetAliveFramesQueueIndex(); 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 d7365cbfd0..15b753d2e2 100644 --- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h +++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.h @@ -92,6 +92,10 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { AnalyzerStats GetAnalyzerStats() const; double GetCpuUsagePercent(); + // Returns mapping from the stream label to the history of frames that were + // met in this stream in the order as they were captured. + std::map> GetStreamFrames() const; + private: // Represents a current state of video stream. class StreamState { @@ -363,6 +367,9 @@ class DefaultVideoQualityAnalyzer : public VideoQualityAnalyzerInterface { // still encoding. std::map> stream_to_frame_id_history_ RTC_GUARDED_BY(mutex_); + // Map from stream index to the list of frames as they were met in the stream. + std::map> stream_to_frame_id_full_history_ + RTC_GUARDED_BY(mutex_); AnalyzerStats analyzer_stats_ RTC_GUARDED_BY(mutex_); DefaultVideoQualityAnalyzerCpuMeasurer cpu_measurer_; diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc index 56c1d3fdb4..b18457e5d4 100644 --- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc +++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_test.cc @@ -1425,5 +1425,44 @@ TEST( } } +TEST(DefaultVideoQualityAnalyzerTest, GetStreamFrames) { + std::unique_ptr frame_generator = + test::CreateSquareFrameGenerator(kFrameWidth, kFrameHeight, + /*type=*/absl::nullopt, + /*num_squares=*/absl::nullopt); + + DefaultVideoQualityAnalyzerOptions options = AnalyzerOptionsForTest(); + DefaultVideoQualityAnalyzer analyzer(Clock::GetRealTimeClock(), options); + analyzer.Start("test_case", std::vector{"alice", "bob"}, + kAnalyzerMaxThreadsCount); + + // The order in which peers captured frames and passed them to analyzer. + std::vector frame_capturers_sequence{ + "alice", "alice", "bob", "bob", "bob", + "bob", "bob", "alice", "alice", "alice", + }; + + std::map> stream_to_frame_ids; + stream_to_frame_ids.emplace("alice_video", std::vector{}); + stream_to_frame_ids.emplace("bob_video", std::vector{}); + + std::vector frames; + for (const std::string& sender : frame_capturers_sequence) { + VideoFrame frame = NextFrame(frame_generator.get(), /*timestamp_us=*/1); + uint16_t frame_id = + analyzer.OnFrameCaptured(sender, sender + "_video", frame); + frame.set_id(frame_id); + stream_to_frame_ids.find(sender + "_video")->second.push_back(frame_id); + frames.push_back(frame); + analyzer.OnFramePreEncode(sender, frame); + analyzer.OnFrameEncoded(sender, frame.id(), FakeEncode(frame), + VideoQualityAnalyzerInterface::EncoderStats()); + } + // We don't need to receive frames for stats to be gathered correctly. + analyzer.Stop(); + + EXPECT_EQ(analyzer.GetStreamFrames(), stream_to_frame_ids); +} + } // namespace } // namespace webrtc