Propagate corruption score to VideoReceiverInfo.

Bug: webrtc:358039777
Change-Id: Ib9f4e17b80b9af2182a019f3201882fd887da506
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/361080
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Emil Vardar (xWF) <vardar@google.com>
Cr-Commit-Position: refs/heads/main@{#42918}
diff --git a/call/video_receive_stream.h b/call/video_receive_stream.h
index 23cf035..370bc16 100644
--- a/call/video_receive_stream.h
+++ b/call/video_receive_stream.h
@@ -129,7 +129,6 @@
     int64_t first_frame_received_to_decoded_ms = -1;
     std::optional<uint64_t> qp_sum;
 
-    // TODO(webrtc:357636606): Propagate this score upwards in the chain.
     // Corruption score, indicating the probability of corruption. Its value is
     // between 0 and 1, where 0 means no corruption and 1 means that the
     // compressed frame is corrupted.
diff --git a/media/base/media_channel.h b/media/base/media_channel.h
index ed69c6b..c59a575 100644
--- a/media/base/media_channel.h
+++ b/media/base/media_channel.h
@@ -635,6 +635,17 @@
   uint32_t key_frames_decoded = 0;
   uint32_t frames_rendered = 0;
   std::optional<uint64_t> qp_sum;
+  // Corruption score, indicating the probability of corruption. Its value is
+  // between 0 and 1, where 0 means no corruption and 1 means that the
+  // compressed frame is corrupted.
+  // However, note that the corruption score may not accurately reflect
+  // corruption. E.g. even if the corruption score is 0, the compressed frame
+  // may still be corrupted and vice versa.
+  std::optional<double> corruption_score_sum;
+  std::optional<double> corruption_score_squared_sum;
+  // Number of frames the `corruption_score` was calculated on. This is
+  // usually not the same as `frames_decoded` or `frames_rendered`.
+  uint32_t corruption_score_count = 0;
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totaldecodetime
   webrtc::TimeDelta total_decode_time = webrtc::TimeDelta::Zero();
   // https://w3c.github.io/webrtc-stats/#dom-rtcinboundrtpstreamstats-totalprocessingdelay
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index ec51433..fa58fd3 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -3689,6 +3689,9 @@
   info.key_frames_decoded = stats.frame_counts.key_frames;
   info.frames_rendered = stats.frames_rendered;
   info.qp_sum = stats.qp_sum;
+  info.corruption_score_sum = stats.corruption_score_sum;
+  info.corruption_score_squared_sum = stats.corruption_score_squared_sum;
+  info.corruption_score_count = stats.corruption_score_count;
   info.total_decode_time = stats.total_decode_time;
   info.total_processing_delay = stats.total_processing_delay;
   info.total_assembly_time = stats.total_assembly_time;
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index 13ffe6f..52981dd 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -6675,6 +6675,9 @@
   stats.frames_rendered = 13;
   stats.frames_decoded = 14;
   stats.qp_sum = 15;
+  stats.corruption_score_sum = 0.3;
+  stats.corruption_score_squared_sum = 0.05;
+  stats.corruption_score_count = 2;
   stats.total_decode_time = webrtc::TimeDelta::Millis(16);
   stats.total_assembly_time = webrtc::TimeDelta::Millis(4);
   stats.frames_assembled_from_multiple_packets = 2;
@@ -6718,6 +6721,12 @@
   EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames),
             receive_info.receivers[0].key_frames_decoded);
   EXPECT_EQ(stats.qp_sum, receive_info.receivers[0].qp_sum);
+  EXPECT_EQ(stats.corruption_score_sum,
+            receive_info.receivers[0].corruption_score_sum);
+  EXPECT_EQ(stats.corruption_score_squared_sum,
+            receive_info.receivers[0].corruption_score_squared_sum);
+  EXPECT_EQ(stats.corruption_score_count,
+            receive_info.receivers[0].corruption_score_count);
   EXPECT_EQ(stats.total_decode_time,
             receive_info.receivers[0].total_decode_time);
   EXPECT_EQ(stats.total_assembly_time,