[DVQA] Add detailed printout of when frame was dropped

Bug: b/196229820
Change-Id: I5ed463f1cc9694db7b9a0a0564a5b1784d6ba724
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/229381
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34811}
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 2886fa8..a2fbdbe 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer.cc
@@ -45,9 +45,28 @@
   RTC_LOG(INFO) << "[" << name << "] Dropped     : " << counters.dropped;
 }
 
+absl::string_view ToString(FrameDropPhase phase) {
+  switch (phase) {
+    case FrameDropPhase::kBeforeEncoder:
+      return "kBeforeEncoder";
+    case FrameDropPhase::kByEncoder:
+      return "kByEncoder";
+    case FrameDropPhase::kTransport:
+      return "kTransport";
+    case FrameDropPhase::kAfterDecoder:
+      return "kAfterDecoder";
+    case FrameDropPhase::kLastValue:
+      RTC_CHECK(false) << "FrameDropPhase::kLastValue mustn't be used";
+  }
+}
+
 void LogStreamInternalStats(const std::string& name,
                             const StreamStats& stats,
                             Timestamp start_time) {
+  for (const auto& entry : stats.dropped_by_phase) {
+    RTC_LOG(INFO) << "[" << name << "] Dropped at " << ToString(entry.first)
+                  << ": " << entry.second;
+  }
   RTC_LOG(INFO) << "[" << name
                 << "] Dropped by encoder     : " << stats.dropped_by_encoder;
   RTC_LOG(INFO) << "[" << name << "] Dropped before encoder : "
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc
index b4aac71..ceabf09 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_frames_comparator.cc
@@ -405,6 +405,21 @@
     stats->ssim.AddSample(StatsSample(ssim, frame_stats.received_time));
   }
 
+  // Compute dropped phase for dropped frame
+  if (comparison.type == FrameComparisonType::kDroppedFrame) {
+    webrtc_pc_e2e::FrameDropPhase dropped_phase;
+    if (frame_stats.decode_end_time.IsFinite()) {
+      dropped_phase = webrtc_pc_e2e::FrameDropPhase::kAfterDecoder;
+    } else if (frame_stats.encoded_time.IsFinite()) {
+      dropped_phase = webrtc_pc_e2e::FrameDropPhase::kTransport;
+    } else if (frame_stats.pre_encode_time.IsFinite()) {
+      dropped_phase = webrtc_pc_e2e::FrameDropPhase::kByEncoder;
+    } else {
+      dropped_phase = webrtc_pc_e2e::FrameDropPhase::kBeforeEncoder;
+    }
+    stats->dropped_by_phase[dropped_phase]++;
+  }
+
   if (frame_stats.encoded_time.IsFinite()) {
     stats->encode_time_ms.AddSample(StatsSample(
         (frame_stats.encoded_time - frame_stats.pre_encode_time).ms(),
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.cc b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.cc
index 1149ac1..f40f5e0 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.cc
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.cc
@@ -38,6 +38,14 @@
          (event_last_time_ - event_first_time_).us() * kMicrosPerSecond;
 }
 
+StreamStats::StreamStats(Timestamp stream_started_time)
+    : stream_started_time(stream_started_time) {
+  for (int i = static_cast<int>(FrameDropPhase::kBeforeEncoder);
+       i < static_cast<int>(FrameDropPhase::kLastValue); ++i) {
+    dropped_by_phase.emplace(static_cast<FrameDropPhase>(i), 0);
+  }
+}
+
 std::string StatsKey::ToString() const {
   rtc::StringBuilder out;
   out << stream_label << "_" << sender << "_" << receiver;
diff --git a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h
index 4c90961..278c9ba 100644
--- a/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h
+++ b/test/pc/e2e/analyzer/video/default_video_quality_analyzer_shared_objects.h
@@ -11,6 +11,7 @@
 #ifndef TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_SHARED_OBJECTS_H_
 #define TEST_PC_E2E_ANALYZER_VIDEO_DEFAULT_VIDEO_QUALITY_ANALYZER_SHARED_OBJECTS_H_
 
+#include <map>
 #include <memory>
 #include <string>
 #include <utility>
@@ -78,9 +79,19 @@
   Timestamp switched_from_at = Timestamp::PlusInfinity();
 };
 
+// Represents phases where video frame can be dropped and such drop will be
+// detected by analyzer.
+enum class FrameDropPhase : int {
+  kBeforeEncoder,
+  kByEncoder,
+  kTransport,
+  kAfterDecoder,
+  // kLastValue must be the last value in this enumeration.
+  kLastValue
+};
+
 struct StreamStats {
-  explicit StreamStats(Timestamp stream_started_time)
-      : stream_started_time(stream_started_time) {}
+  explicit StreamStats(Timestamp stream_started_time);
 
   // The time when the first frame of this stream was captured.
   Timestamp stream_started_time;
@@ -117,6 +128,8 @@
   int64_t total_encoded_images_payload = 0;
   int64_t dropped_by_encoder = 0;
   int64_t dropped_before_encoder = 0;
+  // Counters on which phase how many frames were dropped.
+  std::map<FrameDropPhase, int64_t> dropped_by_phase;
 
   // Vector of encoders used for this stream by sending client.
   std::vector<StreamCodecInfo> encoders;