#include "pch.h" #include "../src/Common/VideoTypes.h" #include "../src/Decoder/VideoDecoderFactory.h" #include "../src/FileIO/WebMFileReader.h" #include #include #include using namespace Vav2Player; int main(int argc, char* argv[]) { SetConsoleCP(CP_UTF8); SetConsoleOutputCP(CP_UTF8); std::cout << "=== MAJOR_REFACTORING_GUIDE Phase 3: Basic Video Test ===" << std::endl; if (argc < 2) { std::cout << "Usage: " << argv[0] << " " << std::endl; return 1; } std::string filePath = argv[1]; std::cout << "Testing video file: " << filePath << std::endl; try { // Test WebMFileReader auto fileReader = std::make_unique(); if (!fileReader->OpenFile(filePath)) { std::cout << "Failed to open video file" << std::endl; return 1; } auto tracks = fileReader->GetVideoTracks(); if (tracks.empty()) { std::cout << "No video tracks found" << std::endl; return 1; } std::cout << "Found " << tracks.size() << " video track(s)" << std::endl; // Select first track if (!fileReader->SelectVideoTrack(tracks[0].track_number)) { std::cout << "Failed to select video track" << std::endl; return 1; } auto metadata = fileReader->GetVideoMetadata(); std::cout << "Video: " << metadata.width << "x" << metadata.height << " @ " << metadata.frame_rate << " fps" << std::endl; std::cout << "Codec: " << (metadata.codec_type == VideoCodecType::AV1 ? "AV1" : metadata.codec_type == VideoCodecType::VP9 ? "VP9" : "Other") << std::endl; // Test decoder creation - Try AdaptiveNVDEC first (AUTO mode), then fallback others std::cout << std::endl; std::cout << "=== TESTING ADAPTIVE NVDEC DECODER (AUTO MODE) ===" << std::endl; auto autoDecoder = Vav2Player::VideoDecoderFactory::CreateDecoder(metadata.codec_type, Vav2Player::VideoDecoderFactory::DecoderType::AUTO); bool useAuto = false; if (autoDecoder && autoDecoder->Initialize(metadata)) { std::cout << "[SUCCESS] AUTO decoder (AdaptiveNVDEC/fallback) initialized successfully" << std::endl; std::cout << "Decoder type: " << autoDecoder->GetCodecName() << std::endl; useAuto = true; } else { std::cout << "[FAILED] AUTO decoder failed" << std::endl; } std::cout << std::endl; std::cout << "=== TESTING MEDIA FOUNDATION DECODER ===" << std::endl; auto mfDecoder = Vav2Player::VideoDecoderFactory::CreateDecoder(metadata.codec_type, Vav2Player::VideoDecoderFactory::DecoderType::MEDIA_FOUNDATION); bool useMF = false; if (mfDecoder && mfDecoder->Initialize(metadata)) { std::cout << "[SUCCESS] MediaFoundation decoder initialized successfully" << std::endl; useMF = true; } else { std::cout << "[FAILED] MediaFoundation decoder failed" << std::endl; } std::cout << std::endl; std::cout << "=== TESTING DAV1D DECODER ===" << std::endl; auto dav1dDecoder = Vav2Player::VideoDecoderFactory::CreateDecoder(metadata.codec_type, Vav2Player::VideoDecoderFactory::DecoderType::DAV1D); bool useDav1d = false; if (dav1dDecoder && dav1dDecoder->Initialize(metadata)) { std::cout << "[SUCCESS] dav1d decoder initialized successfully" << std::endl; useDav1d = true; } else { std::cout << "[FAILED] dav1d decoder failed" << std::endl; } // Use the decoder that works (prefer AUTO for adaptive quality control) std::unique_ptr decoder; if (useAuto) { std::cout << std::endl << "=== USING AUTO DECODER (AdaptiveNVDEC/fallback) ===" << std::endl; decoder = std::move(autoDecoder); } else if (useMF) { std::cout << std::endl << "=== USING MEDIA FOUNDATION DECODER ===" << std::endl; decoder = std::move(mfDecoder); } else if (useDav1d) { std::cout << std::endl << "=== USING DAV1D DECODER ===" << std::endl; decoder = std::move(dav1dDecoder); } else { std::cout << "No working decoder found" << std::endl; return 1; } if (!decoder) { std::string codecName = (metadata.codec_type == VideoCodecType::AV1 ? "AV1" : (metadata.codec_type == VideoCodecType::VP9 ? "VP9" : "Other")); std::cout << "Failed to create " << codecName << " decoder" << std::endl; return 1; } // Note: Decoder is already initialized in the selection logic above std::cout << "Selected decoder is ready for use" << std::endl; // Performance test - measure decoding performance for 4K video std::cout << "=== PERFORMANCE TEST: 4K Video Decoding ===" << std::endl; std::cout << "Target: 30fps (33.33ms per frame)" << std::endl; std::cout << std::endl; int packetsRead = 0; int framesDecoded = 0; int maxFrames = 30; // Test 30 frames (1 second at 30fps) auto testStartTime = std::chrono::high_resolution_clock::now(); double totalDecodeTime = 0.0; double totalPacketReadTime = 0.0; std::vector frameDecodeTimes; std::vector packetReadTimes; for (int i = 0; i < maxFrames; i++) { // Measure packet reading time auto packetReadStart = std::chrono::high_resolution_clock::now(); Vav2Player::VideoPacket packet; if (!fileReader->ReadNextPacket(packet)) { std::cout << "End of file at packet " << i << std::endl; break; } auto packetReadEnd = std::chrono::high_resolution_clock::now(); double packetReadTime = std::chrono::duration(packetReadEnd - packetReadStart).count(); packetReadTimes.push_back(packetReadTime); totalPacketReadTime += packetReadTime; packetsRead++; // Measure frame decoding time auto decodeStart = std::chrono::high_resolution_clock::now(); Vav2Player::VideoFrame frame; if (decoder->DecodeFrame(packet, frame)) { auto decodeEnd = std::chrono::high_resolution_clock::now(); double decodeTime = std::chrono::duration(decodeEnd - decodeStart).count(); frameDecodeTimes.push_back(decodeTime); totalDecodeTime += decodeTime; framesDecoded++; std::cout << "Frame " << framesDecoded << ": " << "read=" << std::fixed << std::setprecision(2) << packetReadTime << "ms, " << "decode=" << decodeTime << "ms, " << "total=" << (packetReadTime + decodeTime) << "ms" << std::endl; } else { std::cout << "Frame " << i << ": decode failed" << std::endl; } } auto testEndTime = std::chrono::high_resolution_clock::now(); double totalTestTime = std::chrono::duration(testEndTime - testStartTime).count(); std::cout << std::endl; std::cout << "=== PERFORMANCE RESULTS ===" << std::endl; std::cout << "Frames decoded: " << framesDecoded << " / " << packetsRead << " packets" << std::endl; std::cout << "Total test time: " << std::fixed << std::setprecision(2) << totalTestTime << "ms" << std::endl; if (framesDecoded > 0) { double avgDecodeTime = totalDecodeTime / framesDecoded; double avgPacketReadTime = totalPacketReadTime / packetsRead; double avgTotalTime = avgDecodeTime + avgPacketReadTime; double achievableFPS = 1000.0 / avgTotalTime; std::cout << std::endl; std::cout << "Average packet read time: " << avgPacketReadTime << "ms" << std::endl; std::cout << "Average decode time: " << avgDecodeTime << "ms" << std::endl; std::cout << "Average total time per frame: " << avgTotalTime << "ms" << std::endl; std::cout << "Achievable FPS: " << std::fixed << std::setprecision(1) << achievableFPS << " fps" << std::endl; std::cout << std::endl; if (achievableFPS >= 30.0) { std::cout << "[SUCCESS] Can achieve 30fps target!" << std::endl; } else { std::cout << "[WARNING] Cannot achieve 30fps target (current: " << achievableFPS << " fps)" << std::endl; // Identify bottleneck if (avgDecodeTime > avgPacketReadTime * 2) { std::cout << "[BOTTLENECK] Decoding is the main bottleneck (" << avgDecodeTime << "ms)" << std::endl; } else if (avgPacketReadTime > avgDecodeTime * 2) { std::cout << "[BOTTLENECK] Packet reading is the main bottleneck (" << avgPacketReadTime << "ms)" << std::endl; } else { std::cout << "[BOTTLENECK] Both decoding and I/O contribute to slowdown" << std::endl; } } std::cout << std::endl; std::cout << "Target frame time (30fps): 33.33ms" << std::endl; std::cout << "Current frame time: " << avgTotalTime << "ms" << std::endl; std::cout << "Performance gap: " << std::fixed << std::setprecision(1) << (avgTotalTime - 33.33) << "ms too slow" << std::endl; } else { std::cout << "[ERROR] No frames decoded successfully" << std::endl; } std::cout << "=== MAJOR_REFACTORING_GUIDE Phase 3: Test completed successfully ===" << std::endl; std::cout << "Basic video decoding pipeline verified!" << std::endl; return 0; } catch (const std::exception& e) { std::cout << "Exception: " << e.what() << std::endl; return 1; } catch (...) { std::cout << "Unknown exception occurred" << std::endl; return 1; } }