#include #include #include "Decoder/MediaCodecSelector.h" #define LOG_TAG "MediaCodecSelectorTest" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) using namespace VavCore; class MediaCodecSelectorTest : public ::testing::Test { protected: void SetUp() override { LOGI("Setting up MediaCodecSelectorTest"); selector = std::make_unique(); } void TearDown() override { LOGI("Tearing down MediaCodecSelectorTest"); selector.reset(); } std::unique_ptr selector; }; // Test 1: Get available AV1 codecs (using EnumerateAV1Decoders) TEST_F(MediaCodecSelectorTest, GetAvailableAV1Codecs) { LOGI("Test: GetAvailableAV1Codecs"); std::vector codecs = selector->EnumerateAV1Decoders(); LOGI("Found %zu AV1 codecs", codecs.size()); for (const auto& codec : codecs) { LOGI(" - %s", codec.c_str()); } EXPECT_GE(codecs.size(), 0) << "Should have 0 or more codecs"; if (codecs.size() > 0) { SUCCEED() << "Found " << codecs.size() << " AV1 codec(s)"; } else { GTEST_SKIP() << "No AV1 codecs available (API < 29 or no support)"; } } // Test 2: Get enhanced codec list TEST_F(MediaCodecSelectorTest, GetEnhancedCodecList) { LOGI("Test: GetEnhancedCodecList"); auto codecs = selector->GetEnhancedCodecList(); LOGI("Found %zu enhanced codecs", codecs.size()); for (const auto& codec : codecs) { LOGI(" - %s", codec.c_str()); } if (codecs.size() > 0) { SUCCEED() << "Enhanced codec list retrieved: " << codecs.size() << " codec(s)"; } else { GTEST_SKIP() << "No enhanced codecs available"; } } // Test 3: Get CodecInfo structures TEST_F(MediaCodecSelectorTest, GetCodecInfoStructures) { LOGI("Test: GetCodecInfoStructures"); auto codecInfos = selector->GetAvailableCodecs(); LOGI("Found %zu codec info structures", codecInfos.size()); for (const auto& info : codecInfos) { LOGI(" - name=%s, vendor=%s, hw=%s, priority=%d", info.name.c_str(), info.vendor.c_str(), info.is_hardware ? "YES" : "NO", info.priority); } if (codecInfos.size() > 0) { SUCCEED() << "CodecInfo structures retrieved"; } else { GTEST_SKIP() << "No codec info available"; } } // Test 4: Empty codec list handling TEST_F(MediaCodecSelectorTest, EmptyCodecListHandling) { LOGI("Test: EmptyCodecListHandling"); // Just verify that empty list doesn't crash auto codecs = selector->EnumerateAV1Decoders(); LOGI("Codec count: %zu (may be 0 on devices without AV1)", codecs.size()); SUCCEED() << "Empty codec list handled correctly"; } // Test 5: Check hardware codec keywords TEST_F(MediaCodecSelectorTest, CheckHardwareCodecKeywords) { LOGI("Test: CheckHardwareCodecKeywords"); auto codecs = selector->EnumerateAV1Decoders(); if (codecs.empty()) { GTEST_SKIP() << "No codecs available"; } bool foundHardwareKeyword = false; for (const auto& codec : codecs) { if (codec.find("qcom") != std::string::npos || codec.find("qti") != std::string::npos || codec.find("exynos") != std::string::npos || codec.find("sec") != std::string::npos || codec.find("mtk") != std::string::npos) { LOGI("Found hardware codec: %s", codec.c_str()); foundHardwareKeyword = true; } } if (foundHardwareKeyword) { SUCCEED() << "Hardware codecs found"; } else { LOGI("No hardware keywords found (may be emulator or old device)"); } } // Test 6: Verify Qualcomm priority (if available) TEST_F(MediaCodecSelectorTest, VerifyQualcommPriorityIfAvailable) { LOGI("Test: VerifyQualcommPriorityIfAvailable"); auto codecs = selector->EnumerateAV1Decoders(); if (codecs.empty()) { GTEST_SKIP() << "No codecs available"; } bool hasQualcomm = false; for (const auto& codec : codecs) { if (codec.find("qti") != std::string::npos || codec.find("qcom") != std::string::npos) { LOGI("Qualcomm codec found: %s", codec.c_str()); hasQualcomm = true; break; } } if (hasQualcomm) { SUCCEED() << "Qualcomm codec detected"; } else { LOGI("No Qualcomm codec (device may not have Snapdragon chip)"); } } // Test 7: Create AV1 decoder TEST_F(MediaCodecSelectorTest, CreateAV1Decoder) { LOGI("Test: CreateAV1Decoder"); AMediaCodec* codec = selector->CreateAV1Decoder(); if (codec != nullptr) { LOGI("AV1 decoder created successfully"); // NOTE: Do not delete codec here - it's managed by MediaCodecSelector // Deleting it would cause double-free or use-after-free // AMediaCodec_delete(codec); SUCCEED() << "Decoder creation successful"; } else { GTEST_SKIP() << "Could not create AV1 decoder (API < 29 or no support)"; } } // Test 8: Enhanced codec list comparison TEST_F(MediaCodecSelectorTest, EnhancedCodecListComparison) { LOGI("Test: EnhancedCodecListComparison"); auto basicCodecs = selector->EnumerateAV1Decoders(); auto enhancedCodecs = selector->GetEnhancedCodecList(); LOGI("Basic codecs: %zu", basicCodecs.size()); LOGI("Enhanced codecs: %zu", enhancedCodecs.size()); // Enhanced list may have more codecs due to keyword matching EXPECT_GE(enhancedCodecs.size(), basicCodecs.size()) << "Enhanced list should have at least as many codecs as basic list"; SUCCEED() << "Codec list comparison complete"; } // Test 9: CodecInfo priority ordering TEST_F(MediaCodecSelectorTest, CodecInfoPriorityOrdering) { LOGI("Test: CodecInfoPriorityOrdering"); auto codecInfos = selector->GetAvailableCodecs(); if (codecInfos.size() < 2) { GTEST_SKIP() << "Need at least 2 codecs for priority test"; } // Check if list is sorted by priority (lower number = higher priority) bool isSorted = true; for (size_t i = 1; i < codecInfos.size(); i++) { if (codecInfos[i].priority < codecInfos[i-1].priority) { isSorted = false; break; } } if (isSorted) { SUCCEED() << "Codec list is properly sorted by priority"; } else { LOGI("Codec list not strictly sorted (may be intentional)"); } } // Test 10: Hardware vs software classification TEST_F(MediaCodecSelectorTest, HardwareSoftwareClassification) { LOGI("Test: HardwareSoftwareClassification"); auto codecInfos = selector->GetAvailableCodecs(); if (codecInfos.empty()) { GTEST_SKIP() << "No codecs available"; } int hardwareCount = 0; int softwareCount = 0; for (const auto& info : codecInfos) { if (info.is_hardware) { hardwareCount++; LOGI("Hardware codec: %s (vendor=%s)", info.name.c_str(), info.vendor.c_str()); } else { softwareCount++; LOGI("Software codec: %s", info.name.c_str()); } } LOGI("Hardware codecs: %d, Software codecs: %d", hardwareCount, softwareCount); SUCCEED() << "Hardware/software classification complete"; }