In VideoEncoderFactoryTemplate pass webrtc::Environment to individual traits when supported
Bug: webrtc:15860 Change-Id: I022887e57855c072ddfb0edaf37cd96e9fc64ea6 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/342981 Reviewed-by: Philip Eliasson <philipel@webrtc.org> Commit-Queue: Danil Chapovalov <danilchap@webrtc.org> Cr-Commit-Position: refs/heads/main@{#41909}
This commit is contained in:
parent
98aba6b9a8
commit
dd28f1364b
@ -166,8 +166,9 @@ rtc_source_set("video_encoder_factory_template") {
|
|||||||
|
|
||||||
deps = [
|
deps = [
|
||||||
":video_codecs_api",
|
":video_codecs_api",
|
||||||
"../../api:array_view",
|
"..:array_view",
|
||||||
"../../modules/video_coding/svc:scalability_mode_util",
|
"../../modules/video_coding/svc:scalability_mode_util",
|
||||||
|
"../environment",
|
||||||
]
|
]
|
||||||
|
|
||||||
absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ]
|
absl_deps = [ "//third_party/abseil-cpp/absl/algorithm:container" ]
|
||||||
|
|||||||
@ -66,6 +66,8 @@ if (rtc_include_tests) {
|
|||||||
"..:video_encoder_factory_template_open_h264_adapter",
|
"..:video_encoder_factory_template_open_h264_adapter",
|
||||||
"../../:mock_video_encoder",
|
"../../:mock_video_encoder",
|
||||||
"../../../test:test_support",
|
"../../../test:test_support",
|
||||||
|
"../../environment",
|
||||||
|
"../../environment:environment_factory",
|
||||||
"//testing/gtest",
|
"//testing/gtest",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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_encoder.h"
|
#include "api/test/mock_video_encoder.h"
|
||||||
#include "api/video_codecs/video_encoder_factory_template.h"
|
#include "api/video_codecs/video_encoder_factory_template.h"
|
||||||
#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h"
|
#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h"
|
||||||
@ -17,6 +19,9 @@
|
|||||||
#include "test/gmock.h"
|
#include "test/gmock.h"
|
||||||
#include "test/gtest.h"
|
#include "test/gtest.h"
|
||||||
|
|
||||||
|
namespace webrtc {
|
||||||
|
namespace {
|
||||||
|
|
||||||
using ::testing::Contains;
|
using ::testing::Contains;
|
||||||
using ::testing::Each;
|
using ::testing::Each;
|
||||||
using ::testing::Eq;
|
using ::testing::Eq;
|
||||||
@ -25,11 +30,10 @@ using ::testing::IsEmpty;
|
|||||||
using ::testing::IsNull;
|
using ::testing::IsNull;
|
||||||
using ::testing::Not;
|
using ::testing::Not;
|
||||||
using ::testing::NotNull;
|
using ::testing::NotNull;
|
||||||
|
using ::testing::StrictMock;
|
||||||
using ::testing::UnorderedElementsAre;
|
using ::testing::UnorderedElementsAre;
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
namespace {
|
|
||||||
using CodecSupport = VideoEncoderFactory::CodecSupport;
|
using CodecSupport = VideoEncoderFactory::CodecSupport;
|
||||||
|
|
||||||
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"}});
|
||||||
@ -39,7 +43,7 @@ struct FooEncoderTemplateAdapter {
|
|||||||
|
|
||||||
static std::unique_ptr<VideoEncoder> CreateEncoder(
|
static std::unique_ptr<VideoEncoder> CreateEncoder(
|
||||||
const SdpVideoFormat& format) {
|
const SdpVideoFormat& format) {
|
||||||
return std::make_unique<testing::StrictMock<MockVideoEncoder>>();
|
return std::make_unique<StrictMock<MockVideoEncoder>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
|
static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
|
||||||
@ -54,8 +58,9 @@ struct BarEncoderTemplateAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<VideoEncoder> CreateEncoder(
|
static std::unique_ptr<VideoEncoder> CreateEncoder(
|
||||||
|
const Environment& env,
|
||||||
const SdpVideoFormat& format) {
|
const SdpVideoFormat& format) {
|
||||||
return std::make_unique<testing::StrictMock<MockVideoEncoder>>();
|
return std::make_unique<StrictMock<MockVideoEncoder>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
|
static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
|
||||||
@ -67,10 +72,11 @@ struct BarEncoderTemplateAdapter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCreateEncoder) {
|
TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCreateEncoder) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
|
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
|
||||||
EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
|
EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), NotNull());
|
EXPECT_THAT(factory.Create(env, kFooSdp), NotNull());
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), IsNull());
|
EXPECT_THAT(factory.Create(env, SdpVideoFormat("FooX")), IsNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCodecSupport) {
|
TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCodecSupport) {
|
||||||
@ -93,16 +99,27 @@ TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCreateEncoders) {
|
TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCreateEncoders) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
|
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
|
||||||
BarEncoderTemplateAdapter>
|
BarEncoderTemplateAdapter>
|
||||||
factory;
|
factory;
|
||||||
EXPECT_THAT(factory.GetSupportedFormats(),
|
EXPECT_THAT(factory.GetSupportedFormats(),
|
||||||
UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp));
|
UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp));
|
||||||
|
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")), NotNull());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(VideoEncoderFactoryTemplate,
|
||||||
|
CreatesEncoderWithoutEnvironmentWhenNotNeeded) {
|
||||||
|
// FooEncoderTemplateAdapter::CreateEncoder doesn't take Environment parameter
|
||||||
|
// Expect it can be created both with newer and older api.
|
||||||
|
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
|
||||||
|
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), NotNull());
|
EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), NotNull());
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(kBarLowSdp), NotNull());
|
EXPECT_THAT(factory.Create(CreateEnvironment(), kFooSdp), NotNull());
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(kBarHighSdp), NotNull());
|
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), IsNull());
|
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("Bar")), NotNull());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCodecSupport) {
|
TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCodecSupport) {
|
||||||
@ -126,47 +143,51 @@ TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCodecSupport) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TEST(VideoEncoderFactoryTemplate, LibvpxVp8) {
|
TEST(VideoEncoderFactoryTemplate, LibvpxVp8) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
VideoEncoderFactoryTemplate<LibvpxVp8EncoderTemplateAdapter> factory;
|
VideoEncoderFactoryTemplate<LibvpxVp8EncoderTemplateAdapter> factory;
|
||||||
auto formats = factory.GetSupportedFormats();
|
auto formats = factory.GetSupportedFormats();
|
||||||
EXPECT_THAT(formats.size(), 1);
|
EXPECT_THAT(formats.size(), 1);
|
||||||
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "VP8"));
|
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "VP8"));
|
||||||
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
|
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
|
||||||
Contains(ScalabilityMode::kL1T3)));
|
Contains(ScalabilityMode::kL1T3)));
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull());
|
EXPECT_THAT(factory.Create(env, formats[0]), NotNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(VideoEncoderFactoryTemplate, LibvpxVp9) {
|
TEST(VideoEncoderFactoryTemplate, LibvpxVp9) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
VideoEncoderFactoryTemplate<LibvpxVp9EncoderTemplateAdapter> factory;
|
VideoEncoderFactoryTemplate<LibvpxVp9EncoderTemplateAdapter> 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(formats, Each(Field(&SdpVideoFormat::scalability_modes,
|
EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes,
|
||||||
Contains(ScalabilityMode::kL3T3_KEY))));
|
Contains(ScalabilityMode::kL3T3_KEY))));
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull());
|
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(VideoEncoderFactoryTemplate, OpenH264) {
|
TEST(VideoEncoderFactoryTemplate, OpenH264) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
VideoEncoderFactoryTemplate<OpenH264EncoderTemplateAdapter> factory;
|
VideoEncoderFactoryTemplate<OpenH264EncoderTemplateAdapter> 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(formats, Each(Field(&SdpVideoFormat::scalability_modes,
|
EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes,
|
||||||
Contains(ScalabilityMode::kL1T3))));
|
Contains(ScalabilityMode::kL1T3))));
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull());
|
EXPECT_THAT(factory.Create(env, formats[0]), NotNull());
|
||||||
}
|
}
|
||||||
#endif // defined(WEBRTC_USE_H264)
|
#endif // defined(WEBRTC_USE_H264)
|
||||||
|
|
||||||
TEST(VideoEncoderFactoryTemplate, LibaomAv1) {
|
TEST(VideoEncoderFactoryTemplate, LibaomAv1) {
|
||||||
|
const Environment env = CreateEnvironment();
|
||||||
VideoEncoderFactoryTemplate<LibaomAv1EncoderTemplateAdapter> factory;
|
VideoEncoderFactoryTemplate<LibaomAv1EncoderTemplateAdapter> factory;
|
||||||
auto formats = factory.GetSupportedFormats();
|
auto formats = factory.GetSupportedFormats();
|
||||||
EXPECT_THAT(formats.size(), 1);
|
EXPECT_THAT(formats.size(), 1);
|
||||||
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "AV1"));
|
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "AV1"));
|
||||||
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
|
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
|
||||||
Contains(ScalabilityMode::kL3T3_KEY)));
|
Contains(ScalabilityMode::kL3T3_KEY)));
|
||||||
EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull());
|
EXPECT_THAT(factory.Create(env, formats[0]), NotNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -13,10 +13,12 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#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/sdp_video_format.h"
|
#include "api/video_codecs/sdp_video_format.h"
|
||||||
#include "api/video_codecs/video_encoder.h"
|
#include "api/video_codecs/video_encoder.h"
|
||||||
#include "api/video_codecs/video_encoder_factory.h"
|
#include "api/video_codecs/video_encoder_factory.h"
|
||||||
@ -34,7 +36,8 @@ namespace webrtc {
|
|||||||
//
|
//
|
||||||
// // Creates an encoder instance for the given format.
|
// // Creates an encoder instance for the given format.
|
||||||
// static std::unique_ptr<VideoEncoder>
|
// static std::unique_ptr<VideoEncoder>
|
||||||
// CreateEncoder(const SdpVideoFormat& format);
|
// CreateEncoder(const Environment& env,
|
||||||
|
// const SdpVideoFormat& format);
|
||||||
//
|
//
|
||||||
// // Returns true if the encoder supports the given scalability mode.
|
// // Returns true if the encoder supports the given scalability mode.
|
||||||
// static bool
|
// static bool
|
||||||
@ -64,6 +67,20 @@ class VideoEncoderFactoryTemplate : public VideoEncoderFactory {
|
|||||||
return CreateVideoEncoderInternal<Ts...>(matched.value_or(format));
|
return CreateVideoEncoderInternal<Ts...>(matched.value_or(format));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<VideoEncoder> Create(const Environment& env,
|
||||||
|
const SdpVideoFormat& format) override {
|
||||||
|
// We fuzzy match the specified format for both valid and not so valid
|
||||||
|
// reasons. The valid reason is that there are many standardized codec
|
||||||
|
// specific fmtp parameters that have not been implemented, and in those
|
||||||
|
// cases we should not fail to instantiate an encoder just because we don't
|
||||||
|
// recognize the parameter. The not so valid reason is that we have started
|
||||||
|
// adding parameters completely unrelated to the SDP to the SdpVideoFormat.
|
||||||
|
// TODO: bugs.webrtc.org/13868 - Remove FuzzyMatchSdpVideoFormat
|
||||||
|
absl::optional<SdpVideoFormat> matched =
|
||||||
|
FuzzyMatchSdpVideoFormat(GetSupportedFormats(), format);
|
||||||
|
return CreateInternal<Ts...>(env, matched.value_or(format));
|
||||||
|
}
|
||||||
|
|
||||||
CodecSupport QueryCodecSupport(
|
CodecSupport QueryCodecSupport(
|
||||||
const SdpVideoFormat& format,
|
const SdpVideoFormat& format,
|
||||||
absl::optional<std::string> scalability_mode) const override {
|
absl::optional<std::string> scalability_mode) const override {
|
||||||
@ -114,8 +131,17 @@ class VideoEncoderFactoryTemplate : public VideoEncoderFactory {
|
|||||||
std::unique_ptr<VideoEncoder> CreateVideoEncoderInternal(
|
std::unique_ptr<VideoEncoder> CreateVideoEncoderInternal(
|
||||||
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<VideoEncoder>,
|
||||||
|
decltype(V::CreateEncoder),
|
||||||
|
const Environment&,
|
||||||
|
const SdpVideoFormat&>) {
|
||||||
|
// Newer code shouldn't call `CreateVideoEncoder` function,
|
||||||
|
// Older code should only use traits where Environmnet is not required.
|
||||||
|
RTC_CHECK_NOTREACHED();
|
||||||
|
} else {
|
||||||
return V::CreateEncoder(format);
|
return V::CreateEncoder(format);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if constexpr (sizeof...(Vs) > 0) {
|
if constexpr (sizeof...(Vs) > 0) {
|
||||||
return CreateVideoEncoderInternal<Vs...>(format);
|
return CreateVideoEncoderInternal<Vs...>(format);
|
||||||
@ -124,6 +150,27 @@ class VideoEncoderFactoryTemplate : public VideoEncoderFactory {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename V, typename... Vs>
|
||||||
|
std::unique_ptr<VideoEncoder> CreateInternal(const Environment& env,
|
||||||
|
const SdpVideoFormat& format) {
|
||||||
|
if (IsFormatInList(format, V::SupportedFormats())) {
|
||||||
|
if constexpr (std::is_invocable_r_v<std::unique_ptr<VideoEncoder>,
|
||||||
|
decltype(V::CreateEncoder),
|
||||||
|
const Environment&,
|
||||||
|
const SdpVideoFormat&>) {
|
||||||
|
return V::CreateEncoder(env, format);
|
||||||
|
} else {
|
||||||
|
return V::CreateEncoder(format);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (sizeof...(Vs) > 0) {
|
||||||
|
return CreateInternal<Vs...>(env, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename V, typename... Vs>
|
template <typename V, typename... Vs>
|
||||||
CodecSupport QueryCodecSupportInternal(
|
CodecSupport QueryCodecSupportInternal(
|
||||||
const SdpVideoFormat& format,
|
const SdpVideoFormat& format,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user