Extend make_ref_counted to interoperate with RefCountedNonVirtual

Update RtpPacketInfos internals to use rtc::make_ref_counted, and a
Data class with no virtual methods.

Bug: webrtc:13464, webrtc:12701
Change-Id: I03f6bee69a9f060dcf287284fc779268d5eb433e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/244505
Reviewed-by: Tomas Gunnarsson <tommi@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Niels Moller <nisse@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#35660}
diff --git a/api/DEPS b/api/DEPS
index cadaaa2..0b8a70e 100644
--- a/api/DEPS
+++ b/api/DEPS
@@ -168,6 +168,9 @@
     # For private member and constructor.
     "+rtc_base/system/file_wrapper.h",
   ],
+  "rtp_packet_infos\.h": [
+    "+rtc_base/ref_counted_object.h",
+  ],
   "rtp_receiver_interface\.h": [
     "+rtc_base/ref_count.h",
   ],
diff --git a/api/rtp_packet_infos.h b/api/rtp_packet_infos.h
index 2ca3174..031e333 100644
--- a/api/rtp_packet_infos.h
+++ b/api/rtp_packet_infos.h
@@ -18,6 +18,7 @@
 #include "api/ref_counted_base.h"
 #include "api/rtp_packet_info.h"
 #include "api/scoped_refptr.h"
+#include "rtc_base/ref_counted_object.h"
 #include "rtc_base/system/rtc_export.h"
 
 namespace webrtc {
@@ -79,7 +80,7 @@
   size_type size() const { return entries().size(); }
 
  private:
-  class Data : public rtc::RefCountedBase {
+  class Data final : public rtc::RefCountedNonVirtual<Data> {
    public:
     static rtc::scoped_refptr<Data> Create(const vector_type& entries) {
       // Performance optimization for the empty case.
@@ -87,7 +88,7 @@
         return nullptr;
       }
 
-      return new Data(entries);
+      return rtc::make_ref_counted<Data>(entries);
     }
 
     static rtc::scoped_refptr<Data> Create(vector_type&& entries) {
@@ -96,16 +97,16 @@
         return nullptr;
       }
 
-      return new Data(std::move(entries));
+      return rtc::make_ref_counted<Data>(std::move(entries));
     }
 
     const vector_type& entries() const { return entries_; }
 
-   private:
     explicit Data(const vector_type& entries) : entries_(entries) {}
     explicit Data(vector_type&& entries) : entries_(std::move(entries)) {}
-    ~Data() override {}
+    ~Data() = default;
 
+   private:
     const vector_type entries_;
   };
 
diff --git a/rtc_base/ref_counted_object.h b/rtc_base/ref_counted_object.h
index 2a55d86..37612ad 100644
--- a/rtc_base/ref_counted_object.h
+++ b/rtc_base/ref_counted_object.h
@@ -20,6 +20,23 @@
 
 namespace rtc {
 
+namespace webrtc_make_ref_counted_internal {
+// Determines if the given class has AddRef and Release methods.
+template <typename T>
+class HasAddRefAndRelease {
+ private:
+  template <typename C,
+            decltype(std::declval<C>().AddRef())* = nullptr,
+            decltype(std::declval<C>().Release())* = nullptr>
+  static int Test(int);
+  template <typename>
+  static char Test(...);
+
+ public:
+  static constexpr bool value = std::is_same_v<decltype(Test<T>(0)), int>;
+};
+}  // namespace webrtc_make_ref_counted_internal
+
 template <class T>
 class RefCountedObject : public T {
  public:
@@ -64,10 +81,9 @@
 class FinalRefCountedObject final : public T {
  public:
   using T::T;
-  // Until c++17 compilers are allowed not to inherit the default constructors.
-  // Thus the default constructors are forwarded explicitly.
-  FinalRefCountedObject() = default;
-  explicit FinalRefCountedObject(const T& other) : T(other) {}
+  // Above using declaration propagates a default move constructor
+  // FinalRefCountedObject(FinalRefCountedObject&& other), but we also need
+  // move construction from T.
   explicit FinalRefCountedObject(T&& other) : T(std::move(other)) {}
   FinalRefCountedObject(const FinalRefCountedObject&) = delete;
   FinalRefCountedObject& operator=(const FinalRefCountedObject&) = delete;
@@ -106,8 +122,13 @@
 //
 //   auto p = scoped_refptr<Foo>(new RefCountedObject<Foo>("bar", 123));
 //
-// If the class does not inherit from RefCountInterface, the example is
-// equivalent to:
+// If the class does not inherit from RefCountInterface, but does have
+// AddRef/Release methods (so a T* is convertible to rtc::scoped_refptr), this
+// is equivalent to just
+//
+//   auto p = scoped_refptr<Foo>(new Foo("bar", 123));
+//
+// Otherwise, the example is equivalent to:
 //
 //   auto p = scoped_refptr<FinalRefCountedObject<Foo>>(
 //       new FinalRefCountedObject<Foo>("bar", 123));
@@ -122,22 +143,37 @@
 // needed.
 
 // `make_ref_counted` for classes that are convertible to RefCountInterface.
-template <
-    typename T,
-    typename... Args,
-    typename std::enable_if<std::is_convertible<T*, RefCountInterface*>::value,
-                            T>::type* = nullptr>
+template <typename T,
+          typename... Args,
+          typename std::enable_if<std::is_convertible_v<T*, RefCountInterface*>,
+                                  T>::type* = nullptr>
 scoped_refptr<T> make_ref_counted(Args&&... args) {
   return new RefCountedObject<T>(std::forward<Args>(args)...);
 }
 
 // `make_ref_counted` for complete classes that are not convertible to
-// RefCountInterface.
+// RefCountInterface and already carry a ref count.
 template <
     typename T,
     typename... Args,
-    typename std::enable_if<!std::is_convertible<T*, RefCountInterface*>::value,
-                            T>::type* = nullptr>
+    typename std::enable_if<
+        !std::is_convertible_v<T*, RefCountInterface*> &&
+            webrtc_make_ref_counted_internal::HasAddRefAndRelease<T>::value,
+        T>::type* = nullptr>
+scoped_refptr<T> make_ref_counted(Args&&... args) {
+  return scoped_refptr<T>(new T(std::forward<Args>(args)...));
+}
+
+// `make_ref_counted` for complete classes that are not convertible to
+// RefCountInterface and have no ref count of their own.
+template <
+    typename T,
+    typename... Args,
+    typename std::enable_if<
+        !std::is_convertible_v<T*, RefCountInterface*> &&
+            !webrtc_make_ref_counted_internal::HasAddRefAndRelease<T>::value,
+
+        T>::type* = nullptr>
 scoped_refptr<FinalRefCountedObject<T>> make_ref_counted(Args&&... args) {
   return new FinalRefCountedObject<T>(std::forward<Args>(args)...);
 }
@@ -188,7 +224,7 @@
 template <typename T>
 struct Ref {
   typedef typename std::conditional<
-      std::is_convertible<T*, RefCountInterface*>::value,
+      webrtc_make_ref_counted_internal::HasAddRefAndRelease<T>::value,
       T,
       FinalRefCountedObject<T>>::type Type;