#include #include #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> 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"; } }