Files
video-v1/vav2/platforms/windows/tests/headless/src/SimpleHeadlessMain.cpp

222 lines
10 KiB
C++
Raw Normal View History

#include "pch.h"
2025-09-23 04:54:39 +09:00
#include "../src/Common/VideoTypes.h"
2025-09-22 22:01:53 +09:00
#include "../src/Decoder/VideoDecoderFactory.h"
#include "../src/FileIO/WebMFileReader.h"
#include <chrono>
#include <vector>
#include <iomanip>
2025-09-23 04:54:39 +09:00
using namespace Vav2Player;
int main(int argc, char* argv[])
{
SetConsoleCP(CP_UTF8);
SetConsoleOutputCP(CP_UTF8);
2025-09-22 22:01:53 +09:00
std::cout << "=== MAJOR_REFACTORING_GUIDE Phase 3: Basic Video Test ===" << std::endl;
if (argc < 2) {
2025-09-22 22:01:53 +09:00
std::cout << "Usage: " << argv[0] << " <video_file.webm>" << std::endl;
return 1;
}
2025-09-22 22:01:53 +09:00
std::string filePath = argv[1];
std::cout << "Testing video file: " << filePath << std::endl;
try {
// Test WebMFileReader
2025-09-23 04:54:39 +09:00
auto fileReader = std::make_unique<Vav2Player::WebMFileReader>();
2025-09-22 22:01:53 +09:00
if (!fileReader->OpenFile(filePath)) {
std::cout << "Failed to open video file" << std::endl;
return 1;
}
2025-09-22 22:01:53 +09:00
auto tracks = fileReader->GetVideoTracks();
if (tracks.empty()) {
std::cout << "No video tracks found" << std::endl;
return 1;
}
2025-09-22 22:01:53 +09:00
std::cout << "Found " << tracks.size() << " video track(s)" << std::endl;
2025-09-22 22:01:53 +09:00
// Select first track
if (!fileReader->SelectVideoTrack(tracks[0].track_number)) {
std::cout << "Failed to select video track" << std::endl;
return 1;
}
2025-09-22 02:15:47 +09:00
2025-09-22 22:01:53 +09:00
auto metadata = fileReader->GetVideoMetadata();
std::cout << "Video: " << metadata.width << "x" << metadata.height
<< " @ " << metadata.frame_rate << " fps" << std::endl;
2025-09-23 05:52:19 +09:00
std::cout << "Codec: " << (metadata.codec_type == VideoCodecType::AV1 ? "AV1" :
metadata.codec_type == VideoCodecType::VP9 ? "VP9" : "Other") << std::endl;
2025-09-22 02:15:47 +09:00
2025-09-24 03:33:54 +09:00
// 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 {
2025-09-24 03:33:54 +09:00
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;
}
2025-09-24 03:33:54 +09:00
// Use the decoder that works (prefer AUTO for adaptive quality control)
std::unique_ptr<IVideoDecoder> decoder;
2025-09-24 03:33:54 +09:00
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;
}
2025-09-22 22:01:53 +09:00
if (!decoder) {
2025-09-24 03:33:54 +09:00
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;
2025-09-22 02:15:47 +09:00
return 1;
}
2025-09-24 03:33:54 +09:00
// Note: Decoder is already initialized in the selection logic above
std::cout << "Selected decoder is ready for use" << std::endl;
2025-09-22 02:15:47 +09:00
// 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<double> frameDecodeTimes;
std::vector<double> packetReadTimes;
for (int i = 0; i < maxFrames; i++) {
// Measure packet reading time
auto packetReadStart = std::chrono::high_resolution_clock::now();
2025-09-23 04:54:39 +09:00
Vav2Player::VideoPacket packet;
2025-09-22 22:01:53 +09:00
if (!fileReader->ReadNextPacket(packet)) {
std::cout << "End of file at packet " << i << std::endl;
2025-09-22 22:01:53 +09:00
break;
}
2025-09-22 02:15:47 +09:00
auto packetReadEnd = std::chrono::high_resolution_clock::now();
double packetReadTime = std::chrono::duration<double, std::milli>(packetReadEnd - packetReadStart).count();
packetReadTimes.push_back(packetReadTime);
totalPacketReadTime += packetReadTime;
packetsRead++;
// Measure frame decoding time
auto decodeStart = std::chrono::high_resolution_clock::now();
2025-09-23 04:54:39 +09:00
Vav2Player::VideoFrame frame;
2025-09-22 22:01:53 +09:00
if (decoder->DecodeFrame(packet, frame)) {
auto decodeEnd = std::chrono::high_resolution_clock::now();
double decodeTime = std::chrono::duration<double, std::milli>(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;
2025-09-22 22:01:53 +09:00
} else {
std::cout << "Frame " << i << ": decode failed" << std::endl;
}
2025-09-22 02:15:47 +09:00
}
auto testEndTime = std::chrono::high_resolution_clock::now();
double totalTestTime = std::chrono::duration<double, std::milli>(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;
}
2025-09-22 22:01:53 +09:00
std::cout << "=== MAJOR_REFACTORING_GUIDE Phase 3: Test completed successfully ===" << std::endl;
std::cout << "Basic video decoding pipeline verified!" << std::endl;
return 0;
2025-09-22 22:01:53 +09:00
} catch (const std::exception& e) {
std::cout << "Exception: " << e.what() << std::endl;
return 1;
} catch (...) {
std::cout << "Unknown exception occurred" << std::endl;
return 1;
}
}