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}
This commit is contained in:
Danil Chapovalov 2024-02-21 13:16:19 +01:00 committed by WebRTC LUCI CQ
parent bff68580b5
commit 9cd5c3f48e
5 changed files with 56 additions and 30 deletions

View file

@ -231,7 +231,8 @@ rtc_source_set("video_decoder_factory_template") {
deps = [ deps = [
":video_codecs_api", ":video_codecs_api",
"../../api:array_view", "..:array_view",
"../environment",
] ]
absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ] absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ]
@ -245,6 +246,7 @@ rtc_source_set("video_decoder_factory_template_libvpx_vp8_adapter") {
deps = [ deps = [
":video_codecs_api", ":video_codecs_api",
"../../modules/video_coding:webrtc_vp8", "../../modules/video_coding:webrtc_vp8",
"../environment",
] ]
} }

View file

@ -83,6 +83,8 @@ if (rtc_include_tests) {
"..:video_decoder_factory_template_open_h264_adapter", "..:video_decoder_factory_template_open_h264_adapter",
"../../:mock_video_decoder", "../../:mock_video_decoder",
"../../../test:test_support", "../../../test:test_support",
"../../environment",
"../../environment:environment_factory",
"//testing/gtest", "//testing/gtest",
] ]
} }

View file

@ -8,6 +8,8 @@
* be found in the AUTHORS file in the root of the source tree. * 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/test/mock_video_decoder.h"
#include "api/video_codecs/video_decoder_factory_template.h" #include "api/video_codecs/video_decoder_factory_template.h"
#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h" #include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h"
@ -17,17 +19,17 @@
#include "test/gmock.h" #include "test/gmock.h"
#include "test/gtest.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 webrtc {
namespace { 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 kFooSdp("Foo");
const SdpVideoFormat kBarLowSdp("Bar", {{"profile", "low"}}); const SdpVideoFormat kBarLowSdp("Bar", {{"profile", "low"}});
const SdpVideoFormat kBarHighSdp("Bar", {{"profile", "high"}}); const SdpVideoFormat kBarHighSdp("Bar", {{"profile", "high"}});
@ -49,6 +51,7 @@ struct BarDecoderTemplateAdapter {
} }
static std::unique_ptr<VideoDecoder> CreateDecoder( static std::unique_ptr<VideoDecoder> CreateDecoder(
const Environment& env,
const SdpVideoFormat& format) { const SdpVideoFormat& format) {
auto decoder = std::make_unique<testing::StrictMock<MockVideoDecoder>>(); auto decoder = std::make_unique<testing::StrictMock<MockVideoDecoder>>();
EXPECT_CALL(*decoder, Destruct); EXPECT_CALL(*decoder, Destruct);
@ -57,10 +60,11 @@ struct BarDecoderTemplateAdapter {
}; };
TEST(VideoDecoderFactoryTemplate, OneTemplateAdapterCreateDecoder) { TEST(VideoDecoderFactoryTemplate, OneTemplateAdapterCreateDecoder) {
const Environment env = CreateEnvironment();
VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter> factory; VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter> factory;
EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp)); EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
EXPECT_THAT(factory.CreateVideoDecoder(kFooSdp), Ne(nullptr)); EXPECT_THAT(factory.Create(env, kFooSdp), NotNull());
EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("FooX")), Eq(nullptr)); EXPECT_THAT(factory.Create(env, SdpVideoFormat("FooX")), IsNull());
} }
TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) { TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) {
@ -71,52 +75,57 @@ TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) {
} }
TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersCreateDecoders) { TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersCreateDecoders) {
const Environment env = CreateEnvironment();
VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter, VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter,
BarDecoderTemplateAdapter> BarDecoderTemplateAdapter>
factory; factory;
EXPECT_THAT(factory.GetSupportedFormats(), EXPECT_THAT(factory.GetSupportedFormats(),
UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp)); UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp));
EXPECT_THAT(factory.CreateVideoDecoder(kFooSdp), Ne(nullptr)); EXPECT_THAT(factory.Create(env, kFooSdp), NotNull());
EXPECT_THAT(factory.CreateVideoDecoder(kBarLowSdp), Ne(nullptr)); EXPECT_THAT(factory.Create(env, kBarLowSdp), NotNull());
EXPECT_THAT(factory.CreateVideoDecoder(kBarHighSdp), Ne(nullptr)); EXPECT_THAT(factory.Create(env, kBarHighSdp), NotNull());
EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("FooX")), Eq(nullptr)); EXPECT_THAT(factory.Create(env, SdpVideoFormat("FooX")), IsNull());
EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("Bar")), Eq(nullptr)); EXPECT_THAT(factory.Create(env, SdpVideoFormat("Bar")), IsNull());
} }
TEST(VideoDecoderFactoryTemplate, LibvpxVp8) { TEST(VideoDecoderFactoryTemplate, LibvpxVp8) {
const Environment env = CreateEnvironment();
VideoDecoderFactoryTemplate<LibvpxVp8DecoderTemplateAdapter> factory; VideoDecoderFactoryTemplate<LibvpxVp8DecoderTemplateAdapter> factory;
auto formats = factory.GetSupportedFormats(); auto formats = factory.GetSupportedFormats();
EXPECT_THAT(formats.size(), 1); ASSERT_THAT(formats,
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "VP8")); UnorderedElementsAre(Field(&SdpVideoFormat::name, "VP8")));
EXPECT_THAT(factory.CreateVideoDecoder(formats[0]), Ne(nullptr)); EXPECT_THAT(factory.Create(env, formats[0]), NotNull());
} }
TEST(VideoDecoderFactoryTemplate, LibvpxVp9) { TEST(VideoDecoderFactoryTemplate, LibvpxVp9) {
const Environment env = CreateEnvironment();
VideoDecoderFactoryTemplate<LibvpxVp9DecoderTemplateAdapter> factory; VideoDecoderFactoryTemplate<LibvpxVp9DecoderTemplateAdapter> factory;
auto formats = factory.GetSupportedFormats(); auto formats = factory.GetSupportedFormats();
EXPECT_THAT(formats, Not(IsEmpty())); EXPECT_THAT(formats, Not(IsEmpty()));
EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "VP9"))); 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 // TODO(bugs.webrtc.org/13573): When OpenH264 is no longer a conditional build
// target remove this #ifdef. // target remove this #ifdef.
#if defined(WEBRTC_USE_H264) #if defined(WEBRTC_USE_H264)
TEST(VideoDecoderFactoryTemplate, OpenH264) { TEST(VideoDecoderFactoryTemplate, OpenH264) {
const Environment env = CreateEnvironment();
VideoDecoderFactoryTemplate<OpenH264DecoderTemplateAdapter> factory; VideoDecoderFactoryTemplate<OpenH264DecoderTemplateAdapter> factory;
auto formats = factory.GetSupportedFormats(); auto formats = factory.GetSupportedFormats();
EXPECT_THAT(formats, Not(IsEmpty())); EXPECT_THAT(formats, Not(IsEmpty()));
EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "H264"))); 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) #endif // defined(WEBRTC_USE_H264)
TEST(VideoDecoderFactoryTemplate, Dav1d) { TEST(VideoDecoderFactoryTemplate, Dav1d) {
const Environment env = CreateEnvironment();
VideoDecoderFactoryTemplate<Dav1dDecoderTemplateAdapter> factory; VideoDecoderFactoryTemplate<Dav1dDecoderTemplateAdapter> factory;
auto formats = factory.GetSupportedFormats(); auto formats = factory.GetSupportedFormats();
EXPECT_THAT(formats, Not(IsEmpty())); EXPECT_THAT(formats, Not(IsEmpty()));
EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "AV1"))); 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 } // namespace

View file

@ -12,10 +12,12 @@
#define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_H_ #define API_VIDEO_CODECS_VIDEO_DECODER_FACTORY_TEMPLATE_H_
#include <memory> #include <memory>
#include <type_traits>
#include <vector> #include <vector>
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include "api/array_view.h" #include "api/array_view.h"
#include "api/environment/environment.h"
#include "api/video_codecs/video_decoder.h" #include "api/video_codecs/video_decoder.h"
#include "api/video_codecs/video_decoder_factory.h" #include "api/video_codecs/video_decoder_factory.h"
@ -31,7 +33,8 @@ namespace webrtc {
// //
// // Creates a decoder instance for the given format. // // Creates a decoder instance for the given format.
// static std::unique_ptr<VideoDecoder> // 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 // Note that the order of the template arguments matter as the factory will
// return the first decoder implementation supporting the given SdpVideoFormat. // return the first decoder implementation supporting the given SdpVideoFormat.
@ -42,9 +45,9 @@ class VideoDecoderFactoryTemplate : public VideoDecoderFactory {
return GetSupportedFormatsInternal<Ts...>(); return GetSupportedFormatsInternal<Ts...>();
} }
std::unique_ptr<VideoDecoder> CreateVideoDecoder( std::unique_ptr<VideoDecoder> Create(const Environment& env,
const SdpVideoFormat& format) override { const SdpVideoFormat& format) override {
return CreateVideoDecoderInternal<Ts...>(format); return CreateVideoDecoderInternal<Ts...>(env, format);
} }
private: private:
@ -77,13 +80,21 @@ class VideoDecoderFactoryTemplate : public VideoDecoderFactory {
template <typename V, typename... Vs> template <typename V, typename... Vs>
std::unique_ptr<VideoDecoder> CreateVideoDecoderInternal( std::unique_ptr<VideoDecoder> CreateVideoDecoderInternal(
const Environment& env,
const SdpVideoFormat& format) { const SdpVideoFormat& format) {
if (IsFormatInList(format, V::SupportedFormats())) { if (IsFormatInList(format, V::SupportedFormats())) {
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); return V::CreateDecoder(format);
} }
}
if constexpr (sizeof...(Vs) > 0) { if constexpr (sizeof...(Vs) > 0) {
return CreateVideoDecoderInternal<Vs...>(format); return CreateVideoDecoderInternal<Vs...>(env, format);
} }
return nullptr; return nullptr;

View file

@ -14,6 +14,7 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "api/environment/environment.h"
#include "api/video_codecs/sdp_video_format.h" #include "api/video_codecs/sdp_video_format.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h" #include "modules/video_coding/codecs/vp8/include/vp8.h"
@ -24,8 +25,9 @@ struct LibvpxVp8DecoderTemplateAdapter {
} }
static std::unique_ptr<VideoDecoder> CreateDecoder( static std::unique_ptr<VideoDecoder> CreateDecoder(
const Environment& env,
const SdpVideoFormat& format) { const SdpVideoFormat& format) {
return VP8Decoder::Create(); return CreateVp8Decoder(env);
} }
}; };
} // namespace webrtc } // namespace webrtc