diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/Vav2Player.vcxproj.filters b/vav2/platforms/windows/applications/vav2player/Vav2Player/Vav2Player.vcxproj.filters
index e50056f..362f95a 100644
--- a/vav2/platforms/windows/applications/vav2player/Vav2Player/Vav2Player.vcxproj.filters
+++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/Vav2Player.vcxproj.filters
@@ -6,7 +6,11 @@
-
+
+
+
+
+
@@ -14,12 +18,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/vav2/platforms/windows/vavcore/VavCore.vcxproj b/vav2/platforms/windows/vavcore/VavCore.vcxproj
index c15272d..ff3d742 100644
--- a/vav2/platforms/windows/vavcore/VavCore.vcxproj
+++ b/vav2/platforms/windows/vavcore/VavCore.vcxproj
@@ -45,8 +45,6 @@
true
- $(ProjectDir)lib\
- $(ProjectDir)obj\$(Configuration)\
VavCore-debug
@@ -77,6 +75,11 @@
webm-debug.lib;dav1d-debug.lib;amf-debug.lib;vpld.lib;mfplat.lib;mf.lib;mfuuid.lib;nvcuvid.lib;cuda.lib;d3d11.lib;%(AdditionalDependencies)
$(ProjectDir)..\..\..\..\lib\libwebm;$(ProjectDir)..\..\..\..\lib\dav1d;$(ProjectDir)..\..\..\..\lib\amf;$(ProjectDir)..\..\..\..\lib\libvpl;$(ProjectDir)..\..\..\..\oss\nvidia-video-codec\Lib\x64;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.0\lib\x64;%(AdditionalLibraryDirectories)
+
+ echo Copying VavCore Debug DLL...
+copy "$(TargetPath)" "$(ProjectDir)lib\$(TargetFileName)"
+echo DLL copy completed.
+
@@ -90,6 +93,7 @@
pch.h
$(ProjectDir)include;$(ProjectDir)..\..\..\..\include\libwebm;$(ProjectDir)..\..\..\..\include\dav1d;$(ProjectDir)..\..\..\..\include\amf;$(ProjectDir)..\..\..\..\include\libvpl;$(ProjectDir)..\..\..\..\oss\nvidia-video-codec\Interface;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.0\include;%(AdditionalIncludeDirectories)
stdcpp20
+ true
@@ -99,6 +103,7 @@
true
webm.lib;dav1d.lib;amf.lib;vpl.lib;mfplat.lib;mf.lib;mfuuid.lib;nvcuvid.lib;cuda.lib;d3d11.lib;%(AdditionalDependencies)
$(ProjectDir)..\..\..\..\lib\libwebm;$(ProjectDir)..\..\..\..\lib\dav1d;$(ProjectDir)..\..\..\..\lib\amf;$(ProjectDir)..\..\..\..\lib\libvpl;$(ProjectDir)..\..\..\..\oss\nvidia-video-codec\Lib\x64;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v13.0\lib\x64;%(AdditionalLibraryDirectories)
+ /OPT:REF /OPT:ICF=5 /OPT:LBR %(AdditionalOptions)
webm.lib;dav1d.lib;amf.lib;vpl.lib;mfplat.lib;mf.lib;mfuuid.lib;nvcuvid.lib;cuda.lib;d3d11.lib;%(AdditionalDependencies)
@@ -109,8 +114,8 @@
echo "Copying VavCore DLL to Godot extension directory..."
if not exist "$(ProjectDir)..\godot-plugin\libs\windows-x86_64\" mkdir "$(ProjectDir)..\godot-plugin\libs\windows-x86_64\"
copy "$(TargetPath)" "$(ProjectDir)..\godot-plugin\libs\windows-x86_64\"
- echo "VavCore DLL copied successfully"
-
+ copy "$(TargetPath)" "$(ProjectDir)lib\$(TargetFileName)"
+ echo "VavCore DLL copied successfully"
Installing VavCore DLL to Godot extension
@@ -137,6 +142,7 @@
Create
+
diff --git a/vav2/platforms/windows/vavcore/src/Decoder/AMFAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/AMFAV1Decoder.cpp
index 5dc368c..898e8a5 100644
--- a/vav2/platforms/windows/vavcore/src/Decoder/AMFAV1Decoder.cpp
+++ b/vav2/platforms/windows/vavcore/src/Decoder/AMFAV1Decoder.cpp
@@ -1,4 +1,4 @@
-#include "pch.h"
+#include "pch.h"
#include
// MUST follow header include order to avoid build error
@@ -869,14 +869,5 @@ void RegisterAMFDecoders() {
});
}
-// Static initialization for registration
-namespace {
- struct AMFDecoderRegistration {
- AMFDecoderRegistration() {
- RegisterAMFDecoders();
- }
- };
- static AMFDecoderRegistration s_amfRegistration;
-}
} // namespace VavCore
\ No newline at end of file
diff --git a/vav2/platforms/windows/vavcore/src/Decoder/AV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/AV1Decoder.cpp
index 28f4123..32d39f3 100644
--- a/vav2/platforms/windows/vavcore/src/Decoder/AV1Decoder.cpp
+++ b/vav2/platforms/windows/vavcore/src/Decoder/AV1Decoder.cpp
@@ -293,7 +293,5 @@ void RegisterAV1Decoders() {
});
}
-// Static initialization for auto-registration
-static bool s_av1_registered = (RegisterAV1Decoders(), true);
} // namespace VavCore
\ No newline at end of file
diff --git a/vav2/platforms/windows/vavcore/src/Decoder/AndroidMediaCodecAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/AndroidMediaCodecAV1Decoder.cpp
index 4be9c88..1e117c1 100644
--- a/vav2/platforms/windows/vavcore/src/Decoder/AndroidMediaCodecAV1Decoder.cpp
+++ b/vav2/platforms/windows/vavcore/src/Decoder/AndroidMediaCodecAV1Decoder.cpp
@@ -952,8 +952,6 @@ void RegisterAndroidMediaCodecDecoders() {
});
}
-// Static initialization for auto-registration (Android only)
-static bool s_mediacodec_registered = (RegisterAndroidMediaCodecDecoders(), true);
} // namespace VavCore
diff --git a/vav2/platforms/windows/vavcore/src/Decoder/MediaFoundationAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/MediaFoundationAV1Decoder.cpp
index 6209922..0d1cdae 100644
--- a/vav2/platforms/windows/vavcore/src/Decoder/MediaFoundationAV1Decoder.cpp
+++ b/vav2/platforms/windows/vavcore/src/Decoder/MediaFoundationAV1Decoder.cpp
@@ -1,4 +1,4 @@
-#include "pch.h"
+#include "pch.h"
#include "MediaFoundationAV1Decoder.h"
#include
#include
diff --git a/vav2/platforms/windows/vavcore/src/Decoder/NVDECAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/NVDECAV1Decoder.cpp
index fef4551..9d17915 100644
--- a/vav2/platforms/windows/vavcore/src/Decoder/NVDECAV1Decoder.cpp
+++ b/vav2/platforms/windows/vavcore/src/Decoder/NVDECAV1Decoder.cpp
@@ -689,7 +689,5 @@ void RegisterNVDECDecoders() {
});
}
-// Static initialization for auto-registration
-static bool s_nvdec_registered = (RegisterNVDECDecoders(), true);
} // namespace VavCore
\ No newline at end of file
diff --git a/vav2/platforms/windows/vavcore/src/Decoder/VPLAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/VPLAV1Decoder.cpp
index 74a6916..f663ad5 100644
--- a/vav2/platforms/windows/vavcore/src/Decoder/VPLAV1Decoder.cpp
+++ b/vav2/platforms/windows/vavcore/src/Decoder/VPLAV1Decoder.cpp
@@ -1,4 +1,4 @@
-#include "pch.h"
+#include "pch.h"
#include "VPLAV1Decoder.h"
#include "VideoDecoderFactory.h"
#include
@@ -1019,7 +1019,5 @@ void RegisterVPLDecoders() {
});
}
-// Static initialization for auto-registration
-static bool s_vpl_registered = (RegisterVPLDecoders(), true);
} // namespace VavCore
\ No newline at end of file
diff --git a/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.cpp b/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.cpp
index 3c4b7d6..700fe54 100644
--- a/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.cpp
+++ b/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.cpp
@@ -5,9 +5,6 @@
namespace VavCore {
-// Static member initialization
-std::vector VideoDecoderFactory::s_av1_decoders;
-std::vector VideoDecoderFactory::s_vp9_decoders;
std::unique_ptr VideoDecoderFactory::CreateDecoder(VideoCodecType codec_type, DecoderType decoder_type) {
auto& decoders = GetDecoderList(codec_type);
@@ -163,10 +160,11 @@ std::vector VideoDecoderFactory::GetAvailableDecoders(VideoCodecTyp
}
void VideoDecoderFactory::RegisterAV1Decoder(const DecoderRegistration& registration) {
- s_av1_decoders.push_back(registration);
+ auto& decoders = GetDecoderList(VideoCodecType::AV1);
+ decoders.push_back(registration);
// Sort by priority (lower numbers = higher priority)
- std::sort(s_av1_decoders.begin(), s_av1_decoders.end(), [](const auto& a, const auto& b) {
+ std::sort(decoders.begin(), decoders.end(), [](const auto& a, const auto& b) {
return a.priority < b.priority;
});
@@ -175,10 +173,11 @@ void VideoDecoderFactory::RegisterAV1Decoder(const DecoderRegistration& registra
}
void VideoDecoderFactory::RegisterVP9Decoder(const DecoderRegistration& registration) {
- s_vp9_decoders.push_back(registration);
+ auto& decoders = GetDecoderList(VideoCodecType::VP9);
+ decoders.push_back(registration);
// Sort by priority (lower numbers = higher priority)
- std::sort(s_vp9_decoders.begin(), s_vp9_decoders.end(), [](const auto& a, const auto& b) {
+ std::sort(decoders.begin(), decoders.end(), [](const auto& a, const auto& b) {
return a.priority < b.priority;
});
@@ -236,8 +235,8 @@ void VideoDecoderFactory::InitializeFactory() {
void VideoDecoderFactory::CleanupFactory() {
// Clear all registrations
- s_av1_decoders.clear();
- s_vp9_decoders.clear();
+ GetDecoderList(VideoCodecType::AV1).clear();
+ GetDecoderList(VideoCodecType::VP9).clear();
std::cout << "[VideoDecoderFactory] Factory cleanup completed" << std::endl;
}
@@ -252,13 +251,17 @@ VideoCodecType VideoDecoderFactory::DetectCodecTypeFromId(const std::string& cod
}
std::vector& VideoDecoderFactory::GetDecoderList(VideoCodecType codec_type) {
+ // Lazy initialization to avoid DLL loading issues
+ static std::vector s_av1_decoders_local;
+ static std::vector s_vp9_decoders_local;
+
switch (codec_type) {
case VideoCodecType::AV1:
- return s_av1_decoders;
+ return s_av1_decoders_local;
case VideoCodecType::VP9:
- return s_vp9_decoders;
+ return s_vp9_decoders_local;
default:
- return s_av1_decoders; // Default to AV1
+ return s_av1_decoders_local; // Default to AV1
}
}
diff --git a/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.h b/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.h
index 5476516..8b5b1f3 100644
--- a/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.h
+++ b/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.h
@@ -67,9 +67,6 @@ private:
VideoDecoderFactory(const VideoDecoderFactory&) = delete;
VideoDecoderFactory& operator=(const VideoDecoderFactory&) = delete;
- // Codec-specific registered decoder arrays
- static std::vector s_av1_decoders;
- static std::vector s_vp9_decoders;
// Helper functions
static std::vector& GetDecoderList(VideoCodecType codec_type);
diff --git a/vav2/platforms/windows/vavcore/src/DllMain.cpp b/vav2/platforms/windows/vavcore/src/DllMain.cpp
new file mode 100644
index 0000000..67b0db2
--- /dev/null
+++ b/vav2/platforms/windows/vavcore/src/DllMain.cpp
@@ -0,0 +1,120 @@
+#include "pch.h"
+#include
+#include
+
+// Forward declarations for decoder registration functions
+namespace VavCore {
+ extern void RegisterAV1Decoders();
+ extern void RegisterNVDECDecoders();
+ extern void RegisterVPLDecoders();
+ extern void RegisterAMFDecoders();
+}
+
+// Global state for DLL-level initialization
+static bool g_dll_initialized = false;
+static CRITICAL_SECTION g_dll_cs;
+
+// Safe initialization flag - only allow initialization once per process
+static bool g_safe_to_initialize = false;
+
+BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
+{
+ switch (ul_reason_for_call)
+ {
+ case DLL_PROCESS_ATTACH:
+ {
+ // Initialize critical section for thread safety
+ InitializeCriticalSection(&g_dll_cs);
+
+ // Mark that we're ready for safe initialization
+ g_safe_to_initialize = true;
+
+ std::cout << "[DllMain] VavCore.dll loaded - Process Attach" << std::endl;
+ std::cout << "[DllMain] Safe to initialize: Ready for vavcore_initialize() call" << std::endl;
+ }
+ break;
+
+ case DLL_THREAD_ATTACH:
+ // Thread-specific initialization if needed
+ break;
+
+ case DLL_THREAD_DETACH:
+ // Thread-specific cleanup if needed
+ break;
+
+ case DLL_PROCESS_DETACH:
+ {
+ EnterCriticalSection(&g_dll_cs);
+
+ if (g_dll_initialized) {
+ std::cout << "[DllMain] VavCore.dll unloading - cleaning up decoders" << std::endl;
+
+ // Cleanup all decoder registrations
+ // Note: We don't call VideoDecoderFactory::CleanupFactory() here
+ // because it might cause issues during DLL unload
+
+ g_dll_initialized = false;
+ }
+
+ g_safe_to_initialize = false;
+ LeaveCriticalSection(&g_dll_cs);
+ DeleteCriticalSection(&g_dll_cs);
+
+ std::cout << "[DllMain] VavCore.dll unloaded - Process Detach" << std::endl;
+ }
+ break;
+ }
+ return TRUE;
+}
+
+// Safe initialization function called from vavcore_initialize()
+extern "C" bool PerformSafeDllInitialization()
+{
+ EnterCriticalSection(&g_dll_cs);
+
+ bool result = false;
+
+ if (!g_safe_to_initialize) {
+ std::cout << "[DllMain] ERROR: DLL not ready for initialization" << std::endl;
+ LeaveCriticalSection(&g_dll_cs);
+ return false;
+ }
+
+ if (g_dll_initialized) {
+ std::cout << "[DllMain] Already initialized, skipping" << std::endl;
+ result = true;
+ }
+ else {
+ try {
+ std::cout << "[DllMain] Performing safe decoder registration..." << std::endl;
+
+ // Register all decoders in safe runtime environment
+ VavCore::RegisterAV1Decoders();
+ VavCore::RegisterNVDECDecoders();
+ VavCore::RegisterVPLDecoders();
+ VavCore::RegisterAMFDecoders();
+
+ g_dll_initialized = true;
+ result = true;
+
+ std::cout << "[DllMain] Safe decoder registration completed successfully" << std::endl;
+ }
+ catch (const std::exception& e) {
+ std::cout << "[DllMain] ERROR during initialization: " << e.what() << std::endl;
+ result = false;
+ }
+ catch (...) {
+ std::cout << "[DllMain] ERROR: Unknown exception during initialization" << std::endl;
+ result = false;
+ }
+ }
+
+ LeaveCriticalSection(&g_dll_cs);
+ return result;
+}
+
+// Check if DLL is ready for safe operations
+extern "C" bool IsDllReadyForInitialization()
+{
+ return g_safe_to_initialize;
+}
\ No newline at end of file
diff --git a/vav2/platforms/windows/vavcore/src/VavCore.cpp b/vav2/platforms/windows/vavcore/src/VavCore.cpp
index 8377ebf..1c2465f 100644
--- a/vav2/platforms/windows/vavcore/src/VavCore.cpp
+++ b/vav2/platforms/windows/vavcore/src/VavCore.cpp
@@ -14,13 +14,9 @@
// Use VavCore namespace internally
using namespace VavCore;
-// Forward declarations for decoder registration functions
-namespace VavCore {
- extern void RegisterAV1Decoders();
- extern void RegisterNVDECDecoders();
- extern void RegisterVPLDecoders();
- extern void RegisterAMFDecoders();
-}
+// Forward declarations for DllMain-based initialization
+extern "C" bool PerformSafeDllInitialization();
+extern "C" bool IsDllReadyForInitialization();
// Global state
static bool g_initialized = false;
@@ -164,19 +160,21 @@ VAVCORE_API VavCoreResult vavcore_initialize(void) {
return VAVCORE_SUCCESS;
}
- try {
- // Initialize decoder factories and other subsystems
- // Force decoder registration (in case static initialization fails)
- RegisterAV1Decoders();
- RegisterNVDECDecoders();
- RegisterVPLDecoders();
- RegisterAMFDecoders();
-
- g_initialized = true;
- return VAVCORE_SUCCESS;
- } catch (...) {
+ // Check if DLL is ready for safe initialization
+ if (!IsDllReadyForInitialization()) {
+ std::cout << "[vavcore_initialize] ERROR: DLL not ready for initialization" << std::endl;
return VAVCORE_ERROR_INIT_FAILED;
}
+
+ // Perform safe DLL-level initialization
+ if (!PerformSafeDllInitialization()) {
+ std::cout << "[vavcore_initialize] ERROR: Safe DLL initialization failed" << std::endl;
+ return VAVCORE_ERROR_INIT_FAILED;
+ }
+
+ std::cout << "[vavcore_initialize] VavCore initialization completed successfully" << std::endl;
+ g_initialized = true;
+ return VAVCORE_SUCCESS;
}
VAVCORE_API void vavcore_cleanup(void) {