Pass webrtc::Environment through VideoDecoderFactoryTemplate::Create

Bug: webrtc:15791
Change-Id: Ia648995b7edd53a59f64afde0d74994b68524d39
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/340142
Reviewed-by: Philip Eliasson <philipel@webrtc.org>
Commit-Queue: Danil Chapovalov <danilchap@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#41783}
diff --git a/api/video_codecs/BUILD.gn b/api/video_codecs/BUILD.gn
index 9f7022c..3310a51 100644
--- a/api/video_codecs/BUILD.gn
+++ b/api/video_codecs/BUILD.gn
@@ -231,7 +231,8 @@
 
   deps = [
     ":video_codecs_api",
-    "../../api:array_view",
+    "..:array_view",
+    "../environment",
   ]
 
   absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ]
@@ -245,6 +246,7 @@
   deps = [
     ":video_codecs_api",
     "../../modules/video_coding:webrtc_vp8",
+    "../environment",
   ]
 }
 
diff --git a/api/video_codecs/test/BUILD.gn b/api/video_codecs/test/BUILD.gn
index be897ae..97371b9 100644
--- a/api/video_codecs/test/BUILD.gn
+++ b/api/video_codecs/test/BUILD.gn
@@ -83,6 +83,8 @@
       "..:video_decoder_factory_template_open_h264_adapter",
       "../../:mock_video_decoder",
       "../../../test:test_support",
+      "../../environment",
+      "../../environment:environment_factory",
       "//testing/gtest",
     ]
   }
diff --git a/api/video_codecs/test/video_decoder_factory_template_tests.cc b/api/video_codecs/test/video_decoder_factory_template_tests.cc
index 1cc2b58..f0b6275 100644
--- a/api/video_codecs/test/video_decoder_factory_template_tests.cc
+++ b/api/video_codecs/test/video_decoder_factory_template_tests.cc
@@ -8,6 +8,8 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include "api/environment/environment.h"
+#include "api/environment/environment_factory.h"
 #include "api/test/mock_video_decoder.h"
 #include "api/video_codecs/video_decoder_factory_template.h"
 #include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h"
@@ -17,17 +19,17 @@
 #include "test/gmock.h"
 #include "test/gtest.h"
 
-using ::testing::Contains;
-using ::testing::Each;
-using ::testing::Eq;
-using ::testing::Field;
-using ::testing::IsEmpty;
-using ::testing::Ne;
-using ::testing::Not;
-using ::testing::UnorderedElementsAre;
-
 namespace webrtc {
 namespace {
+
+using ::testing::Each;
+using ::testing::Field;
+using ::testing::IsEmpty;
+using ::testing::IsNull;
+using ::testing::Not;
+using ::testing::NotNull;
+using ::testing::UnorderedElementsAre;
+
 const SdpVideoFormat kFooSdp("Foo");
 const SdpVideoFormat kBarLowSdp("Bar", {{"profile", "low"}});
 const SdpVideoFormat kBarHighSdp("Bar", {{"profile", "high"}});
@@ -49,6 +51,7 @@
   }
 
   static std::unique_ptr<VideoDecoder> CreateDecoder(
+      const Environment& env,
       const SdpVideoFormat& format) {
     auto decoder = std::make_unique<testing::StrictMock<MockVideoDecoder>>();
     EXPECT_CALL(*decoder, Destruct);
@@ -57,10 +60,11 @@
 };
 
 TEST(VideoDecoderFactoryTemplate, OneTemplateAdapterCreateDecoder) {
+  const Environment env = CreateEnvironment();
   VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter> factory;
   EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
-  EXPECT_THAT(factory.CreateVideoDecoder(kFooSdp), Ne(nullptr));
-  EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("FooX")), Eq(nullptr));
+  EXPECT_THAT(factory.Create(env, kFooSdp), NotNull());
+  EXPECT_THAT(factory.Create(env, SdpVideoFormat("FooX")), IsNull());
 }
 
 TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) {
@@ -71,52 +75,57 @@
 }
 
 TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersCreateDecoders) {
+  const Environment env = CreateEnvironment();
   VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter,
                               BarDecoderTemplateAdapter>
       factory;
   EXPECT_THAT(factory.GetSupportedFormats(),
               UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp));
-  EXPECT_THAT(factory.CreateVideoDecoder(kFooSdp), Ne(nullptr));
-  EXPECT_THAT(factory.CreateVideoDecoder(kBarLowSdp), Ne(nullptr));
-  EXPECT_THAT(factory.CreateVideoDecoder(kBarHighSdp), Ne(nullptr));
-  EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("FooX")), Eq(nullptr));
-  EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("Bar")), Eq(nullptr));
+  EXPECT_THAT(factory.Create(env, kFooSdp), NotNull());
+  EXPECT_THAT(factory.Create(env, kBarLowSdp), NotNull());
+  EXPECT_THAT(factory.Create(env, kBarHighSdp), NotNull());
+  EXPECT_THAT(factory.Create(env, SdpVideoFormat("FooX")), IsNull());
+  EXPECT_THAT(factory.Create(env, SdpVideoFormat("Bar")), IsNull());
 }
 
 TEST(VideoDecoderFactoryTemplate, LibvpxVp8) {
+  const Environment env = CreateEnvironment();
   VideoDecoderFactoryTemplate<LibvpxVp8DecoderTemplateAdapter> factory;
   auto formats = factory.GetSupportedFormats();
-  EXPECT_THAT(formats.size(), 1);
-  EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "VP8"));
-  EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr));
+  ASSERT_THAT(formats,
+              UnorderedElementsAre(Field(&SdpVideoFormat::name, "VP8")));
+  EXPECT_THAT(factory.Create(env, formats[0]), NotNull());
 }
 
 TEST(VideoDecoderFactoryTemplate, LibvpxVp9) {
+  const Environment env = CreateEnvironment();
   VideoDecoderFactoryTemplate<LibvpxVp9DecoderTemplateAdapter> factory;
   auto formats = factory.GetSupportedFormats();
   EXPECT_THAT(formats, Not(IsEmpty()));
   EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "VP9")));
-  EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr));
+  EXPECT_THAT(factory.Create(env, formats[0]), NotNull());
 }
 
 // TODO(bugs.webrtc.org/13573): When OpenH264 is no longer a conditional build
 //                              target remove this #ifdef.
 #if defined(WEBRTC_USE_H264)
 TEST(VideoDecoderFactoryTemplate, OpenH264) {
+  const Environment env = CreateEnvironment();
   VideoDecoderFactoryTemplate<OpenH264DecoderTemplateAdapter> factory;
   auto formats = factory.GetSupportedFormats();
   EXPECT_THAT(formats, Not(IsEmpty()));
   EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "H264")));
-  EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr));
+  EXPECT_THAT(factory.Create(env, formats[0]), NotNull());
 }
 #endif  // defined(WEBRTC_USE_H264)
 
 TEST(VideoDecoderFactoryTemplate, Dav1d) {
+  const Environment env = CreateEnvironment();
   VideoDecoderFactoryTemplate<Dav1dDecoderTemplateAdapter> factory;
   auto formats = factory.GetSupportedFormats();
   EXPECT_THAT(formats, Not(IsEmpty()));
   EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "AV1")));
-  EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr));
+  EXPECT_THAT(factory.Create(env, formats[0]), NotNull());
 }
 
 }  // namespace
diff --git a/api/video_codecs/video_decoder_factory_template.h b/api/video_codecs/video_decoder_factory_template.h
index 703ae11..e859615 100644
--- a/api/video_codecs/video_decoder_factory_template.h
+++ b/api/video_codecs/video_decoder_factory_template.h
@@ -12,10 +12,12 @@
 #define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_H_
 
 #include <memory>
+#include <type_traits>
 #include <vector>
 
 #include "absl/algorithm/container.h"
 #include "api/array_view.h"
+#include "api/environment/environment.h"
 #include "api/video_codecs/video_decoder.h"
 #include "api/video_codecs/video_decoder_factory.h"
 
@@ -31,7 +33,8 @@
 //
 //   // Creates a decoder instance for the given format.
 //   static std::unique_ptr<VideoDecoder>
-//       CreateDecoder(const SdpVideoFormat& format);
+//       CreateDecoder(const Environment& env,
+//                     const SdpVideoFormat& format);
 //
 // Note that the order of the template arguments matter as the factory will
 // return the first decoder implementation supporting the given SdpVideoFormat.
@@ -42,9 +45,9 @@
     return GetSupportedFormatsInternal<Ts...>();
   }
 
-  std::unique_ptr<VideoDecoder> CreateVideoDecoder(
-      const SdpVideoFormat& format) override {
-    return CreateVideoDecoderInternal<Ts...>(format);
+  std::unique_ptr<VideoDecoder> Create(const Environment& env,
+                                       const SdpVideoFormat& format) override {
+    return CreateVideoDecoderInternal<Ts...>(env, format);
   }
 
  private:
@@ -77,13 +80,21 @@
 
   template <typename V, typename... Vs>
   std::unique_ptr<VideoDecoder> CreateVideoDecoderInternal(
+      const Environment& env,
       const SdpVideoFormat& format) {
     if (IsFormatInList(format, V::SupportedFormats())) {
-      return V::CreateDecoder(format);
+      if constexpr (std::is_invocable_r_v<std::unique_ptr<VideoDecoder>,
+                                          decltype(V::CreateDecoder),
+                                          const Environment&,
+                                          const SdpVideoFormat&>) {
+        return V::CreateDecoder(env, format);
+      } else {
+        return V::CreateDecoder(format);
+      }
     }
 
     if constexpr (sizeof...(Vs) > 0) {
-      return CreateVideoDecoderInternal<Vs...>(format);
+      return CreateVideoDecoderInternal<Vs...>(env, format);
     }
 
     return nullptr;
diff --git a/api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h b/api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h
index 0c45a4b..2f4beda 100644
--- a/api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h
+++ b/api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h
@@ -14,6 +14,7 @@
 #include <memory>
 #include <vector>
 
+#include "api/environment/environment.h"
 #include "api/video_codecs/sdp_video_format.h"
 #include "modules/video_coding/codecs/vp8/include/vp8.h"
 
@@ -24,8 +25,9 @@
   }
 
   static std::unique_ptr<VideoDecoder> CreateDecoder(
+      const Environment& env,
       const SdpVideoFormat& format) {
-    return VP8Decoder::Create();
+    return CreateVp8Decoder(env);
   }
 };
 }  // namespace webrtc