#include #include #include #include #include #include #include "D3D12Manager.h" using namespace std::chrono; struct FrameTask { int frame_index; ID3D12Resource* texture; VavCoreVideoFrame frame; VavCoreResult result; uint8_t* cpu_buffer; }; int main(int argc, char* argv[]) { printf("[LargeResolutionTest] Starting test...\n"); // Parse command line arguments if (argc < 2) { printf("[ERROR] Usage: LargeResolutionTest.exe \n"); printf("[INFO] Test videos:\n"); printf(" - D:/Project/video-av1/sample/test_2160p_av1.webm\n"); printf(" - D:/Project/video-av1/sample/test_1080p_stripe.webm\n"); return 1; } const char* video_path = argv[1]; printf("[LargeResolutionTest] Video: %s\n", video_path); // Step 1: Initialize VavCore printf("\n[Step 1] Initializing VavCore...\n"); VavCoreResult result = vavcore_initialize(); if (result != VAVCORE_SUCCESS) { printf("[ERROR] Failed to initialize VavCore: error code %d\n", result); return 1; } printf("[OK] VavCore initialized successfully\n"); // Step 2: Create D3D12 device (headless) printf("\n[Step 2] Creating D3D12 device...\n"); D3D12Manager d3d12; if (!d3d12.Initialize()) { printf("[ERROR] Failed to create D3D12 device\n"); vavcore_cleanup(); return 1; } printf("[OK] D3D12 device created\n"); // Step 3: Create VavCore player printf("\n[Step 3] Creating VavCore player...\n"); VavCorePlayer* player = vavcore_create_player(); if (!player) { printf("[ERROR] Failed to create VavCore player\n"); d3d12.Cleanup(); vavcore_cleanup(); return 1; } printf("[OK] VavCore player created\n"); // Step 4: Set decoder type to NVDEC explicitly printf("\n[Step 4] Setting decoder type to NVDEC...\n"); result = vavcore_set_decoder_type(player, VAVCORE_DECODER_NVDEC); if (result != VAVCORE_SUCCESS) { printf("[ERROR] Failed to set decoder type: error code %d\n", result); vavcore_destroy_player(player); d3d12.Cleanup(); vavcore_cleanup(); return 1; } printf("[OK] Decoder type set to NVDEC\n"); // Step 5: Set D3D12 device for zero-copy printf("\n[Step 5] Setting D3D12 device for VavCore...\n"); result = vavcore_set_d3d_device(player, d3d12.GetDevice(), VAVCORE_SURFACE_D3D12_RESOURCE); if (result != VAVCORE_SUCCESS) { printf("[ERROR] Failed to set D3D12 device: error code %d\n", result); vavcore_destroy_player(player); d3d12.Cleanup(); vavcore_cleanup(); return 1; } printf("[OK] D3D12 device set for VavCore\n"); // Step 6: Open video file printf("\n[Step 6] Opening video file...\n"); result = vavcore_open_file(player, video_path); if (result != VAVCORE_SUCCESS) { printf("[ERROR] Failed to open video file: error code %d\n", result); vavcore_destroy_player(player); d3d12.Cleanup(); vavcore_cleanup(); return 1; } // Get video metadata VavCoreVideoMetadata metadata = {}; result = vavcore_get_metadata(player, &metadata); if (result != VAVCORE_SUCCESS) { printf("[ERROR] Failed to get video metadata: error code %d\n", result); vavcore_close_file(player); vavcore_destroy_player(player); d3d12.Cleanup(); vavcore_cleanup(); return 1; } printf("[OK] Video opened: %dx%d, %.2f fps, %llu frames\n", metadata.width, metadata.height, metadata.frame_rate, (unsigned long long)metadata.total_frames); printf("[LargeResolutionTest] Decoder: NVDEC (explicit)\n"); printf("[LargeResolutionTest] Surface: D3D12\n"); // Step 7: Continuous frame decoding (limited to ~10 seconds) const int MAX_FRAMES = 300; // ~10 seconds at 30fps printf("\n[Step 7] Decoding video (limited to %d frames for testing)...\n\n", MAX_FRAMES); printf("[INFO] NVDEC pipeline priming: Calling decode continuously\n"); printf("[INFO] First 2 frames will be skipped for priming\n"); printf("[INFO] Total frames in video: %llu\n\n", (unsigned long long)metadata.total_frames); int decode_errors = 0; int successful_decodes = 0; int frame_index = 0; // Performance measurement auto start_time = high_resolution_clock::now(); auto last_report_time = start_time; int frames_since_last_report = 0; // Continuous decode loop - decode limited frames while (!vavcore_is_end_of_file(player) && frame_index < MAX_FRAMES) { // Create NV12 texture ID3D12Resource* texture = d3d12.CreateNV12Texture(metadata.width, metadata.height); if (!texture) { printf("[ERROR] Failed to create texture for frame %d\n", frame_index); decode_errors++; frame_index++; continue; } // Decode frame to D3D12 surface VavCoreVideoFrame frame; VavCoreResult result = vavcore_decode_to_surface( player, VAVCORE_SURFACE_D3D12_RESOURCE, texture, &frame ); if (result != VAVCORE_SUCCESS) { printf("Frame %3d: Decode failed (error code %d)\n", frame_index, result); texture->Release(); decode_errors++; frame_index++; continue; } // Skip first 2 frames (priming) if (frame_index < 2) { printf("Frame %3d: PRIMING (decoded but skipped)\n", frame_index); } else { successful_decodes++; frames_since_last_report++; // Print performance report every 30 frames if (frame_index % 30 == 0) { auto current_time = high_resolution_clock::now(); auto elapsed_ms = duration_cast(current_time - last_report_time).count(); double fps = (frames_since_last_report * 1000.0) / elapsed_ms; printf("Frame %3d: Decoded successfully (progress: %d/%llu, FPS: %.1f)\n", frame_index, frame_index, (unsigned long long)metadata.total_frames, fps); last_report_time = current_time; frames_since_last_report = 0; } } // Cleanup texture immediately to prevent memory buildup texture->Release(); frame_index++; } // Calculate overall performance auto end_time = high_resolution_clock::now(); auto total_ms = duration_cast(end_time - start_time).count(); double overall_fps = (successful_decodes * 1000.0) / total_ms; double decode_time_per_frame = (double)total_ms / successful_decodes; // Step 8: Print results printf("\n[LargeResolutionTest] Results:\n"); printf(" Resolution: %dx%d\n", metadata.width, metadata.height); printf(" Total frames in video: %llu\n", (unsigned long long)metadata.total_frames); printf(" Total frames decoded: %d\n", frame_index); printf(" Priming frames: 2\n"); printf(" Successful decodes (after priming): %d\n", successful_decodes); printf(" Decode errors: %d\n", decode_errors); printf("\n[LargeResolutionTest] Performance:\n"); printf(" Total time: %.2f seconds\n", total_ms / 1000.0); printf(" Average FPS: %.1f fps\n", overall_fps); printf(" Average decode time per frame: %.2f ms\n", decode_time_per_frame); printf(" Target FPS (30fps): %s\n", overall_fps >= 30.0 ? "PASS" : "FAIL"); bool test_passed = (decode_errors == 0 && successful_decodes == (frame_index - 2) && overall_fps >= 30.0); if (test_passed) { printf("\n[LargeResolutionTest] Test SUCCESS - All frames decoded successfully\n"); } else { printf("\n[LargeResolutionTest] Test FAILED - Some frames failed to decode\n"); } // Cleanup vavcore_close_file(player); vavcore_destroy_player(player); d3d12.Cleanup(); vavcore_cleanup(); return test_passed ? 0 : 1; }