#include "pch.h" // Basic Windows includes #include // AV1 Player core components (no WinUI3 dependencies) #include "../src/Common/VideoTypes.h" #include "../src/Decoder/VideoDecoderFactory.h" #include "../src/FileIO/WebMFileReader.h" #include "../src/Common/FramePool.h" using namespace Vav2Player; class HeadlessTestRunner { public: HeadlessTestRunner() { std::cout << "=== Vav2Player Headless Test Runner ===" << std::endl; std::cout << "Pure console application for testing AV1 components" << std::endl << std::endl; } bool RunBasicTests(const std::string& videoFile) { std::cout << "[TEST] Starting basic component tests..." << std::endl; // Test 1: VideoDecoderFactory if (!TestVideoDecoderFactory()) return false; // Test 2: WebMFileReader if (!TestWebMFileReader(videoFile)) return false; // Test 3: AV1 Decoder if (!TestAV1Decoder(videoFile)) return false; // Test 4: Full Pipeline if (!TestFullPipeline(videoFile)) return false; std::cout << std::endl << "[SUCCESS] All basic tests passed!" << std::endl; return true; } private: bool TestVideoDecoderFactory() { std::cout << "[TEST 1] VideoDecoderFactory..." << std::endl; try { // Test AUTO decoder creation auto decoder = VideoDecoderFactory::CreateDecoder(VideoDecoderFactory::DecoderType::AUTO); if (!decoder) { std::cout << "[FAIL] Could not create AUTO decoder" << std::endl; return false; } // Test SOFTWARE decoder creation auto softwareDecoder = VideoDecoderFactory::CreateDecoder(VideoDecoderFactory::DecoderType::SOFTWARE); if (!softwareDecoder) { std::cout << "[FAIL] Could not create SOFTWARE decoder" << std::endl; return false; } std::cout << "[PASS] VideoDecoderFactory working correctly" << std::endl; return true; } catch (const std::exception& e) { std::cout << "[FAIL] VideoDecoderFactory exception: " << e.what() << std::endl; return false; } } bool TestWebMFileReader(const std::string& videoFile) { std::cout << "[TEST 2] WebMFileReader with file: " << videoFile << std::endl; try { WebMFileReader reader; // Test file opening if (!reader.OpenFile(videoFile)) { std::cout << "[FAIL] Could not open WebM file" << std::endl; return false; } // Test video track detection auto tracks = reader.GetVideoTracks(); if (tracks.empty()) { std::cout << "[FAIL] No video tracks found" << std::endl; return false; } std::cout << "[INFO] Found " << tracks.size() << " video track(s)" << std::endl; // Test track selection if (!reader.SelectVideoTrack(0)) { std::cout << "[FAIL] Could not select video track 0" << std::endl; return false; } // Test metadata auto metadata = reader.GetVideoMetadata(); std::cout << "[INFO] Video: " << metadata.width << "x" << metadata.height << " @ " << metadata.frameRate << " fps" << std::endl; std::cout << "[PASS] WebMFileReader working correctly" << std::endl; return true; } catch (const std::exception& e) { std::cout << "[FAIL] WebMFileReader exception: " << e.what() << std::endl; return false; } } bool TestAV1Decoder(const std::string& videoFile) { std::cout << "[TEST 3] AV1 Decoder..." << std::endl; try { WebMFileReader reader; if (!reader.OpenFile(videoFile) || !reader.SelectVideoTrack(0)) { std::cout << "[FAIL] Could not prepare file for decoder test" << std::endl; return false; } auto decoder = VideoDecoderFactory::CreateDecoder(VideoDecoderFactory::DecoderType::SOFTWARE); if (!decoder) { std::cout << "[FAIL] Could not create decoder" << std::endl; return false; } if (!decoder->Initialize()) { std::cout << "[FAIL] Could not initialize decoder" << std::endl; return false; } // Test decoding first few frames int decodedFrames = 0; int maxTestFrames = 5; for (int i = 0; i < maxTestFrames; i++) { VideoPacket packet; if (!reader.ReadNextPacket(packet)) { std::cout << "[INFO] End of file reached at frame " << i << std::endl; break; } VideoFrame frame; if (decoder->DecodeFrame(packet, frame)) { decodedFrames++; std::cout << "[INFO] Frame " << (i + 1) << ": " << frame.width << "x" << frame.height << std::endl; } else { std::cout << "[WARN] Failed to decode frame " << (i + 1) << std::endl; } } if (decodedFrames == 0) { std::cout << "[FAIL] No frames were decoded" << std::endl; return false; } std::cout << "[PASS] AV1 Decoder working correctly (" << decodedFrames << " frames decoded)" << std::endl; return true; } catch (const std::exception& e) { std::cout << "[FAIL] AV1 Decoder exception: " << e.what() << std::endl; return false; } } bool TestFullPipeline(const std::string& videoFile) { std::cout << "[TEST 4] Full Pipeline Performance..." << std::endl; try { auto startTime = std::chrono::high_resolution_clock::now(); WebMFileReader reader; if (!reader.OpenFile(videoFile) || !reader.SelectVideoTrack(0)) { std::cout << "[FAIL] Could not prepare file for pipeline test" << std::endl; return false; } auto decoder = VideoDecoderFactory::CreateDecoder(VideoDecoderFactory::DecoderType::SOFTWARE); if (!decoder || !decoder->Initialize()) { std::cout << "[FAIL] Could not initialize decoder for pipeline test" << std::endl; return false; } // Process 30 frames for performance measurement int processedFrames = 0; int maxFrames = 30; for (int i = 0; i < maxFrames; i++) { VideoPacket packet; if (!reader.ReadNextPacket(packet)) break; VideoFrame frame; if (decoder->DecodeFrame(packet, frame)) { processedFrames++; } } auto endTime = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast(endTime - startTime); if (processedFrames > 0) { double fps = (double)processedFrames * 1000.0 / duration.count(); std::cout << "[INFO] Processed " << processedFrames << " frames in " << duration.count() << "ms" << std::endl; std::cout << "[INFO] Performance: " << fps << " fps" << std::endl; } std::cout << "[PASS] Full Pipeline working correctly" << std::endl; return true; } catch (const std::exception& e) { std::cout << "[FAIL] Full Pipeline exception: " << e.what() << std::endl; return false; } } }; // Headless-only main function int main(int argc, char* argv[]) { // Setup console SetConsoleCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8); if (argc < 2) { std::cout << "Usage: Vav2PlayerHeadless.exe " << std::endl; std::cout << "Example: Vav2PlayerHeadless.exe test_video.webm" << std::endl; return 1; } std::string videoFile = argv[1]; std::cout << "Testing with video file: " << videoFile << std::endl << std::endl; HeadlessTestRunner runner; bool success = runner.RunBasicTests(videoFile); std::cout << std::endl << "=== Test Summary ===" << std::endl; if (success) { std::cout << "All tests PASSED ✓" << std::endl; std::cout << "Press Enter to exit..."; std::cin.get(); return 0; } else { std::cout << "Some tests FAILED ✗" << std::endl; std::cout << "Press Enter to exit..."; std::cin.get(); return 1; } }