#include "base/tizen/provider_callbacks_helper.h"
#include "base/tizen/resource_manager.h"
#include "media/filters/tizen/media_video_codec.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace switches {
extern const char kTizenAppId[] = "widget-id";
} // namespace switches
+namespace base {
+class MockResourceManager : public ResourceManager {
+ public:
+ MockResourceManager() = default;
+ ~MockResourceManager() override = default;
+
+ MOCK_METHOD(absl::optional<AllocatedResource>,
+ AllocateResource,
+ (int, int, ReleaseCB));
+
+ MOCK_METHOD(bool, CanAllocate, (int, int));
+ MOCK_METHOD(bool, SetPriority, (int));
+ MOCK_METHOD(bool, IsCategorySupported, (int));
+
+ MOCK_METHOD(int, GetJpegCategoryId, (const char*, int));
+ MOCK_METHOD(int,
+ GetCapableVideoCategoryId,
+ (const char*, int, int, int, int, int, PreferTexturingSupport));
+
+ MOCK_METHOD(bool, HasUHDVideoDecoder, ());
+};
+} // namespace base
+
namespace media {
class FakeResourceManager : public base::ResourceManager {
side_thread.FlushForTesting();
}
+using ResolutionList = std::vector<gfx::Size>;
+ResolutionList kDecreasingResolutionData[] = {
+ {{3840, 2160},
+ {1920, 1080},
+ {1280, 720},
+ {960, 540},
+ {640, 360},
+ {320, 180}},
+ {{1920, 1080}, {1280, 720}, {960, 540}, {640, 360}, {320, 180}},
+ {{1280, 720}, {960, 540}, {640, 360}, {320, 180}},
+ {{960, 540}, {640, 360}, {320, 180}},
+ {{640, 360}, {320, 180}}};
+
+class DecoderPromotionTestReuseDecoder
+ : public testing::TestWithParam<ResolutionList> {};
+
+TEST_P(DecoderPromotionTestReuseDecoder,
+ H264DecoderMightBeReusedWithLowerResolution) {
+ base::MockResourceManager resource_manager;
+ DecoderPromotion* decoder_promotion = DecoderPromotion::GetInstance();
+ decoder_promotion->SetResourceManagerForTesting(&resource_manager);
+
+ // Do not need to assign callback implementations, as they won't be called.
+ AllocationCallbacks callbacks;
+
+ constexpr const VideoCodecLevel kDefaultLevel = 40;
+ constexpr const size_t kDefaultBitDepth = 8;
+ constexpr const auto kDefaultSampling = VideoChromaSampling::k420;
+ constexpr const auto kDefaultLatency = LatencyMode::kNormal;
+ constexpr const auto kDefaultTexturing = base::PreferTexturingSupport::kNo;
+
+ EXPECT_CALL(resource_manager, SetPriority(testing::_))
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(resource_manager, HasUHDVideoDecoder())
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(resource_manager, IsCategorySupported(testing::_))
+ .WillRepeatedly(testing::Return(true));
+
+ int category = 1;
+ EXPECT_CALL(
+ resource_manager,
+ GetCapableVideoCategoryId(testing::_, testing::_, testing::_, testing::_,
+ testing::_, testing::_, testing::_))
+ .WillRepeatedly([&]() { return category++; });
+ EXPECT_CALL(resource_manager,
+ AllocateResource(testing::_, testing::_, testing::_))
+ .WillOnce([](int, int, base::ResourceManager::ReleaseCB)
+ -> absl::optional<base::AllocatedResource> {
+ return base::AllocatedResource(base::AllocatedResource::Token{},
+ "testing", 1);
+ });
+
+ const auto resolution_list = GetParam();
+
+ absl::optional<AllocatedDecoder> decoder = decoder_promotion->SelectDecoder(
+ {MediaVideoCodec::kCodecH264, kDefaultLevel, resolution_list[0],
+ kDefaultSampling, kDefaultBitDepth, kDefaultLatency, kDefaultTexturing,
+ nullptr},
+ std::move(callbacks));
+ ASSERT_TRUE(decoder.has_value());
+
+ for (size_t i = 1; i < resolution_list.size(); ++i) {
+ EXPECT_FALSE(decoder_promotion->NeedsDecoderReselection(
+ *decoder, {MediaVideoCodec::kCodecH264, kDefaultLevel,
+ resolution_list[i], kDefaultSampling, kDefaultBitDepth,
+ kDefaultLatency, kDefaultTexturing, nullptr}));
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(H264DecoderMightBeReusedWithLowerResolution,
+ DecoderPromotionTestReuseDecoder,
+ testing::ValuesIn(kDecreasingResolutionData));
+
+TEST(DecoderPromotionTestReuseDecoder, H264DecoderMightBeReusedWithLowerLevel) {
+ base::MockResourceManager resource_manager;
+ DecoderPromotion* decoder_promotion = DecoderPromotion::GetInstance();
+ decoder_promotion->SetResourceManagerForTesting(&resource_manager);
+
+ // Do not need to assign callback implementations, as they won't be called.
+ AllocationCallbacks callbacks;
+
+ constexpr const gfx::Size kDefaultCodedSize(1920, 1080);
+ constexpr const MediaVideoCodec kDefaultCodec = MediaVideoCodec::kCodecH264;
+ constexpr const size_t kDefaultBitDepth = 8;
+ constexpr const auto kDefaultSampling = VideoChromaSampling::k420;
+ constexpr const auto kDefaultLatency = LatencyMode::kNormal;
+ constexpr const auto kDefaultTexturing = base::PreferTexturingSupport::kNo;
+
+ EXPECT_CALL(resource_manager, SetPriority(testing::_))
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(resource_manager, HasUHDVideoDecoder())
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(resource_manager, IsCategorySupported(testing::_))
+ .WillRepeatedly(testing::Return(true));
+
+ int category = 1;
+ EXPECT_CALL(
+ resource_manager,
+ GetCapableVideoCategoryId(testing::_, testing::_, testing::_, testing::_,
+ testing::_, testing::_, testing::_))
+ .WillRepeatedly([&]() { return category++; });
+ EXPECT_CALL(resource_manager,
+ AllocateResource(testing::_, testing::_, testing::_))
+ .WillOnce([](int, int, base::ResourceManager::ReleaseCB)
+ -> absl::optional<base::AllocatedResource> {
+ return base::AllocatedResource(base::AllocatedResource::Token{},
+ "testing", 1);
+ });
+
+ absl::optional<AllocatedDecoder> decoder = decoder_promotion->SelectDecoder(
+ {kDefaultCodec, 42, kDefaultCodedSize, kDefaultSampling, kDefaultBitDepth,
+ kDefaultLatency, kDefaultTexturing, nullptr},
+ std::move(callbacks));
+ ASSERT_TRUE(decoder.has_value());
+
+ for (VideoCodecLevel level : {41, 40}) {
+ EXPECT_FALSE(decoder_promotion->NeedsDecoderReselection(
+ *decoder,
+ {kDefaultCodec, level, kDefaultCodedSize, kDefaultSampling,
+ kDefaultBitDepth, kDefaultLatency, kDefaultTexturing, nullptr}));
+ }
+}
+
+TEST(DecoderPromotionTestReuseDecoder,
+ H264DecoderMightBeReusedUptoFHDResolution) {
+ base::MockResourceManager resource_manager;
+ DecoderPromotion* decoder_promotion = DecoderPromotion::GetInstance();
+ decoder_promotion->SetResourceManagerForTesting(&resource_manager);
+
+ // Do not need to assign callback implementations, as they won't be called.
+ AllocationCallbacks callbacks;
+
+ constexpr const VideoCodecLevel kDefaultLevel = 42;
+ constexpr const MediaVideoCodec kDefaultCodec = MediaVideoCodec::kCodecH264;
+ constexpr const size_t kDefaultBitDepth = 8;
+ constexpr const auto kDefaultSampling = VideoChromaSampling::k420;
+ constexpr const auto kDefaultLatency = LatencyMode::kNormal;
+ constexpr const auto kDefaultTexturing = base::PreferTexturingSupport::kNo;
+
+ EXPECT_CALL(resource_manager, SetPriority(testing::_))
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(resource_manager, HasUHDVideoDecoder())
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(resource_manager, IsCategorySupported(testing::_))
+ .WillRepeatedly(testing::Return(true));
+
+ int category = 1;
+ EXPECT_CALL(
+ resource_manager,
+ GetCapableVideoCategoryId(testing::_, testing::_, testing::_, testing::_,
+ testing::_, testing::_, testing::_))
+ .WillRepeatedly([&]() { return category++; });
+ EXPECT_CALL(resource_manager,
+ AllocateResource(testing::_, testing::_, testing::_))
+ .WillOnce([](int, int, base::ResourceManager::ReleaseCB)
+ -> absl::optional<base::AllocatedResource> {
+ return base::AllocatedResource(base::AllocatedResource::Token{},
+ "testing", 1);
+ });
+
+ absl::optional<AllocatedDecoder> decoder = decoder_promotion->SelectDecoder(
+ {kDefaultCodec, kDefaultLevel, gfx::Size(320, 180), kDefaultSampling,
+ kDefaultBitDepth, kDefaultLatency, kDefaultTexturing, nullptr},
+ std::move(callbacks));
+ ASSERT_TRUE(decoder.has_value());
+
+ EXPECT_FALSE(decoder_promotion->NeedsDecoderReselection(
+ *decoder,
+ {kDefaultCodec, kDefaultLevel, gfx::Size{1920, 1080}, kDefaultSampling,
+ kDefaultBitDepth, kDefaultLatency, kDefaultTexturing, nullptr}));
+}
+
+TEST(DecoderPromotionTestReuseDecoder,
+ H264FullHDReusesWhenDecreasingLevelTo42) {
+ base::MockResourceManager resource_manager;
+ DecoderPromotion* decoder_promotion = DecoderPromotion::GetInstance();
+ decoder_promotion->SetResourceManagerForTesting(&resource_manager);
+
+ // Do not need to assign callback implementations, as they won't be called.
+ AllocationCallbacks callbacks;
+
+ constexpr const gfx::Size kDefaultCodedSize(1920, 1080);
+ constexpr const MediaVideoCodec kDefaultCodec = MediaVideoCodec::kCodecH264;
+ constexpr const size_t kDefaultBitDepth = 8;
+ constexpr const auto kDefaultSampling = VideoChromaSampling::k420;
+ constexpr const auto kDefaultLatency = LatencyMode::kNormal;
+ constexpr const auto kDefaultTexturing = base::PreferTexturingSupport::kNo;
+
+ EXPECT_CALL(resource_manager, SetPriority(testing::_))
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(resource_manager, HasUHDVideoDecoder())
+ .WillRepeatedly(testing::Return(true));
+ EXPECT_CALL(resource_manager, IsCategorySupported(testing::_))
+ .WillRepeatedly(testing::Return(true));
+
+ int category = 1;
+ EXPECT_CALL(
+ resource_manager,
+ GetCapableVideoCategoryId(testing::_, testing::_, testing::_, testing::_,
+ testing::_, testing::_, testing::_))
+ .WillRepeatedly([&]() { return category++; });
+ EXPECT_CALL(resource_manager,
+ AllocateResource(testing::_, testing::_, testing::_))
+ .WillOnce([](int, int, base::ResourceManager::ReleaseCB)
+ -> absl::optional<base::AllocatedResource> {
+ return base::AllocatedResource(base::AllocatedResource::Token{},
+ "testing", 1);
+ });
+
+ absl::optional<AllocatedDecoder> decoder = decoder_promotion->SelectDecoder(
+ {kDefaultCodec, 50, kDefaultCodedSize, kDefaultSampling, kDefaultBitDepth,
+ kDefaultLatency, kDefaultTexturing, nullptr},
+ std::move(callbacks));
+ ASSERT_TRUE(decoder.has_value());
+
+ EXPECT_FALSE(decoder_promotion->NeedsDecoderReselection(
+ *decoder,
+ {kDefaultCodec, 42, kDefaultCodedSize, kDefaultSampling, kDefaultBitDepth,
+ kDefaultLatency, kDefaultTexturing, nullptr}));
+}
+
} // namespace media