253 lines
8.6 KiB
C++
253 lines
8.6 KiB
C++
|
|
#include <gtest/gtest.h>
|
||
|
|
#include <android/log.h>
|
||
|
|
#include "Decoder/VideoDecoderFactory.h"
|
||
|
|
#include "Decoder/IVideoDecoder.h"
|
||
|
|
#include "Common/VideoTypes.h"
|
||
|
|
|
||
|
|
#define LOG_TAG "VideoDecoderFactoryTest"
|
||
|
|
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
|
||
|
|
|
||
|
|
using namespace VavCore;
|
||
|
|
|
||
|
|
class VideoDecoderFactoryTest : public ::testing::Test {
|
||
|
|
protected:
|
||
|
|
void SetUp() override {
|
||
|
|
LOGI("Setting up VideoDecoderFactoryTest");
|
||
|
|
VideoDecoderFactory::InitializeFactory();
|
||
|
|
}
|
||
|
|
|
||
|
|
void TearDown() override {
|
||
|
|
LOGI("Tearing down VideoDecoderFactoryTest");
|
||
|
|
VideoDecoderFactory::CleanupFactory();
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Test 1: Factory initialization
|
||
|
|
TEST_F(VideoDecoderFactoryTest, FactoryInitialization) {
|
||
|
|
LOGI("Test: FactoryInitialization");
|
||
|
|
|
||
|
|
// Initialization is done in SetUp, this test just verifies it doesn't crash
|
||
|
|
SUCCEED() << "Factory initialized successfully";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 2: Get available decoders for AV1
|
||
|
|
TEST_F(VideoDecoderFactoryTest, GetAvailableAV1Decoders) {
|
||
|
|
LOGI("Test: GetAvailableAV1Decoders");
|
||
|
|
|
||
|
|
auto decoders = VideoDecoderFactory::GetAvailableDecoders(VideoCodecType::AV1);
|
||
|
|
|
||
|
|
LOGI("Found %zu AV1 decoders", decoders.size());
|
||
|
|
for (const auto& decoder : decoders) {
|
||
|
|
LOGI(" - %s", decoder.c_str());
|
||
|
|
}
|
||
|
|
|
||
|
|
// On Android, we should have at least MediaCodec or dav1d
|
||
|
|
EXPECT_GT(decoders.size(), 0) << "Should have at least one AV1 decoder";
|
||
|
|
|
||
|
|
// Check if mediacodec is available
|
||
|
|
bool hasMediaCodec = false;
|
||
|
|
bool hasDav1d = false;
|
||
|
|
|
||
|
|
for (const auto& decoder : decoders) {
|
||
|
|
if (decoder == "mediacodec") hasMediaCodec = true;
|
||
|
|
if (decoder == "dav1d") hasDav1d = true;
|
||
|
|
}
|
||
|
|
|
||
|
|
LOGI("MediaCodec available: %s", hasMediaCodec ? "YES" : "NO");
|
||
|
|
LOGI("dav1d available: %s", hasDav1d ? "YES" : "NO");
|
||
|
|
|
||
|
|
SUCCEED() << "Available decoders listed successfully";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 3: Create decoder with AUTO type
|
||
|
|
TEST_F(VideoDecoderFactoryTest, CreateDecoderWithAutoType) {
|
||
|
|
LOGI("Test: CreateDecoderWithAutoType");
|
||
|
|
|
||
|
|
auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, VideoDecoderFactory::DecoderType::AUTO);
|
||
|
|
|
||
|
|
ASSERT_NE(decoder, nullptr) << "Should create a decoder with AUTO type";
|
||
|
|
|
||
|
|
SUCCEED() << "Created decoder with AUTO type";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 4: Create decoder with MEDIACODEC type
|
||
|
|
TEST_F(VideoDecoderFactoryTest, CreateDecoderWithMediaCodecType) {
|
||
|
|
LOGI("Test: CreateDecoderWithMediaCodecType");
|
||
|
|
|
||
|
|
auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, VideoDecoderFactory::DecoderType::MEDIACODEC);
|
||
|
|
|
||
|
|
if (decoder != nullptr) {
|
||
|
|
LOGI("MediaCodec decoder created successfully");
|
||
|
|
SUCCEED() << "MediaCodec decoder available";
|
||
|
|
} else {
|
||
|
|
GTEST_SKIP() << "MediaCodec decoder not available (API < 29 or no support)";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 5: Create decoder with DAV1D type
|
||
|
|
TEST_F(VideoDecoderFactoryTest, CreateDecoderWithDav1dType) {
|
||
|
|
LOGI("Test: CreateDecoderWithDav1dType");
|
||
|
|
|
||
|
|
auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, VideoDecoderFactory::DecoderType::DAV1D);
|
||
|
|
|
||
|
|
if (decoder != nullptr) {
|
||
|
|
LOGI("dav1d decoder created successfully");
|
||
|
|
SUCCEED() << "dav1d decoder available";
|
||
|
|
} else {
|
||
|
|
GTEST_SKIP() << "dav1d decoder not available (build configuration)";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 6: Create decoder by name
|
||
|
|
TEST_F(VideoDecoderFactoryTest, CreateDecoderByName) {
|
||
|
|
LOGI("Test: CreateDecoderByName");
|
||
|
|
|
||
|
|
auto decoder = VideoDecoderFactory::CreateDecoder("mediacodec");
|
||
|
|
|
||
|
|
if (decoder != nullptr) {
|
||
|
|
LOGI("Created decoder by name successfully");
|
||
|
|
SUCCEED() << "Decoder created by name successfully";
|
||
|
|
} else {
|
||
|
|
GTEST_SKIP() << "Named decoder not available";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 7: Create decoder from codec ID
|
||
|
|
TEST_F(VideoDecoderFactoryTest, CreateDecoderFromCodecId) {
|
||
|
|
LOGI("Test: CreateDecoderFromCodecId");
|
||
|
|
|
||
|
|
auto decoder = VideoDecoderFactory::CreateDecoderFromCodecId("V_AV1", VideoDecoderFactory::DecoderType::AUTO);
|
||
|
|
|
||
|
|
ASSERT_NE(decoder, nullptr) << "Should create decoder from codec ID";
|
||
|
|
|
||
|
|
SUCCEED() << "Decoder created from codec ID successfully";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 8: Check codec support
|
||
|
|
TEST_F(VideoDecoderFactoryTest, CheckCodecSupport) {
|
||
|
|
LOGI("Test: CheckCodecSupport");
|
||
|
|
|
||
|
|
bool av1Supported = VideoDecoderFactory::IsCodecSupported(VideoCodecType::AV1);
|
||
|
|
bool vp9Supported = VideoDecoderFactory::IsCodecSupported(VideoCodecType::VP9);
|
||
|
|
|
||
|
|
LOGI("AV1 supported: %s", av1Supported ? "YES" : "NO");
|
||
|
|
LOGI("VP9 supported: %s", vp9Supported ? "YES" : "NO");
|
||
|
|
|
||
|
|
EXPECT_TRUE(av1Supported) << "AV1 should be supported on Android";
|
||
|
|
|
||
|
|
SUCCEED() << "Codec support check completed";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 9: Get decoder description
|
||
|
|
TEST_F(VideoDecoderFactoryTest, GetDecoderDescription) {
|
||
|
|
LOGI("Test: GetDecoderDescription");
|
||
|
|
|
||
|
|
auto decoders = VideoDecoderFactory::GetAvailableDecoders(VideoCodecType::AV1);
|
||
|
|
|
||
|
|
for (const auto& decoderName : decoders) {
|
||
|
|
std::string description = VideoDecoderFactory::GetDecoderDescription(decoderName);
|
||
|
|
|
||
|
|
LOGI("Decoder: %s", decoderName.c_str());
|
||
|
|
LOGI(" Description: %s", description.c_str());
|
||
|
|
|
||
|
|
EXPECT_FALSE(description.empty()) << "Description should not be empty";
|
||
|
|
}
|
||
|
|
|
||
|
|
SUCCEED() << "Decoder descriptions retrieved";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 10: Decoder priority order
|
||
|
|
TEST_F(VideoDecoderFactoryTest, DecoderPriorityOrder) {
|
||
|
|
LOGI("Test: DecoderPriorityOrder");
|
||
|
|
|
||
|
|
auto decoders = VideoDecoderFactory::GetAvailableDecoders(VideoCodecType::AV1);
|
||
|
|
|
||
|
|
if (decoders.size() >= 2) {
|
||
|
|
LOGI("Decoder priority order:");
|
||
|
|
for (size_t i = 0; i < decoders.size(); i++) {
|
||
|
|
LOGI(" %zu. %s", i + 1, decoders[i].c_str());
|
||
|
|
}
|
||
|
|
|
||
|
|
// On Android, MediaCodec should typically be first (higher priority)
|
||
|
|
if (decoders[0] == "mediacodec") {
|
||
|
|
SUCCEED() << "MediaCodec has highest priority (as expected)";
|
||
|
|
} else {
|
||
|
|
LOGI("Highest priority: %s", decoders[0].c_str());
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
LOGI("Only one decoder available");
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 11: Create multiple decoders concurrently
|
||
|
|
TEST_F(VideoDecoderFactoryTest, CreateMultipleDecodersConcurrently) {
|
||
|
|
LOGI("Test: CreateMultipleDecodersConcurrently");
|
||
|
|
|
||
|
|
std::vector<std::unique_ptr<IVideoDecoder>> decoders;
|
||
|
|
|
||
|
|
// Try to create 3 decoders
|
||
|
|
for (int i = 0; i < 3; i++) {
|
||
|
|
auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, VideoDecoderFactory::DecoderType::AUTO);
|
||
|
|
|
||
|
|
if (decoder != nullptr) {
|
||
|
|
LOGI("Created decoder %d", i + 1);
|
||
|
|
decoders.push_back(std::move(decoder));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
EXPECT_GT(decoders.size(), 0) << "Should create at least one decoder";
|
||
|
|
LOGI("Successfully created %zu concurrent decoders", decoders.size());
|
||
|
|
|
||
|
|
SUCCEED() << "Multiple decoders created successfully";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 12: Factory cleanup and reinitialization
|
||
|
|
TEST_F(VideoDecoderFactoryTest, CleanupAndReinitialize) {
|
||
|
|
LOGI("Test: CleanupAndReinitialize");
|
||
|
|
|
||
|
|
// Cleanup
|
||
|
|
VideoDecoderFactory::CleanupFactory();
|
||
|
|
|
||
|
|
// Try to get decoders (should be empty)
|
||
|
|
auto decoders1 = VideoDecoderFactory::GetAvailableDecoders(VideoCodecType::AV1);
|
||
|
|
EXPECT_TRUE(decoders1.empty()) << "Should have no decoders after cleanup";
|
||
|
|
|
||
|
|
// Reinitialize
|
||
|
|
VideoDecoderFactory::InitializeFactory();
|
||
|
|
|
||
|
|
// Get decoders again (should be available)
|
||
|
|
auto decoders2 = VideoDecoderFactory::GetAvailableDecoders(VideoCodecType::AV1);
|
||
|
|
EXPECT_GT(decoders2.size(), 0) << "Should have decoders after reinitialization";
|
||
|
|
|
||
|
|
SUCCEED() << "Cleanup and reinitialization successful";
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 13: Invalid decoder type handling
|
||
|
|
TEST_F(VideoDecoderFactoryTest, InvalidDecoderTypeHandling) {
|
||
|
|
LOGI("Test: InvalidDecoderTypeHandling");
|
||
|
|
|
||
|
|
// Try to create decoder with NVDEC (not available on Android)
|
||
|
|
auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::AV1, VideoDecoderFactory::DecoderType::NVDEC);
|
||
|
|
|
||
|
|
EXPECT_EQ(decoder, nullptr) << "Should return nullptr for unsupported decoder type (NVDEC on Android)";
|
||
|
|
|
||
|
|
if (decoder == nullptr) {
|
||
|
|
SUCCEED() << "Correctly handled invalid decoder type";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Test 14: Create decoder for unsupported codec
|
||
|
|
TEST_F(VideoDecoderFactoryTest, CreateDecoderForUnsupportedCodec) {
|
||
|
|
LOGI("Test: CreateDecoderForUnsupportedCodec");
|
||
|
|
|
||
|
|
// Try to create decoder for H265 (may not be supported)
|
||
|
|
auto decoder = VideoDecoderFactory::CreateDecoder(VideoCodecType::H265, VideoDecoderFactory::DecoderType::AUTO);
|
||
|
|
|
||
|
|
if (decoder == nullptr) {
|
||
|
|
LOGI("H265 decoder not available (expected on AV1-only build)");
|
||
|
|
SUCCEED() << "Correctly handled unsupported codec";
|
||
|
|
} else {
|
||
|
|
LOGI("H265 decoder available");
|
||
|
|
SUCCEED() << "H265 decoder unexpectedly available";
|
||
|
|
}
|
||
|
|
}
|