2025-09-22 02:15:47 +09:00
|
|
|
#include "pch.h"
|
2025-09-23 04:54:39 +09:00
|
|
|
#include "../src/Common/VideoTypes.h"
|
2025-09-22 02:15:47 +09:00
|
|
|
#include "../src/FileIO/WebMFileReader.h"
|
2025-09-23 04:54:39 +09:00
|
|
|
#include "../src/Decoder/AV1Decoder.h"
|
|
|
|
|
#include "SimpleGPURenderer_Headless.h"
|
|
|
|
|
|
|
|
|
|
using namespace Vav2Player;
|
2025-09-22 02:15:47 +09:00
|
|
|
|
|
|
|
|
// AV1 + GPU Integration Test
|
|
|
|
|
// Tests real AV1 video decoding with GPU YUV-to-RGB conversion
|
|
|
|
|
int TestAV1GPUIntegration(const std::string& videoFile)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "\n=== AV1 + GPU Integration Test ===" << std::endl;
|
|
|
|
|
std::cout << "Testing: " << videoFile << std::endl;
|
|
|
|
|
|
|
|
|
|
// 1. Initialize WebM file reader
|
2025-09-23 04:54:39 +09:00
|
|
|
auto fileReader = std::make_unique<WebMFileReader>();
|
2025-09-22 02:15:47 +09:00
|
|
|
|
|
|
|
|
if (!fileReader->OpenFile(videoFile))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[FAIL] Could not open video file" << std::endl;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get video tracks and select the first AV1 track
|
|
|
|
|
auto tracks = fileReader->GetVideoTracks();
|
|
|
|
|
if (tracks.empty())
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[FAIL] No video tracks found" << std::endl;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto& track = tracks[0];
|
|
|
|
|
std::cout << "[INFO] Video track: " << track.width << "x" << track.height
|
|
|
|
|
<< " @ " << track.frame_rate << "fps, Codec: " << static_cast<int>(track.codec_type) << std::endl;
|
|
|
|
|
|
|
|
|
|
if (track.codec_type != Vav2Player::VideoCodecType::AV1)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[FAIL] Not an AV1 video track" << std::endl;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fileReader->SelectVideoTrack(0);
|
|
|
|
|
|
|
|
|
|
// 2. Create headless AV1 decoder
|
2025-09-23 04:54:39 +09:00
|
|
|
auto decoder = std::make_unique<AV1Decoder>();
|
2025-09-22 02:15:47 +09:00
|
|
|
|
|
|
|
|
if (!decoder)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[FAIL] Could not create AV1 decoder" << std::endl;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-23 04:54:39 +09:00
|
|
|
VideoMetadata metadata;
|
2025-09-22 02:15:47 +09:00
|
|
|
metadata.width = track.width;
|
|
|
|
|
metadata.height = track.height;
|
|
|
|
|
metadata.frame_rate = track.frame_rate;
|
|
|
|
|
metadata.codec_type = track.codec_type;
|
|
|
|
|
|
|
|
|
|
if (!decoder->Initialize(metadata))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[FAIL] Could not initialize AV1 decoder" << std::endl;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cout << "[PASS] AV1 decoder initialized successfully" << std::endl;
|
|
|
|
|
|
|
|
|
|
// 3. Initialize GPU renderer
|
2025-09-23 04:54:39 +09:00
|
|
|
auto gpuRenderer = std::make_unique<SimpleGPURenderer_Headless>();
|
2025-09-22 02:15:47 +09:00
|
|
|
|
|
|
|
|
HRESULT hr = gpuRenderer->Initialize(track.width, track.height);
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[FAIL] Could not initialize GPU renderer: 0x" << std::hex << hr << std::endl;
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cout << "[PASS] GPU renderer initialized successfully" << std::endl;
|
|
|
|
|
|
|
|
|
|
// 4. Test actual video frame processing
|
|
|
|
|
int processedFrames = 0;
|
|
|
|
|
int maxFrames = 10; // Test first 10 frames
|
|
|
|
|
|
|
|
|
|
auto startTime = std::chrono::high_resolution_clock::now();
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < maxFrames; i++)
|
|
|
|
|
{
|
|
|
|
|
// Read packet from file
|
2025-09-23 04:54:39 +09:00
|
|
|
VideoPacket packet;
|
2025-09-22 02:15:47 +09:00
|
|
|
if (!fileReader->ReadNextPacket(packet))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[INFO] End of file reached at frame " << i << std::endl;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Decode AV1 packet to YUV frame
|
2025-09-23 04:54:39 +09:00
|
|
|
VideoFrame frame;
|
2025-09-22 02:15:47 +09:00
|
|
|
if (!decoder->DecodeFrame(packet, frame))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[WARN] Failed to decode frame " << i << std::endl;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!frame.is_valid)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[WARN] Invalid frame " << i << std::endl;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Test GPU rendering (currently only validates frame data)
|
|
|
|
|
hr = gpuRenderer->RenderVideoFrame(frame);
|
|
|
|
|
if (FAILED(hr))
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[WARN] GPU rendering failed for frame " << i << ": 0x" << std::hex << hr << std::endl;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
processedFrames++;
|
|
|
|
|
|
|
|
|
|
if (i % 5 == 0)
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[INFO] Processed frame " << i << " (" << frame.width << "x" << frame.height
|
|
|
|
|
<< ", Format: " << static_cast<int>(frame.color_space) << ")" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto endTime = std::chrono::high_resolution_clock::now();
|
|
|
|
|
auto duration = std::chrono::duration<double, std::milli>(endTime - startTime);
|
|
|
|
|
|
|
|
|
|
// 5. Performance analysis
|
|
|
|
|
std::cout << "\n=== Performance Results ===" << std::endl;
|
|
|
|
|
std::cout << "Processed frames: " << processedFrames << "/" << maxFrames << std::endl;
|
|
|
|
|
std::cout << "Total time: " << duration.count() << " ms" << std::endl;
|
|
|
|
|
|
|
|
|
|
if (processedFrames > 0)
|
|
|
|
|
{
|
|
|
|
|
double avgTimePerFrame = duration.count() / processedFrames;
|
|
|
|
|
double fps = 1000.0 / avgTimePerFrame;
|
|
|
|
|
|
|
|
|
|
std::cout << "Average time per frame: " << avgTimePerFrame << " ms" << std::endl;
|
|
|
|
|
std::cout << "Effective FPS: " << fps << std::endl;
|
|
|
|
|
|
|
|
|
|
// Compare with target performance
|
|
|
|
|
double targetFPS = track.frame_rate;
|
|
|
|
|
if (fps >= targetFPS * 0.8) // 80% of target FPS
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[PASS] Performance meets target (" << targetFPS << " fps)" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
std::cout << "[WARN] Performance below target (" << targetFPS << " fps)" << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::cout << "[SUCCESS] AV1 + GPU integration test completed!" << std::endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|