Refactoring MediaCodec decoder
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
#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";
|
||||
}
|
||||
Reference in New Issue
Block a user