Parse extension and store it in RTPVideoHeader

Bug: webrtc:358039777
Change-Id: Ib70046662877efa5f8d0cbe559b44d138f4733e2
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/364481
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Fanny Linderborg <linderborg@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Auto-Submit: Fanny Linderborg <linderborg@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#43146}
diff --git a/video/BUILD.gn b/video/BUILD.gn
index 0eb6d6f..fdbe2fa 100644
--- a/video/BUILD.gn
+++ b/video/BUILD.gn
@@ -117,6 +117,9 @@
     "../call:rtp_sender",
     "../call:video_stream_api",
     "../common_video",
+    "../common_video:corruption_detection_converters",
+    "../common_video:corruption_detection_message",
+    "../common_video:frame_instrumentation_data",
     "../media:media_constants",
     "../media:rtc_sdp_video_format_utils",
     "../modules:module_api",
@@ -170,6 +173,7 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/strings",
+    "//third_party/abseil-cpp/absl/types:variant",
   ]
 
   if (!build_with_mozilla) {
diff --git a/video/rtp_video_stream_receiver2.cc b/video/rtp_video_stream_receiver2.cc
index 818353c..9c8f28c 100644
--- a/video/rtp_video_stream_receiver2.cc
+++ b/video/rtp_video_stream_receiver2.cc
@@ -19,12 +19,17 @@
 
 #include "absl/algorithm/container.h"
 #include "absl/memory/memory.h"
+#include "absl/types/variant.h"
 #include "api/video/video_codec_type.h"
+#include "common_video/corruption_detection_converters.h"
+#include "common_video/corruption_detection_message.h"
+#include "common_video/frame_instrumentation_data.h"
 #include "media/base/media_constants.h"
 #include "modules/pacing/packet_router.h"
 #include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
 #include "modules/rtp_rtcp/include/receive_statistics.h"
 #include "modules/rtp_rtcp/include/rtp_cvo.h"
+#include "modules/rtp_rtcp/source/corruption_detection_extension.h"
 #include "modules/rtp_rtcp/source/create_video_rtp_depacketizer.h"
 #include "modules/rtp_rtcp/source/frame_object.h"
 #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h"
@@ -497,6 +502,21 @@
   return kHasGenericDescriptor;
 }
 
+void RtpVideoStreamReceiver2::SetLastCorruptionDetectionIndex(
+    const absl::variant<FrameInstrumentationSyncData, FrameInstrumentationData>&
+        frame_instrumentation_data) {
+  if (const auto* sync_data = absl::get_if<FrameInstrumentationSyncData>(
+          &frame_instrumentation_data)) {
+    last_corruption_detection_index_ = sync_data->sequence_index;
+  } else if (const auto* data = absl::get_if<FrameInstrumentationData>(
+                 &frame_instrumentation_data)) {
+    last_corruption_detection_index_ =
+        data->sequence_index + data->sample_values.size();
+  } else {
+    RTC_DCHECK_NOTREACHED();
+  }
+}
+
 bool RtpVideoStreamReceiver2::OnReceivedPayloadData(
     rtc::CopyOnWriteBuffer codec_payload,
     const RtpPacketReceived& rtp_packet,
@@ -582,9 +602,7 @@
     return false;
   }
 
-  // Color space should only be transmitted in the last packet of a frame,
-  // therefore, neglect it otherwise so that last_color_space_ is not reset by
-  // mistake.
+  // Extensions that should only be transmitted in the last packet of a frame.
   if (video_header.is_last_packet_in_frame) {
     video_header.color_space = rtp_packet.GetExtension<ColorSpaceExtension>();
     if (video_header.color_space ||
@@ -596,6 +614,20 @@
     } else if (last_color_space_) {
       video_header.color_space = last_color_space_;
     }
+    CorruptionDetectionMessage message;
+    rtp_packet.GetExtension<CorruptionDetectionExtension>(&message);
+    if (message.sample_values().empty()) {
+      // TODO: bugs.webrtc.org/358039777 - Convert message to sync data and
+      // use that for assignment instead of `std::nullptr`.
+      video_header.frame_instrumentation_data = std::nullopt;
+    } else {
+      video_header.frame_instrumentation_data =
+          ConvertCorruptionDetectionMessageToFrameInstrumentationData(
+              message, last_corruption_detection_index_);
+    }
+    if (video_header.frame_instrumentation_data.has_value()) {
+      SetLastCorruptionDetectionIndex(*video_header.frame_instrumentation_data);
+    }
   }
   video_header.video_frame_tracking_id =
       rtp_packet.GetExtension<VideoFrameTrackingIdExtension>();
diff --git a/video/rtp_video_stream_receiver2.h b/video/rtp_video_stream_receiver2.h
index 141f15c..e996bb2 100644
--- a/video/rtp_video_stream_receiver2.h
+++ b/video/rtp_video_stream_receiver2.h
@@ -17,6 +17,7 @@
 #include <string>
 #include <vector>
 
+#include "absl/types/variant.h"
 #include "api/crypto/frame_decryptor_interface.h"
 #include "api/environment/environment.h"
 #include "api/sequence_checker.h"
@@ -26,6 +27,7 @@
 #include "call/rtp_packet_sink_interface.h"
 #include "call/syncable.h"
 #include "call/video_receive_stream.h"
+#include "common_video/frame_instrumentation_data.h"
 #include "modules/rtp_rtcp/include/receive_statistics.h"
 #include "modules/rtp_rtcp/include/recovered_packet_receiver.h"
 #include "modules/rtp_rtcp/include/remote_ntp_time_estimator.h"
@@ -313,6 +315,10 @@
   void UpdatePacketReceiveTimestamps(const RtpPacketReceived& packet,
                                      bool is_keyframe)
       RTC_RUN_ON(packet_sequence_checker_);
+  void SetLastCorruptionDetectionIndex(
+      const absl::variant<FrameInstrumentationSyncData,
+                          FrameInstrumentationData>&
+          frame_instrumentation_data);
 
   const Environment env_;
   TaskQueueBase* const worker_queue_;
@@ -445,6 +451,7 @@
   Timestamp next_keyframe_request_for_missing_video_structure_ =
       Timestamp::MinusInfinity();
   bool sps_pps_idr_is_h264_keyframe_ = false;
+  int last_corruption_detection_index_ = 0;
 };
 
 }  // namespace webrtc