Add `AbsoluteCaptureTime` to `RtpPacketInfo`.

This change stores the optional `AbsoluteCaptureTime` header extension in `RtpPacketInfo` so that we later can consume it in `SourceTracker`.

Bug: webrtc:10739
Change-Id: I975e8863117fcda134535cd49ad71079a7ff38ec
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/148068
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Chen Xing <chxg@google.com>
Cr-Commit-Position: refs/heads/master@{#28790}
diff --git a/api/BUILD.gn b/api/BUILD.gn
index 5c681bc..ffaa4aa 100644
--- a/api/BUILD.gn
+++ b/api/BUILD.gn
@@ -92,6 +92,7 @@
     ":rtp_headers",
     ":scoped_refptr",
     "..:webrtc_common",
+    "../rtc_base:deprecation",
     "../rtc_base:rtc_base_approved",
     "//third_party/abseil-cpp/absl/types:optional",
   ]
diff --git a/api/rtp_headers.h b/api/rtp_headers.h
index e5155f0..4415bd3 100644
--- a/api/rtp_headers.h
+++ b/api/rtp_headers.h
@@ -79,6 +79,18 @@
   absl::optional<int64_t> estimated_capture_clock_offset;
 };
 
+inline bool operator==(const AbsoluteCaptureTime& lhs,
+                       const AbsoluteCaptureTime& rhs) {
+  return (lhs.absolute_capture_timestamp == rhs.absolute_capture_timestamp) &&
+         (lhs.estimated_capture_clock_offset ==
+          rhs.estimated_capture_clock_offset);
+}
+
+inline bool operator!=(const AbsoluteCaptureTime& lhs,
+                       const AbsoluteCaptureTime& rhs) {
+  return !(lhs == rhs);
+}
+
 struct RTPHeaderExtension {
   RTPHeaderExtension();
   RTPHeaderExtension(const RTPHeaderExtension& other);
diff --git a/api/rtp_packet_info.cc b/api/rtp_packet_info.cc
index efb7838..54e26b4 100644
--- a/api/rtp_packet_info.cc
+++ b/api/rtp_packet_info.cc
@@ -18,16 +18,31 @@
 RtpPacketInfo::RtpPacketInfo()
     : ssrc_(0), rtp_timestamp_(0), receive_time_ms_(-1) {}
 
+RtpPacketInfo::RtpPacketInfo(
+    uint32_t ssrc,
+    std::vector<uint32_t> csrcs,
+    uint32_t rtp_timestamp,
+    absl::optional<uint8_t> audio_level,
+    absl::optional<AbsoluteCaptureTime> absolute_capture_time,
+    int64_t receive_time_ms)
+    : ssrc_(ssrc),
+      csrcs_(std::move(csrcs)),
+      rtp_timestamp_(rtp_timestamp),
+      audio_level_(audio_level),
+      absolute_capture_time_(absolute_capture_time),
+      receive_time_ms_(receive_time_ms) {}
+
 RtpPacketInfo::RtpPacketInfo(uint32_t ssrc,
                              std::vector<uint32_t> csrcs,
                              uint32_t rtp_timestamp,
                              absl::optional<uint8_t> audio_level,
                              int64_t receive_time_ms)
-    : ssrc_(ssrc),
-      csrcs_(std::move(csrcs)),
-      rtp_timestamp_(rtp_timestamp),
-      audio_level_(audio_level),
-      receive_time_ms_(receive_time_ms) {}
+    : RtpPacketInfo(ssrc,
+                    std::move(csrcs),
+                    rtp_timestamp,
+                    audio_level,
+                    /*absolute_capture_time=*/absl::nullopt,
+                    receive_time_ms) {}
 
 RtpPacketInfo::RtpPacketInfo(const RTPHeader& rtp_header,
                              int64_t receive_time_ms)
@@ -42,12 +57,15 @@
   if (extension.hasAudioLevel) {
     audio_level_ = extension.audioLevel;
   }
+
+  absolute_capture_time_ = extension.absolute_capture_time;
 }
 
 bool operator==(const RtpPacketInfo& lhs, const RtpPacketInfo& rhs) {
   return (lhs.ssrc() == rhs.ssrc()) && (lhs.csrcs() == rhs.csrcs()) &&
          (lhs.rtp_timestamp() == rhs.rtp_timestamp()) &&
          (lhs.audio_level() == rhs.audio_level()) &&
+         (lhs.absolute_capture_time() == rhs.absolute_capture_time()) &&
          (lhs.receive_time_ms() == rhs.receive_time_ms());
 }
 
diff --git a/api/rtp_packet_info.h b/api/rtp_packet_info.h
index a9e8655..6973027 100644
--- a/api/rtp_packet_info.h
+++ b/api/rtp_packet_info.h
@@ -17,6 +17,7 @@
 
 #include "absl/types/optional.h"
 #include "api/rtp_headers.h"
+#include "rtc_base/deprecation.h"
 
 namespace webrtc {
 
@@ -33,6 +34,15 @@
                 std::vector<uint32_t> csrcs,
                 uint32_t rtp_timestamp,
                 absl::optional<uint8_t> audio_level,
+                absl::optional<AbsoluteCaptureTime> absolute_capture_time,
+                int64_t receive_time_ms);
+
+  // TODO(bugs.webrtc.org/10739): Will be removed sometime after 2019-09-19.
+  RTC_DEPRECATED
+  RtpPacketInfo(uint32_t ssrc,
+                std::vector<uint32_t> csrcs,
+                uint32_t rtp_timestamp,
+                absl::optional<uint8_t> audio_level,
                 int64_t receive_time_ms);
 
   RtpPacketInfo(const RTPHeader& rtp_header, int64_t receive_time_ms);
@@ -54,6 +64,14 @@
   absl::optional<uint8_t> audio_level() const { return audio_level_; }
   void set_audio_level(absl::optional<uint8_t> value) { audio_level_ = value; }
 
+  const absl::optional<AbsoluteCaptureTime>& absolute_capture_time() const {
+    return absolute_capture_time_;
+  }
+  void set_absolute_capture_time(
+      const absl::optional<AbsoluteCaptureTime>& value) {
+    absolute_capture_time_ = value;
+  }
+
   int64_t receive_time_ms() const { return receive_time_ms_; }
   void set_receive_time_ms(int64_t value) { receive_time_ms_ = value; }
 
@@ -68,6 +86,10 @@
   // https://tools.ietf.org/html/rfc6464#section-3
   absl::optional<uint8_t> audio_level_;
 
+  // Fields from the Absolute Capture Time header extension:
+  // http://www.webrtc.org/experiments/rtp-hdrext/abs-capture-time
+  absl::optional<AbsoluteCaptureTime> absolute_capture_time_;
+
   // Local |webrtc::Clock|-based timestamp of when the packet was received.
   int64_t receive_time_ms_;
 };
diff --git a/api/rtp_packet_info_unittest.cc b/api/rtp_packet_info_unittest.cc
index 66cc2ed..fe79f6d 100644
--- a/api/rtp_packet_info_unittest.cc
+++ b/api/rtp_packet_info_unittest.cc
@@ -37,7 +37,7 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.ssrc(), value);
 
-  rhs = RtpPacketInfo(value, {}, {}, {}, {});
+  rhs = RtpPacketInfo(value, {}, {}, {}, {}, {});
   EXPECT_EQ(rhs.ssrc(), value);
 }
 
@@ -64,7 +64,7 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.csrcs(), value);
 
-  rhs = RtpPacketInfo({}, value, {}, {}, {});
+  rhs = RtpPacketInfo({}, value, {}, {}, {}, {});
   EXPECT_EQ(rhs.csrcs(), value);
 }
 
@@ -91,7 +91,7 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.rtp_timestamp(), value);
 
-  rhs = RtpPacketInfo({}, {}, value, {}, {});
+  rhs = RtpPacketInfo({}, {}, value, {}, {}, {});
   EXPECT_EQ(rhs.rtp_timestamp(), value);
 }
 
@@ -118,10 +118,37 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.audio_level(), value);
 
-  rhs = RtpPacketInfo({}, {}, {}, value, {});
+  rhs = RtpPacketInfo({}, {}, {}, value, {}, {});
   EXPECT_EQ(rhs.audio_level(), value);
 }
 
+TEST(RtpPacketInfoTest, AbsoluteCaptureTime) {
+  const absl::optional<AbsoluteCaptureTime> value = AbsoluteCaptureTime{12, 34};
+
+  RtpPacketInfo lhs;
+  RtpPacketInfo rhs;
+
+  EXPECT_TRUE(lhs == rhs);
+  EXPECT_FALSE(lhs != rhs);
+
+  rhs.set_absolute_capture_time(value);
+  EXPECT_EQ(rhs.absolute_capture_time(), value);
+
+  EXPECT_FALSE(lhs == rhs);
+  EXPECT_TRUE(lhs != rhs);
+
+  lhs = rhs;
+
+  EXPECT_TRUE(lhs == rhs);
+  EXPECT_FALSE(lhs != rhs);
+
+  rhs = RtpPacketInfo();
+  EXPECT_NE(rhs.absolute_capture_time(), value);
+
+  rhs = RtpPacketInfo({}, {}, {}, {}, value, {});
+  EXPECT_EQ(rhs.absolute_capture_time(), value);
+}
+
 TEST(RtpPacketInfoTest, ReceiveTimeMs) {
   const int64_t value = 8868963877546349045LL;
 
@@ -145,7 +172,7 @@
   rhs = RtpPacketInfo();
   EXPECT_NE(rhs.receive_time_ms(), value);
 
-  rhs = RtpPacketInfo({}, {}, {}, {}, value);
+  rhs = RtpPacketInfo({}, {}, {}, {}, {}, value);
   EXPECT_EQ(rhs.receive_time_ms(), value);
 }
 
diff --git a/api/rtp_packet_infos_unittest.cc b/api/rtp_packet_infos_unittest.cc
index a14d448..ce502ac 100644
--- a/api/rtp_packet_infos_unittest.cc
+++ b/api/rtp_packet_infos_unittest.cc
@@ -27,9 +27,9 @@
 }  // namespace
 
 TEST(RtpPacketInfosTest, BasicFunctionality) {
-  RtpPacketInfo p0(123, {1, 2}, 89, 5, 7);
-  RtpPacketInfo p1(456, {3, 4}, 89, 4, 1);
-  RtpPacketInfo p2(789, {5, 6}, 88, 1, 7);
+  RtpPacketInfo p0(123, {1, 2}, 89, 5, AbsoluteCaptureTime{45, 78}, 7);
+  RtpPacketInfo p1(456, {3, 4}, 89, 4, AbsoluteCaptureTime{13, 21}, 1);
+  RtpPacketInfo p2(789, {5, 6}, 88, 1, AbsoluteCaptureTime{99, 78}, 7);
 
   RtpPacketInfos x({p0, p1, p2});
 
@@ -52,9 +52,9 @@
 }
 
 TEST(RtpPacketInfosTest, CopyShareData) {
-  RtpPacketInfo p0(123, {1, 2}, 89, 5, 7);
-  RtpPacketInfo p1(456, {3, 4}, 89, 4, 1);
-  RtpPacketInfo p2(789, {5, 6}, 88, 1, 7);
+  RtpPacketInfo p0(123, {1, 2}, 89, 5, AbsoluteCaptureTime{45, 78}, 7);
+  RtpPacketInfo p1(456, {3, 4}, 89, 4, AbsoluteCaptureTime{13, 21}, 1);
+  RtpPacketInfo p2(789, {5, 6}, 88, 1, AbsoluteCaptureTime{99, 78}, 7);
 
   RtpPacketInfos lhs({p0, p1, p2});
   RtpPacketInfos rhs = lhs;
diff --git a/modules/audio_coding/neteq/red_payload_splitter.cc b/modules/audio_coding/neteq/red_payload_splitter.cc
index 7ff5679..1343690 100644
--- a/modules/audio_coding/neteq/red_payload_splitter.cc
+++ b/modules/audio_coding/neteq/red_payload_splitter.cc
@@ -123,6 +123,7 @@
             /*csrcs=*/std::vector<uint32_t>(),
             /*rtp_timestamp=*/new_packet.timestamp,
             /*audio_level=*/absl::nullopt,
+            /*absolute_capture_time=*/absl::nullopt,
             /*receive_time_ms=*/red_packet.packet_info.receive_time_ms());
         new_packets.push_front(std::move(new_packet));
         payload_ptr += payload_length;
diff --git a/modules/rtp_rtcp/source/source_tracker_unittest.cc b/modules/rtp_rtcp/source/source_tracker_unittest.cc
index 2342697..55ae4d1 100644
--- a/modules/rtp_rtcp/source/source_tracker_unittest.cc
+++ b/modules/rtp_rtcp/source/source_tracker_unittest.cc
@@ -109,6 +109,7 @@
     for (size_t i = 0; i < count; ++i) {
       packet_infos.emplace_back(GenerateSsrc(), GenerateCsrcs(),
                                 GenerateRtpTimestamp(), GenerateAudioLevel(),
+                                GenerateAbsoluteCaptureTime(),
                                 GenerateReceiveTimeMs());
     }
 
@@ -170,6 +171,26 @@
         std::uniform_int_distribution<uint16_t>()(generator_));
   }
 
+  absl::optional<AbsoluteCaptureTime> GenerateAbsoluteCaptureTime() {
+    if (std::bernoulli_distribution(0.25)(generator_)) {
+      return absl::nullopt;
+    }
+
+    AbsoluteCaptureTime value;
+
+    value.absolute_capture_timestamp =
+        std::uniform_int_distribution<uint64_t>()(generator_);
+
+    if (std::bernoulli_distribution(0.5)(generator_)) {
+      value.estimated_capture_clock_offset = absl::nullopt;
+    } else {
+      value.estimated_capture_clock_offset =
+          std::uniform_int_distribution<int64_t>()(generator_);
+    }
+
+    return value;
+  }
+
   int64_t GenerateReceiveTimeMs() {
     return std::uniform_int_distribution<int64_t>()(generator_);
   }
@@ -223,13 +244,15 @@
   constexpr uint32_t kCsrcs1 = 21;
   constexpr uint32_t kRtpTimestamp = 40;
   constexpr absl::optional<uint8_t> kAudioLevel = 50;
+  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime = {};
   constexpr int64_t kReceiveTimeMs = 60;
 
   SimulatedClock clock(1000000000000ULL);
   SourceTracker tracker(&clock);
 
-  tracker.OnFrameDelivered(RtpPacketInfos({RtpPacketInfo(
-      kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp, kAudioLevel, kReceiveTimeMs)}));
+  tracker.OnFrameDelivered(RtpPacketInfos(
+      {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp, kAudioLevel,
+                     kAbsoluteCaptureTime, kReceiveTimeMs)}));
 
   int64_t timestamp_ms = clock.TimeInMilliseconds();
 
@@ -251,23 +274,24 @@
   constexpr uint32_t kRtpTimestamp1 = 41;
   constexpr absl::optional<uint8_t> kAudioLevel0 = 50;
   constexpr absl::optional<uint8_t> kAudioLevel1 = absl::nullopt;
+  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime = {};
   constexpr int64_t kReceiveTimeMs0 = 60;
   constexpr int64_t kReceiveTimeMs1 = 61;
 
   SimulatedClock clock(1000000000000ULL);
   SourceTracker tracker(&clock);
 
-  tracker.OnFrameDelivered(
-      RtpPacketInfos({RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0,
-                                    kAudioLevel0, kReceiveTimeMs0)}));
+  tracker.OnFrameDelivered(RtpPacketInfos(
+      {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kAudioLevel0,
+                     kAbsoluteCaptureTime, kReceiveTimeMs0)}));
 
   int64_t timestamp_ms_0 = clock.TimeInMilliseconds();
 
   clock.AdvanceTimeMilliseconds(17);
 
-  tracker.OnFrameDelivered(
-      RtpPacketInfos({RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs2}, kRtpTimestamp1,
-                                    kAudioLevel1, kReceiveTimeMs1)}));
+  tracker.OnFrameDelivered(RtpPacketInfos(
+      {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs2}, kRtpTimestamp1, kAudioLevel1,
+                     kAbsoluteCaptureTime, kReceiveTimeMs1)}));
 
   int64_t timestamp_ms_1 = clock.TimeInMilliseconds();
 
@@ -292,21 +316,22 @@
   constexpr uint32_t kRtpTimestamp1 = 41;
   constexpr absl::optional<uint8_t> kAudioLevel0 = 50;
   constexpr absl::optional<uint8_t> kAudioLevel1 = absl::nullopt;
+  constexpr absl::optional<AbsoluteCaptureTime> kAbsoluteCaptureTime = {};
   constexpr int64_t kReceiveTimeMs0 = 60;
   constexpr int64_t kReceiveTimeMs1 = 61;
 
   SimulatedClock clock(1000000000000ULL);
   SourceTracker tracker(&clock);
 
-  tracker.OnFrameDelivered(
-      RtpPacketInfos({RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0,
-                                    kAudioLevel0, kReceiveTimeMs0)}));
+  tracker.OnFrameDelivered(RtpPacketInfos(
+      {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs1}, kRtpTimestamp0, kAudioLevel0,
+                     kAbsoluteCaptureTime, kReceiveTimeMs0)}));
 
   clock.AdvanceTimeMilliseconds(17);
 
-  tracker.OnFrameDelivered(
-      RtpPacketInfos({RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs2}, kRtpTimestamp1,
-                                    kAudioLevel1, kReceiveTimeMs1)}));
+  tracker.OnFrameDelivered(RtpPacketInfos(
+      {RtpPacketInfo(kSsrc, {kCsrcs0, kCsrcs2}, kRtpTimestamp1, kAudioLevel1,
+                     kAbsoluteCaptureTime, kReceiveTimeMs1)}));
 
   int64_t timestamp_ms_1 = clock.TimeInMilliseconds();