Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
89
TMessagesProj/jni/voip/webrtc/api/video_codecs/test/BUILD.gn
Normal file
89
TMessagesProj/jni/voip/webrtc/api/video_codecs/test/BUILD.gn
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
# Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
#
|
||||
# Use of this source code is governed by a BSD-style license
|
||||
# that can be found in the LICENSE file in the root of the source
|
||||
# tree. An additional intellectual property rights grant can be found
|
||||
# in the file PATENTS. All contributing project authors may
|
||||
# be found in the AUTHORS file in the root of the source tree.
|
||||
|
||||
import("../../../webrtc.gni")
|
||||
|
||||
if (rtc_include_tests) {
|
||||
rtc_library("video_codecs_api_unittests") {
|
||||
testonly = true
|
||||
sources = [
|
||||
"builtin_video_encoder_factory_unittest.cc",
|
||||
"h264_profile_level_id_unittest.cc",
|
||||
"sdp_video_format_unittest.cc",
|
||||
"video_decoder_software_fallback_wrapper_unittest.cc",
|
||||
"video_encoder_software_fallback_wrapper_unittest.cc",
|
||||
]
|
||||
|
||||
if (rtc_use_h265) {
|
||||
sources += [ "h265_profile_tier_level_unittest.cc" ]
|
||||
}
|
||||
|
||||
deps = [
|
||||
":video_decoder_factory_template_tests",
|
||||
":video_encoder_factory_template_tests",
|
||||
"..:builtin_video_encoder_factory",
|
||||
"..:rtc_software_fallback_wrappers",
|
||||
"..:video_codecs_api",
|
||||
"../..:fec_controller_api",
|
||||
"../..:mock_video_encoder",
|
||||
"../../../api:scoped_refptr",
|
||||
"../../../media:media_constants",
|
||||
"../../../media:rtc_media_base",
|
||||
"../../../modules/video_coding:video_codec_interface",
|
||||
"../../../modules/video_coding:video_coding_utility",
|
||||
"../../../modules/video_coding:webrtc_vp8",
|
||||
"../../../rtc_base:checks",
|
||||
"../../../rtc_base:rtc_base_tests_utils",
|
||||
"../../../test:explicit_key_value_config",
|
||||
"../../../test:fake_video_codecs",
|
||||
"../../../test:field_trial",
|
||||
"../../../test:test_support",
|
||||
"../../../test:video_test_common",
|
||||
"../../environment",
|
||||
"../../environment:environment_factory",
|
||||
"../../video:encoded_image",
|
||||
"../../video:video_bitrate_allocation",
|
||||
"../../video:video_frame",
|
||||
"../../video:video_rtp_headers",
|
||||
"//testing/gtest",
|
||||
]
|
||||
absl_deps = [ "//third_party/abseil-cpp/absl/types:optional" ]
|
||||
}
|
||||
|
||||
rtc_library("video_encoder_factory_template_tests") {
|
||||
testonly = true
|
||||
sources = [ "video_encoder_factory_template_tests.cc" ]
|
||||
|
||||
deps = [
|
||||
"..:video_encoder_factory_template",
|
||||
"..:video_encoder_factory_template_libaom_av1_adapter",
|
||||
"..:video_encoder_factory_template_libvpx_vp8_adapter",
|
||||
"..:video_encoder_factory_template_libvpx_vp9_adapter",
|
||||
"..:video_encoder_factory_template_open_h264_adapter",
|
||||
"../../:mock_video_encoder",
|
||||
"../../../test:test_support",
|
||||
"//testing/gtest",
|
||||
]
|
||||
}
|
||||
|
||||
rtc_library("video_decoder_factory_template_tests") {
|
||||
testonly = true
|
||||
sources = [ "video_decoder_factory_template_tests.cc" ]
|
||||
|
||||
deps = [
|
||||
"..:video_decoder_factory_template",
|
||||
"..:video_decoder_factory_template_dav1d_adapter",
|
||||
"..:video_decoder_factory_template_libvpx_vp8_adapter",
|
||||
"..:video_decoder_factory_template_libvpx_vp9_adapter",
|
||||
"..:video_decoder_factory_template_open_h264_adapter",
|
||||
"../../:mock_video_decoder",
|
||||
"../../../test:test_support",
|
||||
"//testing/gtest",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/video_codecs/builtin_video_encoder_factory.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "api/video_codecs/sdp_video_format.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
TEST(BuiltinVideoEncoderFactoryTest, AnnouncesVp9AccordingToBuildFlags) {
|
||||
std::unique_ptr<VideoEncoderFactory> factory =
|
||||
CreateBuiltinVideoEncoderFactory();
|
||||
bool claims_vp9_support = false;
|
||||
for (const SdpVideoFormat& format : factory->GetSupportedFormats()) {
|
||||
if (format.name == "VP9") {
|
||||
claims_vp9_support = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if defined(RTC_ENABLE_VP9)
|
||||
EXPECT_TRUE(claims_vp9_support);
|
||||
#else
|
||||
EXPECT_FALSE(claims_vp9_support);
|
||||
#endif // defined(RTC_ENABLE_VP9)
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/video_codecs/h264_profile_level_id.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
TEST(H264ProfileLevelId, TestParsingInvalid) {
|
||||
// Malformed strings.
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId(""));
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId(" 42e01f"));
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId("4242e01f"));
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId("e01f"));
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId("gggggg"));
|
||||
|
||||
// Invalid level.
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId("42e000"));
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId("42e00f"));
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId("42e0ff"));
|
||||
|
||||
// Invalid profile.
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId("42e11f"));
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId("58601f"));
|
||||
EXPECT_FALSE(ParseH264ProfileLevelId("64e01f"));
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestParsingLevel) {
|
||||
EXPECT_EQ(H264Level::kLevel3_1, ParseH264ProfileLevelId("42e01f")->level);
|
||||
EXPECT_EQ(H264Level::kLevel1_1, ParseH264ProfileLevelId("42e00b")->level);
|
||||
EXPECT_EQ(H264Level::kLevel1_b, ParseH264ProfileLevelId("42f00b")->level);
|
||||
EXPECT_EQ(H264Level::kLevel4_2, ParseH264ProfileLevelId("42C02A")->level);
|
||||
EXPECT_EQ(H264Level::kLevel5_2, ParseH264ProfileLevelId("640c34")->level);
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestParsingConstrainedBaseline) {
|
||||
EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
|
||||
ParseH264ProfileLevelId("42e01f")->profile);
|
||||
EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
|
||||
ParseH264ProfileLevelId("42C02A")->profile);
|
||||
EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
|
||||
ParseH264ProfileLevelId("4de01f")->profile);
|
||||
EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
|
||||
ParseH264ProfileLevelId("58f01f")->profile);
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestParsingBaseline) {
|
||||
EXPECT_EQ(H264Profile::kProfileBaseline,
|
||||
ParseH264ProfileLevelId("42a01f")->profile);
|
||||
EXPECT_EQ(H264Profile::kProfileBaseline,
|
||||
ParseH264ProfileLevelId("58A01F")->profile);
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestParsingMain) {
|
||||
EXPECT_EQ(H264Profile::kProfileMain,
|
||||
ParseH264ProfileLevelId("4D401f")->profile);
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestParsingHigh) {
|
||||
EXPECT_EQ(H264Profile::kProfileHigh,
|
||||
ParseH264ProfileLevelId("64001f")->profile);
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestParsingConstrainedHigh) {
|
||||
EXPECT_EQ(H264Profile::kProfileConstrainedHigh,
|
||||
ParseH264ProfileLevelId("640c1f")->profile);
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestSupportedLevel) {
|
||||
EXPECT_EQ(H264Level::kLevel2_1, *H264SupportedLevel(640 * 480, 25));
|
||||
EXPECT_EQ(H264Level::kLevel3_1, *H264SupportedLevel(1280 * 720, 30));
|
||||
EXPECT_EQ(H264Level::kLevel4_2, *H264SupportedLevel(1920 * 1280, 60));
|
||||
}
|
||||
|
||||
// Test supported level below level 1 requirements.
|
||||
TEST(H264ProfileLevelId, TestSupportedLevelInvalid) {
|
||||
EXPECT_FALSE(H264SupportedLevel(0, 0));
|
||||
// All levels support fps > 5.
|
||||
EXPECT_FALSE(H264SupportedLevel(1280 * 720, 5));
|
||||
// All levels support frame sizes > 183 * 137.
|
||||
EXPECT_FALSE(H264SupportedLevel(183 * 137, 30));
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestToString) {
|
||||
EXPECT_EQ("42e01f", *H264ProfileLevelIdToString(H264ProfileLevelId(
|
||||
H264Profile::kProfileConstrainedBaseline,
|
||||
H264Level::kLevel3_1)));
|
||||
EXPECT_EQ("42000a", *H264ProfileLevelIdToString(H264ProfileLevelId(
|
||||
H264Profile::kProfileBaseline, H264Level::kLevel1)));
|
||||
EXPECT_EQ("4d001f", H264ProfileLevelIdToString(H264ProfileLevelId(
|
||||
H264Profile::kProfileMain, H264Level::kLevel3_1)));
|
||||
EXPECT_EQ("640c2a",
|
||||
*H264ProfileLevelIdToString(H264ProfileLevelId(
|
||||
H264Profile::kProfileConstrainedHigh, H264Level::kLevel4_2)));
|
||||
EXPECT_EQ("64002a", *H264ProfileLevelIdToString(H264ProfileLevelId(
|
||||
H264Profile::kProfileHigh, H264Level::kLevel4_2)));
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestToStringLevel1b) {
|
||||
EXPECT_EQ("42f00b", *H264ProfileLevelIdToString(H264ProfileLevelId(
|
||||
H264Profile::kProfileConstrainedBaseline,
|
||||
H264Level::kLevel1_b)));
|
||||
EXPECT_EQ("42100b",
|
||||
*H264ProfileLevelIdToString(H264ProfileLevelId(
|
||||
H264Profile::kProfileBaseline, H264Level::kLevel1_b)));
|
||||
EXPECT_EQ("4d100b", *H264ProfileLevelIdToString(H264ProfileLevelId(
|
||||
H264Profile::kProfileMain, H264Level::kLevel1_b)));
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestToStringRoundTrip) {
|
||||
EXPECT_EQ("42e01f",
|
||||
*H264ProfileLevelIdToString(*ParseH264ProfileLevelId("42e01f")));
|
||||
EXPECT_EQ("42e01f",
|
||||
*H264ProfileLevelIdToString(*ParseH264ProfileLevelId("42E01F")));
|
||||
EXPECT_EQ("4d100b",
|
||||
*H264ProfileLevelIdToString(*ParseH264ProfileLevelId("4d100b")));
|
||||
EXPECT_EQ("4d100b",
|
||||
*H264ProfileLevelIdToString(*ParseH264ProfileLevelId("4D100B")));
|
||||
EXPECT_EQ("640c2a",
|
||||
*H264ProfileLevelIdToString(*ParseH264ProfileLevelId("640c2a")));
|
||||
EXPECT_EQ("640c2a",
|
||||
*H264ProfileLevelIdToString(*ParseH264ProfileLevelId("640C2A")));
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestToStringInvalid) {
|
||||
EXPECT_FALSE(H264ProfileLevelIdToString(
|
||||
H264ProfileLevelId(H264Profile::kProfileHigh, H264Level::kLevel1_b)));
|
||||
EXPECT_FALSE(H264ProfileLevelIdToString(H264ProfileLevelId(
|
||||
H264Profile::kProfileConstrainedHigh, H264Level::kLevel1_b)));
|
||||
EXPECT_FALSE(H264ProfileLevelIdToString(
|
||||
H264ProfileLevelId(static_cast<H264Profile>(255), H264Level::kLevel3_1)));
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdEmpty) {
|
||||
const absl::optional<H264ProfileLevelId> profile_level_id =
|
||||
ParseSdpForH264ProfileLevelId(CodecParameterMap());
|
||||
EXPECT_TRUE(profile_level_id);
|
||||
EXPECT_EQ(H264Profile::kProfileConstrainedBaseline,
|
||||
profile_level_id->profile);
|
||||
EXPECT_EQ(H264Level::kLevel3_1, profile_level_id->level);
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdConstrainedHigh) {
|
||||
CodecParameterMap params;
|
||||
params["profile-level-id"] = "640c2a";
|
||||
const absl::optional<H264ProfileLevelId> profile_level_id =
|
||||
ParseSdpForH264ProfileLevelId(params);
|
||||
EXPECT_TRUE(profile_level_id);
|
||||
EXPECT_EQ(H264Profile::kProfileConstrainedHigh, profile_level_id->profile);
|
||||
EXPECT_EQ(H264Level::kLevel4_2, profile_level_id->level);
|
||||
}
|
||||
|
||||
TEST(H264ProfileLevelId, TestParseSdpProfileLevelIdInvalid) {
|
||||
CodecParameterMap params;
|
||||
params["profile-level-id"] = "foobar";
|
||||
EXPECT_FALSE(ParseSdpForH264ProfileLevelId(params));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
/*
|
||||
* Copyright (c) 2023 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/video_codecs/h265_profile_tier_level.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
TEST(H265ProfileTierLevel, TestLevelToString) {
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel1), "30");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel2), "60");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel2_1), "63");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel3), "90");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel3_1), "93");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel4), "120");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel4_1), "123");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel5), "150");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel5_1), "153");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel5_2), "156");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel6), "180");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel6_1), "183");
|
||||
EXPECT_EQ(H265LevelToString(H265Level::kLevel6_2), "186");
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestProfileToString) {
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfileMain), "1");
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfileMain10), "2");
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfileMainStill), "3");
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfileRangeExtensions), "4");
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfileHighThroughput), "5");
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfileMultiviewMain), "6");
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfileScalableMain), "7");
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfile3dMain), "8");
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfileScreenContentCoding), "9");
|
||||
EXPECT_EQ(H265ProfileToString(H265Profile::kProfileScalableRangeExtensions),
|
||||
"10");
|
||||
EXPECT_EQ(H265ProfileToString(
|
||||
H265Profile::kProfileHighThroughputScreenContentCoding),
|
||||
"11");
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestTierToString) {
|
||||
EXPECT_EQ(H265TierToString(H265Tier::kTier0), "0");
|
||||
EXPECT_EQ(H265TierToString(H265Tier::kTier1), "1");
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestStringToProfile) {
|
||||
// Invalid profiles.
|
||||
EXPECT_FALSE(StringToH265Profile("0"));
|
||||
EXPECT_FALSE(StringToH265Profile("12"));
|
||||
|
||||
// Malformed profiles
|
||||
EXPECT_FALSE(StringToH265Profile(""));
|
||||
EXPECT_FALSE(StringToH265Profile(" 1"));
|
||||
EXPECT_FALSE(StringToH265Profile("12x"));
|
||||
EXPECT_FALSE(StringToH265Profile("x12"));
|
||||
EXPECT_FALSE(StringToH265Profile("gggg"));
|
||||
|
||||
// Valid profiles.
|
||||
EXPECT_EQ(StringToH265Profile("1"), H265Profile::kProfileMain);
|
||||
EXPECT_EQ(StringToH265Profile("2"), H265Profile::kProfileMain10);
|
||||
EXPECT_EQ(StringToH265Profile("4"), H265Profile::kProfileRangeExtensions);
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestStringToLevel) {
|
||||
// Invalid levels.
|
||||
EXPECT_FALSE(StringToH265Level("0"));
|
||||
EXPECT_FALSE(StringToH265Level("200"));
|
||||
|
||||
// Malformed levels.
|
||||
EXPECT_FALSE(StringToH265Level(""));
|
||||
EXPECT_FALSE(StringToH265Level(" 30"));
|
||||
EXPECT_FALSE(StringToH265Level("30x"));
|
||||
EXPECT_FALSE(StringToH265Level("x30"));
|
||||
EXPECT_FALSE(StringToH265Level("ggggg"));
|
||||
|
||||
// Valid levels.
|
||||
EXPECT_EQ(StringToH265Level("30"), H265Level::kLevel1);
|
||||
EXPECT_EQ(StringToH265Level("93"), H265Level::kLevel3_1);
|
||||
EXPECT_EQ(StringToH265Level("183"), H265Level::kLevel6_1);
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestStringToTier) {
|
||||
// Invalid tiers.
|
||||
EXPECT_FALSE(StringToH265Tier("4"));
|
||||
EXPECT_FALSE(StringToH265Tier("-1"));
|
||||
|
||||
// Malformed tiers.
|
||||
EXPECT_FALSE(StringToH265Tier(""));
|
||||
EXPECT_FALSE(StringToH265Tier(" 1"));
|
||||
EXPECT_FALSE(StringToH265Tier("t1"));
|
||||
|
||||
// Valid tiers.
|
||||
EXPECT_EQ(StringToH265Tier("0"), H265Tier::kTier0);
|
||||
EXPECT_EQ(StringToH265Tier("1"), H265Tier::kTier1);
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestParseSdpProfileTierLevelAllEmpty) {
|
||||
const absl::optional<H265ProfileTierLevel> profile_tier_level =
|
||||
ParseSdpForH265ProfileTierLevel(CodecParameterMap());
|
||||
EXPECT_TRUE(profile_tier_level);
|
||||
EXPECT_EQ(H265Profile::kProfileMain, profile_tier_level->profile);
|
||||
EXPECT_EQ(H265Level::kLevel3_1, profile_tier_level->level);
|
||||
EXPECT_EQ(H265Tier::kTier0, profile_tier_level->tier);
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestParseSdpProfileTierLevelPartialEmpty) {
|
||||
CodecParameterMap params;
|
||||
params["profile-id"] = "1";
|
||||
params["tier-flag"] = "0";
|
||||
absl::optional<H265ProfileTierLevel> profile_tier_level =
|
||||
ParseSdpForH265ProfileTierLevel(params);
|
||||
EXPECT_TRUE(profile_tier_level);
|
||||
EXPECT_EQ(H265Profile::kProfileMain, profile_tier_level->profile);
|
||||
EXPECT_EQ(H265Level::kLevel3_1, profile_tier_level->level);
|
||||
EXPECT_EQ(H265Tier::kTier0, profile_tier_level->tier);
|
||||
|
||||
params.clear();
|
||||
params["profile-id"] = "2";
|
||||
profile_tier_level = ParseSdpForH265ProfileTierLevel(params);
|
||||
EXPECT_TRUE(profile_tier_level);
|
||||
EXPECT_EQ(H265Profile::kProfileMain10, profile_tier_level->profile);
|
||||
EXPECT_EQ(H265Level::kLevel3_1, profile_tier_level->level);
|
||||
EXPECT_EQ(H265Tier::kTier0, profile_tier_level->tier);
|
||||
|
||||
params.clear();
|
||||
params["level-id"] = "180";
|
||||
profile_tier_level = ParseSdpForH265ProfileTierLevel(params);
|
||||
EXPECT_TRUE(profile_tier_level);
|
||||
EXPECT_EQ(H265Profile::kProfileMain, profile_tier_level->profile);
|
||||
EXPECT_EQ(H265Level::kLevel6, profile_tier_level->level);
|
||||
EXPECT_EQ(H265Tier::kTier0, profile_tier_level->tier);
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestParseSdpProfileTierLevelInvalid) {
|
||||
CodecParameterMap params;
|
||||
|
||||
// Invalid profile-tier-level combination.
|
||||
params["profile-id"] = "1";
|
||||
params["tier-flag"] = "1";
|
||||
params["level-id"] = "93";
|
||||
absl::optional<H265ProfileTierLevel> profile_tier_level =
|
||||
ParseSdpForH265ProfileTierLevel(params);
|
||||
EXPECT_FALSE(profile_tier_level);
|
||||
params.clear();
|
||||
params["profile-id"] = "1";
|
||||
params["tier-flag"] = "4";
|
||||
params["level-id"] = "180";
|
||||
profile_tier_level = ParseSdpForH265ProfileTierLevel(params);
|
||||
EXPECT_FALSE(profile_tier_level);
|
||||
|
||||
// Valid profile-tier-level combination.
|
||||
params.clear();
|
||||
params["profile-id"] = "1";
|
||||
params["tier-flag"] = "0";
|
||||
params["level-id"] = "153";
|
||||
profile_tier_level = ParseSdpForH265ProfileTierLevel(params);
|
||||
EXPECT_TRUE(profile_tier_level);
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestToStringRoundTrip) {
|
||||
CodecParameterMap params;
|
||||
params["profile-id"] = "1";
|
||||
params["tier-flag"] = "0";
|
||||
params["level-id"] = "93";
|
||||
absl::optional<H265ProfileTierLevel> profile_tier_level =
|
||||
ParseSdpForH265ProfileTierLevel(params);
|
||||
EXPECT_TRUE(profile_tier_level);
|
||||
EXPECT_EQ("1", H265ProfileToString(profile_tier_level->profile));
|
||||
EXPECT_EQ("0", H265TierToString(profile_tier_level->tier));
|
||||
EXPECT_EQ("93", H265LevelToString(profile_tier_level->level));
|
||||
|
||||
params.clear();
|
||||
params["profile-id"] = "2";
|
||||
params["tier-flag"] = "1";
|
||||
params["level-id"] = "180";
|
||||
profile_tier_level = ParseSdpForH265ProfileTierLevel(params);
|
||||
EXPECT_TRUE(profile_tier_level);
|
||||
EXPECT_EQ("2", H265ProfileToString(profile_tier_level->profile));
|
||||
EXPECT_EQ("1", H265TierToString(profile_tier_level->tier));
|
||||
EXPECT_EQ("180", H265LevelToString(profile_tier_level->level));
|
||||
}
|
||||
|
||||
TEST(H265ProfileTierLevel, TestProfileTierLevelCompare) {
|
||||
CodecParameterMap params1;
|
||||
CodecParameterMap params2;
|
||||
|
||||
// None of profile-id/tier-flag/level-id is specified,
|
||||
EXPECT_TRUE(H265IsSameProfileTierLevel(params1, params2));
|
||||
|
||||
// Same non-empty PTL
|
||||
params1["profile-id"] = "1";
|
||||
params1["tier-flag"] = "0";
|
||||
params1["level-id"] = "120";
|
||||
params2["profile-id"] = "1";
|
||||
params2["tier-flag"] = "0";
|
||||
params2["level-id"] = "120";
|
||||
EXPECT_TRUE(H265IsSameProfileTierLevel(params1, params2));
|
||||
|
||||
// Different profiles.
|
||||
params1.clear();
|
||||
params2.clear();
|
||||
params1["profile-id"] = "1";
|
||||
params2["profile-id"] = "2";
|
||||
EXPECT_FALSE(H265IsSameProfileTierLevel(params1, params2));
|
||||
|
||||
// Different levels.
|
||||
params1.clear();
|
||||
params2.clear();
|
||||
params1["profile-id"] = "1";
|
||||
params2["profile-id"] = "1";
|
||||
params1["level-id"] = "93";
|
||||
params2["level-id"] = "183";
|
||||
EXPECT_FALSE(H265IsSameProfileTierLevel(params1, params2));
|
||||
|
||||
// Different tiers.
|
||||
params1.clear();
|
||||
params2.clear();
|
||||
params1["profile-id"] = "1";
|
||||
params2["profile-id"] = "1";
|
||||
params1["level-id"] = "93";
|
||||
params2["level-id"] = "93";
|
||||
params1["tier-flag"] = "0";
|
||||
params2["tier-flag"] = "1";
|
||||
EXPECT_FALSE(H265IsSameProfileTierLevel(params1, params2));
|
||||
|
||||
// One of the CodecParameterMap is invalid.
|
||||
params1.clear();
|
||||
params2.clear();
|
||||
params1["profile-id"] = "1";
|
||||
params2["profile-id"] = "1";
|
||||
params1["tier-flag"] = "0";
|
||||
params2["tier-flag"] = "4";
|
||||
EXPECT_FALSE(H265IsSameProfileTierLevel(params1, params2));
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*
|
||||
* Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/video_codecs/sdp_video_format.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "media/base/media_constants.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
typedef SdpVideoFormat Sdp;
|
||||
typedef CodecParameterMap Params;
|
||||
|
||||
TEST(SdpVideoFormatTest, SameCodecNameNoParameters) {
|
||||
EXPECT_TRUE(Sdp("H264").IsSameCodec(Sdp("h264")));
|
||||
EXPECT_TRUE(Sdp("VP8").IsSameCodec(Sdp("vp8")));
|
||||
EXPECT_TRUE(Sdp("VP9").IsSameCodec(Sdp("vp9")));
|
||||
EXPECT_TRUE(Sdp("AV1").IsSameCodec(Sdp("Av1")));
|
||||
#ifdef RTC_ENABLE_H265
|
||||
EXPECT_TRUE(Sdp("H265").IsSameCodec(Sdp("h265")));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(SdpVideoFormatTest, DifferentCodecNameNoParameters) {
|
||||
EXPECT_FALSE(Sdp("H264").IsSameCodec(Sdp("VP8")));
|
||||
EXPECT_FALSE(Sdp("VP8").IsSameCodec(Sdp("VP9")));
|
||||
EXPECT_FALSE(Sdp("AV1").IsSameCodec(Sdp("VP8")));
|
||||
#ifdef RTC_ENABLE_H265
|
||||
EXPECT_FALSE(Sdp("H265").IsSameCodec(Sdp("VP8")));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(SdpVideoFormatTest, SameCodecNameSameParameters) {
|
||||
EXPECT_TRUE(Sdp("VP9").IsSameCodec(Sdp("VP9", Params{{"profile-id", "0"}})));
|
||||
EXPECT_TRUE(Sdp("VP9", Params{{"profile-id", "0"}})
|
||||
.IsSameCodec(Sdp("VP9", Params{{"profile-id", "0"}})));
|
||||
EXPECT_TRUE(Sdp("VP9", Params{{"profile-id", "2"}})
|
||||
.IsSameCodec(Sdp("VP9", Params{{"profile-id", "2"}})));
|
||||
EXPECT_TRUE(
|
||||
Sdp("H264", Params{{"profile-level-id", "42e01f"}})
|
||||
.IsSameCodec(Sdp("H264", Params{{"profile-level-id", "42e01f"}})));
|
||||
EXPECT_TRUE(
|
||||
Sdp("H264", Params{{"profile-level-id", "640c34"}})
|
||||
.IsSameCodec(Sdp("H264", Params{{"profile-level-id", "640c34"}})));
|
||||
EXPECT_TRUE(Sdp("AV1").IsSameCodec(Sdp("AV1", Params{{"profile", "0"}})));
|
||||
EXPECT_TRUE(Sdp("AV1", Params{{"profile", "0"}})
|
||||
.IsSameCodec(Sdp("AV1", Params{{"profile", "0"}})));
|
||||
EXPECT_TRUE(Sdp("AV1", Params{{"profile", "2"}})
|
||||
.IsSameCodec(Sdp("AV1", Params{{"profile", "2"}})));
|
||||
#ifdef RTC_ENABLE_H265
|
||||
EXPECT_TRUE(Sdp("H265").IsSameCodec(Sdp(
|
||||
"H265",
|
||||
Params{{"profile-id", "1"}, {"tier-flag", "0"}, {"level-id", "93"}})));
|
||||
EXPECT_TRUE(
|
||||
Sdp("H265",
|
||||
Params{{"profile-id", "2"}, {"tier-flag", "0"}, {"level-id", "93"}})
|
||||
.IsSameCodec(Sdp("H265", Params{{"profile-id", "2"},
|
||||
{"tier-flag", "0"},
|
||||
{"level-id", "93"}})));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(SdpVideoFormatTest, SameCodecNameDifferentParameters) {
|
||||
EXPECT_FALSE(Sdp("VP9").IsSameCodec(Sdp("VP9", Params{{"profile-id", "2"}})));
|
||||
EXPECT_FALSE(Sdp("VP9", Params{{"profile-id", "0"}})
|
||||
.IsSameCodec(Sdp("VP9", Params{{"profile-id", "1"}})));
|
||||
EXPECT_FALSE(Sdp("VP9", Params{{"profile-id", "2"}})
|
||||
.IsSameCodec(Sdp("VP9", Params{{"profile-id", "0"}})));
|
||||
EXPECT_FALSE(
|
||||
Sdp("H264", Params{{"profile-level-id", "42e01f"}})
|
||||
.IsSameCodec(Sdp("H264", Params{{"profile-level-id", "640c34"}})));
|
||||
EXPECT_FALSE(
|
||||
Sdp("H264", Params{{"profile-level-id", "640c34"}})
|
||||
.IsSameCodec(Sdp("H264", Params{{"profile-level-id", "42f00b"}})));
|
||||
EXPECT_FALSE(Sdp("AV1").IsSameCodec(Sdp("AV1", Params{{"profile", "1"}})));
|
||||
EXPECT_FALSE(Sdp("AV1", Params{{"profile", "0"}})
|
||||
.IsSameCodec(Sdp("AV1", Params{{"profile", "1"}})));
|
||||
EXPECT_FALSE(Sdp("AV1", Params{{"profile", "1"}})
|
||||
.IsSameCodec(Sdp("AV1", Params{{"profile", "2"}})));
|
||||
#ifdef RTC_ENABLE_H265
|
||||
EXPECT_FALSE(Sdp("H265").IsSameCodec(Sdp(
|
||||
"H265",
|
||||
Params{{"profile-id", "0"}, {"tier-flag", "0"}, {"level-id", "93"}})));
|
||||
EXPECT_FALSE(Sdp("H265").IsSameCodec(Sdp(
|
||||
"H265",
|
||||
Params{{"profile-id", "1"}, {"tier-flag", "1"}, {"level-id", "93"}})));
|
||||
EXPECT_FALSE(Sdp("H265").IsSameCodec(Sdp(
|
||||
"H265",
|
||||
Params{{"profile-id", "1"}, {"tier-flag", "0"}, {"level-id", "90"}})));
|
||||
EXPECT_FALSE(
|
||||
Sdp("H265",
|
||||
Params{{"profile-id", "2"}, {"tier-flag", "0"}, {"level-id", "93"}})
|
||||
.IsSameCodec(Sdp("H265", Params{{"profile-id", "1"},
|
||||
{"tier-flag", "0"},
|
||||
{"level-id", "93"}})));
|
||||
EXPECT_FALSE(
|
||||
Sdp("H265",
|
||||
Params{{"profile-id", "1"}, {"tier-flag", "1"}, {"level-id", "120"}})
|
||||
.IsSameCodec(Sdp("H265", Params{{"profile-id", "1"},
|
||||
{"tier-flag", "0"},
|
||||
{"level-id", "120"}})));
|
||||
EXPECT_FALSE(
|
||||
Sdp("H265",
|
||||
Params{{"profile-id", "1"}, {"tier-flag", "0"}, {"level-id", "93"}})
|
||||
.IsSameCodec(Sdp("H265", Params{{"profile-id", "1"},
|
||||
{"tier-flag", "0"},
|
||||
{"level-id", "90"}})));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(SdpVideoFormatTest, DifferentCodecNameSameParameters) {
|
||||
EXPECT_FALSE(Sdp("VP9", Params{{"profile-id", "0"}})
|
||||
.IsSameCodec(Sdp("H264", Params{{"profile-id", "0"}})));
|
||||
EXPECT_FALSE(Sdp("VP9", Params{{"profile-id", "2"}})
|
||||
.IsSameCodec(Sdp("VP8", Params{{"profile-id", "2"}})));
|
||||
EXPECT_FALSE(
|
||||
Sdp("H264", Params{{"profile-level-id", "42e01f"}})
|
||||
.IsSameCodec(Sdp("VP9", Params{{"profile-level-id", "42e01f"}})));
|
||||
EXPECT_FALSE(
|
||||
Sdp("H264", Params{{"profile-level-id", "640c34"}})
|
||||
.IsSameCodec(Sdp("VP8", Params{{"profile-level-id", "640c34"}})));
|
||||
EXPECT_FALSE(Sdp("AV1", Params{{"profile", "0"}})
|
||||
.IsSameCodec(Sdp("H264", Params{{"profile", "0"}})));
|
||||
EXPECT_FALSE(Sdp("AV1", Params{{"profile", "2"}})
|
||||
.IsSameCodec(Sdp("VP9", Params{{"profile", "2"}})));
|
||||
#ifdef RTC_ENABLE_H265
|
||||
EXPECT_FALSE(Sdp("H265", Params{{"profile-id", "0"}})
|
||||
.IsSameCodec(Sdp("H264", Params{{"profile-id", "0"}})));
|
||||
EXPECT_FALSE(Sdp("H265", Params{{"profile-id", "2"}})
|
||||
.IsSameCodec(Sdp("VP9", Params{{"profile-id", "2"}})));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST(SdpVideoFormatTest, H264PacketizationMode) {
|
||||
// The default packetization mode is 0.
|
||||
EXPECT_TRUE(Sdp("H264", Params{{cricket::kH264FmtpPacketizationMode, "0"}})
|
||||
.IsSameCodec(Sdp("H264")));
|
||||
EXPECT_FALSE(Sdp("H264", Params{{cricket::kH264FmtpPacketizationMode, "1"}})
|
||||
.IsSameCodec(Sdp("H264")));
|
||||
|
||||
EXPECT_TRUE(
|
||||
Sdp("H264", Params{{cricket::kH264FmtpPacketizationMode, "1"}})
|
||||
.IsSameCodec(
|
||||
Sdp("H264", Params{{cricket::kH264FmtpPacketizationMode, "1"}})));
|
||||
}
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#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"
|
||||
#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h"
|
||||
#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h"
|
||||
#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h"
|
||||
#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 {
|
||||
const SdpVideoFormat kFooSdp("Foo");
|
||||
const SdpVideoFormat kBarLowSdp("Bar", {{"profile", "low"}});
|
||||
const SdpVideoFormat kBarHighSdp("Bar", {{"profile", "high"}});
|
||||
|
||||
struct FooDecoderTemplateAdapter {
|
||||
static std::vector<SdpVideoFormat> SupportedFormats() { return {kFooSdp}; }
|
||||
|
||||
static std::unique_ptr<VideoDecoder> CreateDecoder(
|
||||
const SdpVideoFormat& format) {
|
||||
auto decoder = std::make_unique<testing::StrictMock<MockVideoDecoder>>();
|
||||
EXPECT_CALL(*decoder, Destruct);
|
||||
return decoder;
|
||||
}
|
||||
};
|
||||
|
||||
struct BarDecoderTemplateAdapter {
|
||||
static std::vector<SdpVideoFormat> SupportedFormats() {
|
||||
return {kBarLowSdp, kBarHighSdp};
|
||||
}
|
||||
|
||||
static std::unique_ptr<VideoDecoder> CreateDecoder(
|
||||
const SdpVideoFormat& format) {
|
||||
auto decoder = std::make_unique<testing::StrictMock<MockVideoDecoder>>();
|
||||
EXPECT_CALL(*decoder, Destruct);
|
||||
return decoder;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(VideoDecoderFactoryTemplate, OneTemplateAdapterCreateDecoder) {
|
||||
VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter> factory;
|
||||
EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
|
||||
EXPECT_THAT(factory.CreateVideoDecoder(kFooSdp), Ne(nullptr));
|
||||
EXPECT_THAT(factory.CreateVideoDecoder(SdpVideoFormat("FooX")), Eq(nullptr));
|
||||
}
|
||||
|
||||
TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) {
|
||||
VideoDecoderFactoryTemplate<FooDecoderTemplateAdapter,
|
||||
FooDecoderTemplateAdapter>
|
||||
factory;
|
||||
EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
|
||||
}
|
||||
|
||||
TEST(VideoDecoderFactoryTemplate, TwoTemplateAdaptersCreateDecoders) {
|
||||
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));
|
||||
}
|
||||
|
||||
TEST(VideoDecoderFactoryTemplate, LibvpxVp8) {
|
||||
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));
|
||||
}
|
||||
|
||||
TEST(VideoDecoderFactoryTemplate, LibvpxVp9) {
|
||||
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));
|
||||
}
|
||||
|
||||
// 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) {
|
||||
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));
|
||||
}
|
||||
#endif // defined(WEBRTC_USE_H264)
|
||||
|
||||
TEST(VideoDecoderFactoryTemplate, Dav1d) {
|
||||
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));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
* Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/video_codecs/video_decoder_software_fallback_wrapper.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "absl/types/optional.h"
|
||||
#include "api/environment/environment.h"
|
||||
#include "api/environment/environment_factory.h"
|
||||
#include "api/video/encoded_image.h"
|
||||
#include "api/video/video_frame.h"
|
||||
#include "api/video_codecs/video_decoder.h"
|
||||
#include "modules/video_coding/codecs/vp8/include/vp8.h"
|
||||
#include "modules/video_coding/include/video_codec_interface.h"
|
||||
#include "modules/video_coding/include/video_error_codes.h"
|
||||
#include "rtc_base/checks.h"
|
||||
#include "test/explicit_key_value_config.h"
|
||||
#include "test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
class VideoDecoderSoftwareFallbackWrapperTest : public ::testing::Test {
|
||||
protected:
|
||||
VideoDecoderSoftwareFallbackWrapperTest()
|
||||
: VideoDecoderSoftwareFallbackWrapperTest("") {}
|
||||
explicit VideoDecoderSoftwareFallbackWrapperTest(
|
||||
const std::string& field_trials)
|
||||
: field_trials_(field_trials),
|
||||
env_(CreateEnvironment(&field_trials_)),
|
||||
fake_decoder_(new CountingFakeDecoder()),
|
||||
fallback_wrapper_(CreateVideoDecoderSoftwareFallbackWrapper(
|
||||
env_,
|
||||
CreateVp8Decoder(env_),
|
||||
std::unique_ptr<VideoDecoder>(fake_decoder_))) {}
|
||||
|
||||
class CountingFakeDecoder : public VideoDecoder {
|
||||
public:
|
||||
bool Configure(const Settings& settings) override {
|
||||
++configure_count_;
|
||||
return configure_return_value_;
|
||||
}
|
||||
|
||||
int32_t Decode(const EncodedImage& input_image,
|
||||
int64_t render_time_ms) override {
|
||||
++decode_count_;
|
||||
return decode_return_code_;
|
||||
}
|
||||
|
||||
int32_t RegisterDecodeCompleteCallback(
|
||||
DecodedImageCallback* callback) override {
|
||||
decode_complete_callback_ = callback;
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
int32_t Release() override {
|
||||
++release_count_;
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
const char* ImplementationName() const override { return "fake-decoder"; }
|
||||
|
||||
int configure_count_ = 0;
|
||||
int decode_count_ = 0;
|
||||
bool configure_return_value_ = true;
|
||||
int32_t decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
|
||||
DecodedImageCallback* decode_complete_callback_ = nullptr;
|
||||
int release_count_ = 0;
|
||||
int reset_count_ = 0;
|
||||
};
|
||||
test::ExplicitKeyValueConfig field_trials_;
|
||||
const Environment env_;
|
||||
// `fake_decoder_` is owned and released by `fallback_wrapper_`.
|
||||
CountingFakeDecoder* fake_decoder_;
|
||||
std::unique_ptr<VideoDecoder> fallback_wrapper_;
|
||||
};
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, InitializesDecoder) {
|
||||
fallback_wrapper_->Configure({});
|
||||
EXPECT_EQ(1, fake_decoder_->configure_count_);
|
||||
|
||||
EncodedImage encoded_image;
|
||||
encoded_image._frameType = VideoFrameType::kVideoFrameKey;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_EQ(1, fake_decoder_->configure_count_)
|
||||
<< "Initialized decoder should not be reinitialized.";
|
||||
EXPECT_EQ(1, fake_decoder_->decode_count_);
|
||||
}
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
|
||||
UsesFallbackDecoderAfterAnyInitDecodeFailure) {
|
||||
fake_decoder_->configure_return_value_ = false;
|
||||
fallback_wrapper_->Configure({});
|
||||
EXPECT_EQ(1, fake_decoder_->configure_count_);
|
||||
|
||||
EncodedImage encoded_image;
|
||||
encoded_image._frameType = VideoFrameType::kVideoFrameKey;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_EQ(1, fake_decoder_->configure_count_)
|
||||
<< "Should not have attempted reinitializing the fallback decoder on "
|
||||
"keyframe.";
|
||||
// Unfortunately faking a VP8 frame is hard. Rely on no Decode -> using SW
|
||||
// decoder.
|
||||
EXPECT_EQ(0, fake_decoder_->decode_count_)
|
||||
<< "Decoder used even though no InitDecode had succeeded.";
|
||||
}
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, IsSoftwareFallbackSticky) {
|
||||
fallback_wrapper_->Configure({});
|
||||
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
|
||||
EncodedImage encoded_image;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_EQ(1, fake_decoder_->decode_count_);
|
||||
|
||||
// Software fallback should be sticky, fake_decoder_ shouldn't be used.
|
||||
encoded_image._frameType = VideoFrameType::kVideoFrameKey;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_EQ(1, fake_decoder_->decode_count_)
|
||||
<< "Decoder shouldn't be used after failure.";
|
||||
|
||||
// fake_decoder_ should have only been initialized once during the test.
|
||||
EXPECT_EQ(1, fake_decoder_->configure_count_);
|
||||
}
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, DoesNotFallbackOnEveryError) {
|
||||
fallback_wrapper_->Configure({});
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
|
||||
EncodedImage encoded_image;
|
||||
EXPECT_EQ(fake_decoder_->decode_return_code_,
|
||||
fallback_wrapper_->Decode(encoded_image, -1));
|
||||
EXPECT_EQ(1, fake_decoder_->decode_count_);
|
||||
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_EQ(2, fake_decoder_->decode_count_)
|
||||
<< "Decoder should be active even though previous decode failed.";
|
||||
}
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, UsesHwDecoderAfterReinit) {
|
||||
fallback_wrapper_->Configure({});
|
||||
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
|
||||
EncodedImage encoded_image;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_EQ(1, fake_decoder_->decode_count_);
|
||||
|
||||
fallback_wrapper_->Release();
|
||||
fallback_wrapper_->Configure({});
|
||||
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_EQ(2, fake_decoder_->decode_count_)
|
||||
<< "Should not be using fallback after reinit.";
|
||||
}
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, ForwardsReleaseCall) {
|
||||
fallback_wrapper_->Configure({});
|
||||
fallback_wrapper_->Release();
|
||||
EXPECT_EQ(1, fake_decoder_->release_count_);
|
||||
|
||||
fallback_wrapper_->Configure({});
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
|
||||
EncodedImage encoded_image;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_EQ(2, fake_decoder_->release_count_)
|
||||
<< "Decoder should be released during fallback.";
|
||||
fallback_wrapper_->Release();
|
||||
EXPECT_EQ(2, fake_decoder_->release_count_);
|
||||
}
|
||||
|
||||
// TODO(pbos): Fake a VP8 frame well enough to actually receive a callback from
|
||||
// the software decoder.
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
|
||||
ForwardsRegisterDecodeCompleteCallback) {
|
||||
class FakeDecodedImageCallback : public DecodedImageCallback {
|
||||
int32_t Decoded(VideoFrame& decodedImage) override { return 0; }
|
||||
int32_t Decoded(webrtc::VideoFrame& decodedImage,
|
||||
int64_t decode_time_ms) override {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
return -1;
|
||||
}
|
||||
void Decoded(webrtc::VideoFrame& decodedImage,
|
||||
absl::optional<int32_t> decode_time_ms,
|
||||
absl::optional<uint8_t> qp) override {
|
||||
RTC_DCHECK_NOTREACHED();
|
||||
}
|
||||
} callback;
|
||||
|
||||
fallback_wrapper_->Configure({});
|
||||
fallback_wrapper_->RegisterDecodeCompleteCallback(&callback);
|
||||
EXPECT_EQ(&callback, fake_decoder_->decode_complete_callback_);
|
||||
}
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
|
||||
ReportsFallbackImplementationName) {
|
||||
fallback_wrapper_->Configure({});
|
||||
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE;
|
||||
EncodedImage encoded_image;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
// Hard coded expected value since libvpx is the software implementation name
|
||||
// for VP8. Change accordingly if the underlying implementation does.
|
||||
EXPECT_STREQ("libvpx (fallback from: fake-decoder)",
|
||||
fallback_wrapper_->ImplementationName());
|
||||
fallback_wrapper_->Release();
|
||||
}
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest, FallbacksOnTooManyErrors) {
|
||||
fallback_wrapper_->Configure({});
|
||||
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
|
||||
EncodedImage encoded_image;
|
||||
encoded_image._frameType = VideoFrameType::kVideoFrameKey;
|
||||
// Doesn't fallback from a single error.
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_STREQ("fake-decoder", fallback_wrapper_->ImplementationName());
|
||||
|
||||
// However, many frames with the same error, fallback should happen.
|
||||
const int kNumFramesToEncode = 10;
|
||||
for (int i = 0; i < kNumFramesToEncode; ++i) {
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
}
|
||||
// Hard coded expected value since libvpx is the software implementation name
|
||||
// for VP8. Change accordingly if the underlying implementation does.
|
||||
EXPECT_STREQ("libvpx (fallback from: fake-decoder)",
|
||||
fallback_wrapper_->ImplementationName());
|
||||
fallback_wrapper_->Release();
|
||||
}
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
|
||||
DoesNotFallbackOnDeltaFramesErrors) {
|
||||
fallback_wrapper_->Configure({});
|
||||
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
|
||||
EncodedImage encoded_image;
|
||||
encoded_image._frameType = VideoFrameType::kVideoFrameDelta;
|
||||
|
||||
// Many decoded frames with the same error
|
||||
const int kNumFramesToEncode = 10;
|
||||
for (int i = 0; i < kNumFramesToEncode; ++i) {
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
}
|
||||
EXPECT_STREQ("fake-decoder", fallback_wrapper_->ImplementationName());
|
||||
|
||||
fallback_wrapper_->Release();
|
||||
}
|
||||
|
||||
TEST_F(VideoDecoderSoftwareFallbackWrapperTest,
|
||||
DoesNotFallbacksOnNonConsequtiveErrors) {
|
||||
fallback_wrapper_->Configure({});
|
||||
|
||||
EncodedImage encoded_image;
|
||||
encoded_image._frameType = VideoFrameType::kVideoFrameKey;
|
||||
|
||||
const int kNumFramesToEncode = 10;
|
||||
for (int i = 0; i < kNumFramesToEncode; ++i) {
|
||||
// Interleaved errors and successful decodes.
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_ERROR;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
fake_decoder_->decode_return_code_ = WEBRTC_VIDEO_CODEC_OK;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
}
|
||||
EXPECT_STREQ("fake-decoder", fallback_wrapper_->ImplementationName());
|
||||
fallback_wrapper_->Release();
|
||||
}
|
||||
|
||||
class ForcedSoftwareDecoderFallbackTest
|
||||
: public VideoDecoderSoftwareFallbackWrapperTest {
|
||||
public:
|
||||
ForcedSoftwareDecoderFallbackTest()
|
||||
: VideoDecoderSoftwareFallbackWrapperTest(
|
||||
"WebRTC-Video-ForcedSwDecoderFallback/Enabled/") {
|
||||
fake_decoder_ = new CountingFakeDecoder();
|
||||
sw_fallback_decoder_ = new CountingFakeDecoder();
|
||||
fallback_wrapper_ = CreateVideoDecoderSoftwareFallbackWrapper(
|
||||
env_, std::unique_ptr<VideoDecoder>(sw_fallback_decoder_),
|
||||
std::unique_ptr<VideoDecoder>(fake_decoder_));
|
||||
}
|
||||
|
||||
CountingFakeDecoder* sw_fallback_decoder_;
|
||||
};
|
||||
|
||||
TEST_F(ForcedSoftwareDecoderFallbackTest, UsesForcedFallback) {
|
||||
fallback_wrapper_->Configure({});
|
||||
EXPECT_EQ(1, sw_fallback_decoder_->configure_count_);
|
||||
|
||||
EncodedImage encoded_image;
|
||||
encoded_image._frameType = VideoFrameType::kVideoFrameKey;
|
||||
fallback_wrapper_->Decode(encoded_image, -1);
|
||||
EXPECT_EQ(1, sw_fallback_decoder_->configure_count_);
|
||||
EXPECT_EQ(1, sw_fallback_decoder_->decode_count_);
|
||||
|
||||
fallback_wrapper_->Release();
|
||||
EXPECT_EQ(1, sw_fallback_decoder_->release_count_);
|
||||
|
||||
// Only fallback decoder should have been used.
|
||||
EXPECT_EQ(0, fake_decoder_->configure_count_);
|
||||
EXPECT_EQ(0, fake_decoder_->decode_count_);
|
||||
EXPECT_EQ(0, fake_decoder_->release_count_);
|
||||
}
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (c) 2022 The WebRTC project authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license
|
||||
* that can be found in the LICENSE file in the root of the source
|
||||
* tree. An additional intellectual property rights grant can be found
|
||||
* in the file PATENTS. All contributing project authors may
|
||||
* be found in the AUTHORS file in the root of the source tree.
|
||||
*/
|
||||
|
||||
#include "api/test/mock_video_encoder.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_libvpx_vp8_adapter.h"
|
||||
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h"
|
||||
#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h"
|
||||
#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::IsNull;
|
||||
using ::testing::Not;
|
||||
using ::testing::NotNull;
|
||||
using ::testing::UnorderedElementsAre;
|
||||
|
||||
namespace webrtc {
|
||||
namespace {
|
||||
using CodecSupport = VideoEncoderFactory::CodecSupport;
|
||||
const SdpVideoFormat kFooSdp("Foo");
|
||||
const SdpVideoFormat kBarLowSdp("Bar", {{"profile", "low"}});
|
||||
const SdpVideoFormat kBarHighSdp("Bar", {{"profile", "high"}});
|
||||
|
||||
struct FooEncoderTemplateAdapter {
|
||||
static std::vector<SdpVideoFormat> SupportedFormats() { return {kFooSdp}; }
|
||||
|
||||
static std::unique_ptr<VideoEncoder> CreateEncoder(
|
||||
const SdpVideoFormat& format) {
|
||||
return std::make_unique<testing::StrictMock<MockVideoEncoder>>();
|
||||
}
|
||||
|
||||
static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
|
||||
return scalability_mode == ScalabilityMode::kL1T2 ||
|
||||
scalability_mode == ScalabilityMode::kL1T3;
|
||||
}
|
||||
};
|
||||
|
||||
struct BarEncoderTemplateAdapter {
|
||||
static std::vector<SdpVideoFormat> SupportedFormats() {
|
||||
return {kBarLowSdp, kBarHighSdp};
|
||||
}
|
||||
|
||||
static std::unique_ptr<VideoEncoder> CreateEncoder(
|
||||
const SdpVideoFormat& format) {
|
||||
return std::make_unique<testing::StrictMock<MockVideoEncoder>>();
|
||||
}
|
||||
|
||||
static bool IsScalabilityModeSupported(ScalabilityMode scalability_mode) {
|
||||
return scalability_mode == ScalabilityMode::kL1T2 ||
|
||||
scalability_mode == ScalabilityMode::kL1T3 ||
|
||||
scalability_mode == ScalabilityMode::kS2T1 ||
|
||||
scalability_mode == ScalabilityMode::kS3T3;
|
||||
}
|
||||
};
|
||||
|
||||
TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCreateEncoder) {
|
||||
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
|
||||
EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), NotNull());
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), IsNull());
|
||||
}
|
||||
|
||||
TEST(VideoEncoderFactoryTemplate, OneTemplateAdapterCodecSupport) {
|
||||
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter> factory;
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, absl::nullopt),
|
||||
Field(&CodecSupport::is_supported, true));
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "L1T2"),
|
||||
Field(&CodecSupport::is_supported, true));
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "S3T3"),
|
||||
Field(&CodecSupport::is_supported, false));
|
||||
EXPECT_THAT(factory.QueryCodecSupport(SdpVideoFormat("FooX"), absl::nullopt),
|
||||
Field(&CodecSupport::is_supported, false));
|
||||
}
|
||||
|
||||
TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersNoDuplicates) {
|
||||
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
|
||||
FooEncoderTemplateAdapter>
|
||||
factory;
|
||||
EXPECT_THAT(factory.GetSupportedFormats(), UnorderedElementsAre(kFooSdp));
|
||||
}
|
||||
|
||||
TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCreateEncoders) {
|
||||
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
|
||||
BarEncoderTemplateAdapter>
|
||||
factory;
|
||||
EXPECT_THAT(factory.GetSupportedFormats(),
|
||||
UnorderedElementsAre(kFooSdp, kBarLowSdp, kBarHighSdp));
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(kFooSdp), NotNull());
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(kBarLowSdp), NotNull());
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(kBarHighSdp), NotNull());
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("FooX")), IsNull());
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(SdpVideoFormat("Bar")), NotNull());
|
||||
}
|
||||
|
||||
TEST(VideoEncoderFactoryTemplate, TwoTemplateAdaptersCodecSupport) {
|
||||
VideoEncoderFactoryTemplate<FooEncoderTemplateAdapter,
|
||||
BarEncoderTemplateAdapter>
|
||||
factory;
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, absl::nullopt),
|
||||
Field(&CodecSupport::is_supported, true));
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "L1T2"),
|
||||
Field(&CodecSupport::is_supported, true));
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kFooSdp, "S3T3"),
|
||||
Field(&CodecSupport::is_supported, false));
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kBarLowSdp, absl::nullopt),
|
||||
Field(&CodecSupport::is_supported, true));
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kBarHighSdp, absl::nullopt),
|
||||
Field(&CodecSupport::is_supported, true));
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kBarLowSdp, "S2T1"),
|
||||
Field(&CodecSupport::is_supported, true));
|
||||
EXPECT_THAT(factory.QueryCodecSupport(kBarHighSdp, "S3T2"),
|
||||
Field(&CodecSupport::is_supported, false));
|
||||
}
|
||||
|
||||
TEST(VideoEncoderFactoryTemplate, LibvpxVp8) {
|
||||
VideoEncoderFactoryTemplate<LibvpxVp8EncoderTemplateAdapter> factory;
|
||||
auto formats = factory.GetSupportedFormats();
|
||||
EXPECT_THAT(formats.size(), 1);
|
||||
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "VP8"));
|
||||
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
|
||||
Contains(ScalabilityMode::kL1T3)));
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull());
|
||||
}
|
||||
|
||||
TEST(VideoEncoderFactoryTemplate, LibvpxVp9) {
|
||||
VideoEncoderFactoryTemplate<LibvpxVp9EncoderTemplateAdapter> factory;
|
||||
auto formats = factory.GetSupportedFormats();
|
||||
EXPECT_THAT(formats, Not(IsEmpty()));
|
||||
EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "VP9")));
|
||||
EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes,
|
||||
Contains(ScalabilityMode::kL3T3_KEY))));
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(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(VideoEncoderFactoryTemplate, OpenH264) {
|
||||
VideoEncoderFactoryTemplate<OpenH264EncoderTemplateAdapter> factory;
|
||||
auto formats = factory.GetSupportedFormats();
|
||||
EXPECT_THAT(formats, Not(IsEmpty()));
|
||||
EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::name, "H264")));
|
||||
EXPECT_THAT(formats, Each(Field(&SdpVideoFormat::scalability_modes,
|
||||
Contains(ScalabilityMode::kL1T3))));
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull());
|
||||
}
|
||||
#endif // defined(WEBRTC_USE_H264)
|
||||
|
||||
TEST(VideoEncoderFactoryTemplate, LibaomAv1) {
|
||||
VideoEncoderFactoryTemplate<LibaomAv1EncoderTemplateAdapter> factory;
|
||||
auto formats = factory.GetSupportedFormats();
|
||||
EXPECT_THAT(formats.size(), 1);
|
||||
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::name, "AV1"));
|
||||
EXPECT_THAT(formats[0], Field(&SdpVideoFormat::scalability_modes,
|
||||
Contains(ScalabilityMode::kL3T3_KEY)));
|
||||
EXPECT_THAT(factory.CreateVideoEncoder(formats[0]), NotNull());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace webrtc
|
||||
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue