1 /*
2 * Copyright (c) 2016 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 "media/engine/internal_decoder_factory.h"
12
13 #include "api/video_codecs/av1_profile.h"
14 #include "api/video_codecs/sdp_video_format.h"
15 #include "api/video_codecs/video_decoder.h"
16 #include "api/video_codecs/vp9_profile.h"
17 #include "media/base/media_constants.h"
18 #include "system_wrappers/include/field_trial.h"
19 #include "test/field_trial.h"
20 #include "test/gmock.h"
21 #include "test/gtest.h"
22
23 namespace webrtc {
24 namespace {
25 using ::testing::Contains;
26 using ::testing::Field;
27 using ::testing::Not;
28
29 using ::webrtc::field_trial::InitFieldTrialsFromString;
30
31 #ifdef RTC_ENABLE_VP9
32 constexpr bool kVp9Enabled = true;
33 #else
34 constexpr bool kVp9Enabled = false;
35 #endif
36 #ifdef WEBRTC_USE_H264
37 constexpr bool kH264Enabled = true;
38 #else
39 constexpr bool kH264Enabled = false;
40 #endif
41 #ifdef RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY
42 constexpr bool kDav1dIsIncluded = true;
43 #else
44 constexpr bool kDav1dIsIncluded = false;
45 #endif
46 constexpr VideoDecoderFactory::CodecSupport kSupported = {
47 /*is_supported=*/true, /*is_power_efficient=*/false};
48 constexpr VideoDecoderFactory::CodecSupport kUnsupported = {
49 /*is_supported=*/false, /*is_power_efficient=*/false};
50 constexpr char kDav1dDecoderFieldTrialEnabled[] =
51 "WebRTC-Dav1dDecoder/Enabled/";
52 constexpr char kDav1dDecoderFieldTrialDisabled[] =
53 "WebRTC-Dav1dDecoder/Disabled/";
54
55 MATCHER_P(Support, expected, "") {
56 return arg.is_supported == expected.is_supported &&
57 arg.is_power_efficient == expected.is_power_efficient;
58 }
59
TEST(InternalDecoderFactoryTest,Vp8)60 TEST(InternalDecoderFactoryTest, Vp8) {
61 InternalDecoderFactory factory;
62 std::unique_ptr<VideoDecoder> decoder =
63 factory.CreateVideoDecoder(SdpVideoFormat(cricket::kVp8CodecName));
64 EXPECT_TRUE(decoder);
65 }
66
TEST(InternalDecoderFactoryTest,Vp9Profile0)67 TEST(InternalDecoderFactoryTest, Vp9Profile0) {
68 InternalDecoderFactory factory;
69 std::unique_ptr<VideoDecoder> decoder =
70 factory.CreateVideoDecoder(SdpVideoFormat(
71 cricket::kVp9CodecName,
72 {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile0)}}));
73 EXPECT_EQ(static_cast<bool>(decoder), kVp9Enabled);
74 }
75
TEST(InternalDecoderFactoryTest,Vp9Profile1)76 TEST(InternalDecoderFactoryTest, Vp9Profile1) {
77 InternalDecoderFactory factory;
78 std::unique_ptr<VideoDecoder> decoder =
79 factory.CreateVideoDecoder(SdpVideoFormat(
80 cricket::kVp9CodecName,
81 {{kVP9FmtpProfileId, VP9ProfileToString(VP9Profile::kProfile1)}}));
82 EXPECT_EQ(static_cast<bool>(decoder), kVp9Enabled);
83 }
84
TEST(InternalDecoderFactoryTest,H264)85 TEST(InternalDecoderFactoryTest, H264) {
86 InternalDecoderFactory factory;
87 std::unique_ptr<VideoDecoder> decoder =
88 factory.CreateVideoDecoder(SdpVideoFormat(cricket::kH264CodecName));
89 EXPECT_EQ(static_cast<bool>(decoder), kH264Enabled);
90 }
91
TEST(InternalDecoderFactoryTest,Av1Profile0)92 TEST(InternalDecoderFactoryTest, Av1Profile0) {
93 InternalDecoderFactory factory;
94 InitFieldTrialsFromString(kDav1dDecoderFieldTrialEnabled);
95 if (kDav1dIsIncluded) {
96 EXPECT_THAT(factory.GetSupportedFormats(),
97 Contains(Field(&SdpVideoFormat::name, cricket::kAv1CodecName)));
98 EXPECT_TRUE(
99 factory.CreateVideoDecoder(SdpVideoFormat(cricket::kAv1CodecName)));
100 } else {
101 EXPECT_THAT(
102 factory.GetSupportedFormats(),
103 Not(Contains(Field(&SdpVideoFormat::name, cricket::kAv1CodecName))));
104 }
105 }
106
107 #if defined(RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY)
TEST(InternalDecoderFactoryTest,Av1)108 TEST(InternalDecoderFactoryTest, Av1) {
109 InternalDecoderFactory factory;
110 EXPECT_THAT(factory.GetSupportedFormats(),
111 Contains(Field(&SdpVideoFormat::name, cricket::kAv1CodecName)));
112 }
113 #endif
114
TEST(InternalDecoderFactoryTest,Av1Profile1_Dav1dDecoderTrialEnabled)115 TEST(InternalDecoderFactoryTest, Av1Profile1_Dav1dDecoderTrialEnabled) {
116 InitFieldTrialsFromString(kDav1dDecoderFieldTrialEnabled);
117 InternalDecoderFactory factory;
118 std::unique_ptr<VideoDecoder> decoder = factory.CreateVideoDecoder(
119 SdpVideoFormat(cricket::kAv1CodecName,
120 {{kAV1FmtpProfile,
121 AV1ProfileToString(AV1Profile::kProfile1).data()}}));
122 EXPECT_EQ(static_cast<bool>(decoder), kDav1dIsIncluded);
123 }
124
TEST(InternalDecoderFactoryTest,Av1Profile1_Dav1dDecoderTrialDisabled)125 TEST(InternalDecoderFactoryTest, Av1Profile1_Dav1dDecoderTrialDisabled) {
126 test::ScopedFieldTrials disable_dav1d(kDav1dDecoderFieldTrialDisabled);
127 InternalDecoderFactory factory;
128 std::unique_ptr<VideoDecoder> decoder = factory.CreateVideoDecoder(
129 SdpVideoFormat(cricket::kAv1CodecName,
130 {{kAV1FmtpProfile,
131 AV1ProfileToString(AV1Profile::kProfile1).data()}}));
132 EXPECT_FALSE(static_cast<bool>(decoder));
133 }
134
TEST(InternalDecoderFactoryTest,QueryCodecSupportNoReferenceScaling)135 TEST(InternalDecoderFactoryTest, QueryCodecSupportNoReferenceScaling) {
136 InternalDecoderFactory factory;
137 EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp8CodecName),
138 /*reference_scaling=*/false),
139 Support(kSupported));
140 EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp9CodecName),
141 /*reference_scaling=*/false),
142 Support(kVp9Enabled ? kSupported : kUnsupported));
143 EXPECT_THAT(factory.QueryCodecSupport(
144 SdpVideoFormat(cricket::kVp9CodecName,
145 {{kVP9FmtpProfileId,
146 VP9ProfileToString(VP9Profile::kProfile1)}}),
147 /*reference_scaling=*/false),
148 Support(kVp9Enabled ? kSupported : kUnsupported));
149
150 #if defined(RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY)
151 EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kAv1CodecName),
152 /*reference_scaling=*/false),
153 Support(kSupported));
154 #endif
155 }
156
TEST(InternalDecoderFactoryTest,QueryCodecSupportReferenceScaling)157 TEST(InternalDecoderFactoryTest, QueryCodecSupportReferenceScaling) {
158 InternalDecoderFactory factory;
159 // VP9 and AV1 support for spatial layers.
160 EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp9CodecName),
161 /*reference_scaling=*/true),
162 Support(kVp9Enabled ? kSupported : kUnsupported));
163 #if defined(RTC_DAV1D_IN_INTERNAL_DECODER_FACTORY)
164 EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kAv1CodecName),
165 /*reference_scaling=*/true),
166 Support(kSupported));
167 #endif
168
169 // Invalid config even though VP8 and H264 are supported.
170 EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kH264CodecName),
171 /*reference_scaling=*/true),
172 Support(kUnsupported));
173 EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat(cricket::kVp8CodecName),
174 /*reference_scaling=*/true),
175 Support(kUnsupported));
176 }
177
178 } // namespace
179 } // namespace webrtc
180