1 /*
2 * Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "api/test/mock_video_encoder.h"
12 #include "api/video_codecs/video_encoder_factory_template.h"
13 #include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h"
14 #include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h"
15 #include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h"
16 #include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h"
17 #include "test/gmock.h"
18 #include "test/gtest.h"
19
20 using ::testing::Contains;
21 using ::testing::Each;
22 using ::testing::Eq;
23 using ::testing::Field;
24 using ::testing::IsEmpty;
25 using ::testing::Ne;
26 using ::testing::Not;
27 using ::testing::UnorderedElementsAre;
28
29 namespace webrtc {
30 namespace {
31 using CodecSupport = VideoEncoderFactory::CodecSupport;
32 const SdpVideoFormat kFooSdp("Foo");
33 const SdpVideoFormat kBarLowSdp("Bar", {{"profile", "low"}});
34 const SdpVideoFormat kBarHighSdp("Bar", {{"profile", "high"}});
35
36 struct FooEncoderTemplateAdapter {
SupportedFormatswebrtc::__anon59128d390111::FooEncoderTemplateAdapter37 static std::vector<SdpVideoFormat> SupportedFormats() { return {kFooSdp}; }
38
CreateEncoderwebrtc::__anon59128d390111::FooEncoderTemplateAdapter39 static std::unique_ptr<VideoEncoder> CreateEncoder(
40 const SdpVideoFormat& format) {
41 return std::make_unique<testing::StrictMock<MockVideoEncoder>>();
42 }
43
IsScalabilityModeSupportedwebrtc::__anon59128d390111::FooEncoderTemplateAdapter44 static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
45 return scalability_mode == ScalabilityMode::kL1T2 ||
46 scalability_mode == ScalabilityMode::kL1T3;
47 }
48 };
49
50 struct BarEncoderTemplateAdapter {
SupportedFormatswebrtc::__anon59128d390111::BarEncoderTemplateAdapter51 static std::vector<SdpVideoFormat> SupportedFormats() {
52 return {kBarLowSdp, kBarHighSdp};
53 }
54
CreateEncoderwebrtc::__anon59128d390111::BarEncoderTemplateAdapter55 static std::unique_ptr<VideoEncoder> CreateEncoder(
56 const SdpVideoFormat& format) {
57 return std::make_unique<testing::StrictMock<MockVideoEncoder>>();
58 }
59
IsScalabilityModeSupportedwebrtc::__anon59128d390111::BarEncoderTemplateAdapter60 static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
61 return scalability_mode == ScalabilityMode::kL1T2 ||
62 scalability_mode == ScalabilityMode::kL1T3 ||
63 scalability_mode == ScalabilityMode::kS2T1 ||
64 scalability_mode == ScalabilityMode::kS3T3;
65 }
66 };
67
TEST(VideoEncoderFactoryTemplate,OneTemplateAdapterCreateEncoder)68 TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCreateEncoder) {
69 VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
70 EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
71 EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), Ne(nullptr));
72 EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), Eq(nullptr));
73 }
74
TEST(VideoEncoderFactoryTemplate,OneTemplateAdapterCodecSupport)75 TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCodecSupport) {
76 VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
77 EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, absl::nullopt),
78 Field(&CodecSupport::is_supported, true));
79 EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "L1T2"),
80 Field(&CodecSupport::is_supported, true));
81 EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "S3T3"),
82 Field(&CodecSupport::is_supported, false));
83 EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat("FooX"), absl::nullopt),
84 Field(&CodecSupport::is_supported, false));
85 }
86
TEST(VideoEncoderFactoryTemplate,TwoTemplateAdaptersNoDuplicates)87 TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) {
88 VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
89 FooEncoderTemplateAdapter>
90 factory;
91 EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
92 }
93
TEST(VideoEncoderFactoryTemplate,TwoTemplateAdaptersCreateEncoders)94 TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCreateEncoders) {
95 VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
96 BarEncoderTemplateAdapter>
97 factory;
98 EXPECT_THAT(factory.GetSupportedFormats(),
99 UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp));
100 EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), Ne(nullptr));
101 EXPECT_THAT(factory.CreateVideoEncoder(kBarLowSdp), Ne(nullptr));
102 EXPECT_THAT(factory.CreateVideoEncoder(kBarHighSdp), Ne(nullptr));
103 EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), Eq(nullptr));
104 EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("Bar")), Eq(nullptr));
105 }
106
TEST(VideoEncoderFactoryTemplate,TwoTemplateAdaptersCodecSupport)107 TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCodecSupport) {
108 VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
109 BarEncoderTemplateAdapter>
110 factory;
111 EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, absl::nullopt),
112 Field(&CodecSupport::is_supported, true));
113 EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "L1T2"),
114 Field(&CodecSupport::is_supported, true));
115 EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "S3T3"),
116 Field(&CodecSupport::is_supported, false));
117 EXPECT_THAT(factory.QueryCodecSupport(kBarLowSdp, absl::nullopt),
118 Field(&CodecSupport::is_supported, true));
119 EXPECT_THAT(factory.QueryCodecSupport(kBarHighSdp, absl::nullopt),
120 Field(&CodecSupport::is_supported, true));
121 EXPECT_THAT(factory.QueryCodecSupport(kBarLowSdp, "S2T1"),
122 Field(&CodecSupport::is_supported, true));
123 EXPECT_THAT(factory.QueryCodecSupport(kBarHighSdp, "S3T2"),
124 Field(&CodecSupport::is_supported, false));
125 }
126
TEST(VideoEncoderFactoryTemplate,LibvpxVp8)127 TEST(VideoEncoderFactoryTemplate, LibvpxVp8) {
128 VideoEncoderFactoryTemplate<LibvpxVp8EncoderTemplateAdapter> factory;
129 auto formats = factory.GetSupportedFormats();
130 EXPECT_THAT(formats.size(), 1);
131 EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "VP8"));
132 EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
133 Contains(ScalabilityMode::kL1T3)));
134 EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr));
135 }
136
TEST(VideoEncoderFactoryTemplate,LibvpxVp9)137 TEST(VideoEncoderFactoryTemplate, LibvpxVp9) {
138 VideoEncoderFactoryTemplate<LibvpxVp9EncoderTemplateAdapter> factory;
139 auto formats = factory.GetSupportedFormats();
140 EXPECT_THAT(formats, Not(IsEmpty()));
141 EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "VP9")));
142 EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes,
143 Contains(ScalabilityMode::kL3T3_KEY))));
144 EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr));
145 }
146
147 // TODO(bugs.webrtc.org/13573): When OpenH264 is no longer a conditional build
148 // target remove this #ifdef.
149 #if defined(WEBRTC_USE_H264)
TEST(VideoEncoderFactoryTemplate,OpenH264)150 TEST(VideoEncoderFactoryTemplate, OpenH264) {
151 VideoEncoderFactoryTemplate<OpenH264EncoderTemplateAdapter> factory;
152 auto formats = factory.GetSupportedFormats();
153 EXPECT_THAT(formats, Not(IsEmpty()));
154 EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "H264")));
155 EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes,
156 Contains(ScalabilityMode::kL1T3))));
157 EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr));
158 }
159 #endif // defined(WEBRTC_USE_H264)
160
TEST(VideoEncoderFactoryTemplate,LibaomAv1)161 TEST(VideoEncoderFactoryTemplate, LibaomAv1) {
162 VideoEncoderFactoryTemplate<LibaomAv1EncoderTemplateAdapter> factory;
163 auto formats = factory.GetSupportedFormats();
164 EXPECT_THAT(formats.size(), 1);
165 EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "AV1"));
166 EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
167 Contains(ScalabilityMode::kL3T3_KEY)));
168 EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), Ne(nullptr));
169 }
170
171 } // namespace
172 } // namespace webrtc
173