Introduce RtpPacket::GetExtension accessor that return result

instead of using output parameter.

Bug: None
Change-Id: I1d5c150b7cb6302aa29e040e8c9fe68bddfd8c0e
Reviewed-on: https://webrtc-review.googlesource.com/c/110240
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25565}
diff --git a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h
index 2dd9dd4..0d673e0 100644
--- a/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h
+++ b/modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h
@@ -21,6 +21,7 @@
 
 class RtpGenericFrameDescriptorExtension {
  public:
+  using value_type = RtpGenericFrameDescriptor;
   static constexpr RTPExtensionType kId = kRtpExtensionGenericFrameDescriptor;
   static constexpr char kUri[] =
       "http://www.webrtc.org/experiments/rtp-hdrext/"
diff --git a/modules/rtp_rtcp/source/rtp_header_extensions.h b/modules/rtp_rtcp/source/rtp_header_extensions.h
index cd01c1a..808356a 100644
--- a/modules/rtp_rtcp/source/rtp_header_extensions.h
+++ b/modules/rtp_rtcp/source/rtp_header_extensions.h
@@ -27,6 +27,7 @@
 
 class AbsoluteSendTime {
  public:
+  using value_type = uint32_t;
   static constexpr RTPExtensionType kId = kRtpExtensionAbsoluteSendTime;
   static constexpr uint8_t kValueSizeBytes = 3;
   static constexpr const char kUri[] =
@@ -61,6 +62,7 @@
 
 class TransmissionOffset {
  public:
+  using value_type = int32_t;
   static constexpr RTPExtensionType kId = kRtpExtensionTransmissionTimeOffset;
   static constexpr uint8_t kValueSizeBytes = 3;
   static constexpr const char kUri[] = "urn:ietf:params:rtp-hdrext:toffset";
@@ -72,6 +74,7 @@
 
 class TransportSequenceNumber {
  public:
+  using value_type = uint16_t;
   static constexpr RTPExtensionType kId = kRtpExtensionTransportSequenceNumber;
   static constexpr uint8_t kValueSizeBytes = 2;
   static constexpr const char kUri[] =
@@ -84,6 +87,7 @@
 
 class VideoOrientation {
  public:
+  using value_type = VideoRotation;
   static constexpr RTPExtensionType kId = kRtpExtensionVideoRotation;
   static constexpr uint8_t kValueSizeBytes = 1;
   static constexpr const char kUri[] = "urn:3gpp:video-orientation";
@@ -98,6 +102,7 @@
 
 class PlayoutDelayLimits {
  public:
+  using value_type = PlayoutDelay;
   static constexpr RTPExtensionType kId = kRtpExtensionPlayoutDelay;
   static constexpr uint8_t kValueSizeBytes = 3;
   static constexpr const char kUri[] =
@@ -121,6 +126,7 @@
 
 class VideoContentTypeExtension {
  public:
+  using value_type = VideoContentType;
   static constexpr RTPExtensionType kId = kRtpExtensionVideoContentType;
   static constexpr uint8_t kValueSizeBytes = 1;
   static constexpr const char kUri[] =
@@ -137,6 +143,7 @@
 
 class VideoTimingExtension {
  public:
+  using value_type = VideoSendTiming;
   static constexpr RTPExtensionType kId = kRtpExtensionVideoTiming;
   static constexpr uint8_t kValueSizeBytes = 13;
   static constexpr const char kUri[] =
@@ -159,6 +166,7 @@
 
 class FrameMarkingExtension {
  public:
+  using value_type = FrameMarking;
   static constexpr RTPExtensionType kId = kRtpExtensionFrameMarking;
   static constexpr const char kUri[] =
       "http://tools.ietf.org/html/draft-ietf-avtext-framemarking-07";
@@ -177,6 +185,7 @@
 // Subclasses must defined kId and kUri static constexpr members.
 class BaseRtpStringExtension {
  public:
+  using value_type = std::string;
   // String RTP header extensions are limited to 16 bytes because it is the
   // maximum length that can be encoded with one-byte header extensions.
   static constexpr uint8_t kMaxValueSizeBytes = 16;
diff --git a/modules/rtp_rtcp/source/rtp_packet.h b/modules/rtp_rtcp/source/rtp_packet.h
index 3d7d90c..76666b7 100644
--- a/modules/rtp_rtcp/source/rtp_packet.h
+++ b/modules/rtp_rtcp/source/rtp_packet.h
@@ -12,6 +12,7 @@
 
 #include <vector>
 
+#include "absl/types/optional.h"
 #include "api/array_view.h"
 #include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
@@ -95,8 +96,11 @@
   template <typename Extension>
   bool HasExtension() const;
 
-  template <typename Extension, typename... Values>
-  bool GetExtension(Values...) const;
+  template <typename Extension, typename FirstValue, typename... Values>
+  bool GetExtension(FirstValue, Values...) const;
+
+  template <typename Extension>
+  absl::optional<typename Extension::value_type> GetExtension() const;
 
   // Returns view of the raw extension or empty view on failure.
   template <typename Extension>
@@ -183,12 +187,21 @@
   return !FindExtension(Extension::kId).empty();
 }
 
-template <typename Extension, typename... Values>
-bool RtpPacket::GetExtension(Values... values) const {
+template <typename Extension, typename FirstValue, typename... Values>
+bool RtpPacket::GetExtension(FirstValue first, Values... values) const {
   auto raw = FindExtension(Extension::kId);
   if (raw.empty())
     return false;
-  return Extension::Parse(raw, values...);
+  return Extension::Parse(raw, first, values...);
+}
+
+template <typename Extension>
+absl::optional<typename Extension::value_type> RtpPacket::GetExtension() const {
+  absl::optional<typename Extension::value_type> result;
+  auto raw = FindExtension(Extension::kId);
+  if (raw.empty() || !Extension::Parse(raw, &result.emplace()))
+    result = absl::nullopt;
+  return result;
 }
 
 template <typename Extension>
diff --git a/modules/rtp_rtcp/source/rtp_packet_unittest.cc b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
index 431bf5e..b485df6 100644
--- a/modules/rtp_rtcp/source/rtp_packet_unittest.cc
+++ b/modules/rtp_rtcp/source/rtp_packet_unittest.cc
@@ -466,6 +466,23 @@
   EXPECT_EQ(0u, packet.padding_size());
 }
 
+TEST(RtpPacketTest, GetExtensionWithoutParametersReturnsOptionalValue) {
+  RtpPacket::ExtensionManager extensions;
+  extensions.Register<TransmissionOffset>(kTransmissionOffsetExtensionId);
+  extensions.Register<RtpStreamId>(kRtpStreamIdExtensionId);
+
+  RtpPacketReceived packet(&extensions);
+  EXPECT_TRUE(packet.Parse(kPacketWithTO, sizeof(kPacketWithTO)));
+
+  auto time_offset = packet.GetExtension<TransmissionOffset>();
+  static_assert(
+      std::is_same<decltype(time_offset),
+                   absl::optional<TransmissionOffset::value_type>>::value,
+      "");
+  EXPECT_EQ(time_offset, kTimeOffset);
+  EXPECT_FALSE(packet.GetExtension<RtpStreamId>().has_value());
+}
+
 TEST(RtpPacketTest, GetRawExtensionWhenPresent) {
   constexpr uint8_t kRawPacket[] = {
       // comment for clang-format to align kRawPacket nicer.