Files
video-v1/vav2/platforms/android/tests/unit-tests/src/MediaCodecSelectorTest.cpp

233 lines
7.1 KiB
C++
Raw Normal View History

2025-09-30 19:54:29 +09:00
#include <gtest/gtest.h>
#include <android/log.h>
#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<MediaCodecSelector>();
}
void TearDown() override {
LOGI("Tearing down MediaCodecSelectorTest");
selector.reset();
}
std::unique_ptr<MediaCodecSelector> selector;
};
// Test 1: Get available AV1 codecs (using EnumerateAV1Decoders)
TEST_F(MediaCodecSelectorTest, GetAvailableAV1Codecs) {
LOGI("Test: GetAvailableAV1Codecs");
std::vector<std::string> 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";
}