diff --git a/.gitignore b/.gitignore
index e222b0b..15267f5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -378,7 +378,8 @@ output.mp4
# 그럴 경우 이 줄을 주석 처리하거나 더 구체적인 경로를 지정해야 합니다.
*.a
*.so
-/vav2/Vav2Player/packages/
-/vav2/VavCore/lib/
/vav2/Vav2Player_Android/vavcore/build/
/vav2/godot_extension/libs/
+/vav2/platforms/windows/applications/vav2player/packages/
+/vav2/platforms/windows/godot-plugin/libs/
+/vav2/platforms/windows/vavcore/lib
diff --git a/vav2/CLAUDE.md b/vav2/CLAUDE.md
index fde0775..b93e691 100644
--- a/vav2/CLAUDE.md
+++ b/vav2/CLAUDE.md
@@ -224,80 +224,88 @@ WinUI 3 C++로 작성된 AV1 파일 재생 플레이어
## 📁 프로젝트 파일 경로 (Project File Locations)
-### **메인 프로젝트 파일들** (2025-09-25 구조 재편성 완료)
-- **GUI 프로젝트**: `D:\Project\video-av1\vav2\Vav2Player\Vav2Player\Vav2Player.vcxproj`
-- **헤드리스 테스트**: `D:\Project\video-av1\vav2\Vav2Player\Vav2PlayerHeadless\Vav2PlayerHeadless.vcxproj`
-- **유닛 테스트**: `D:\Project\video-av1\vav2\Vav2Player\Vav2UnitTest\Vav2UnitTest.vcxproj`
-- **VavCore 라이브러리**: `D:\Project\video-av1\vav2\Vav2Player\VavCore\VavCore.vcxproj`
-- **솔루션 파일**: `D:\Project\video-av1\vav2\Vav2Player\Vav2Player.sln`
+### **메인 프로젝트 파일들** (2025-09-28 플랫폼별 구조 완성)
+- **VavCore 라이브러리**: `D:\Project\video-av1\vav2\platforms\windows\vavcore\VavCore.vcxproj`
+- **Godot Extension**: `D:\Project\video-av1\vav2\platforms\windows\godot-plugin\src\VavCore.Godot\VavCore.Godot.csproj`
+- **GUI 애플리케이션**: `D:\Project\video-av1\vav2\platforms\windows\applications\vav2player\Vav2Player\Vav2Player.vcxproj`
+- **솔루션 파일**: `D:\Project\video-av1\vav2\platforms\windows\applications\vav2player\Vav2Player.sln`
+- **테스트 프로젝트들**: `D:\Project\video-av1\vav2\platforms\windows\tests\*\`
-### **빌드 명령어 템플릿**
+### **빌드 명령어 템플릿** (플랫폼별 구조)
```bash
-# GUI 프로젝트 빌드
-cd "D:\Project\video-av1\vav2\Vav2Player\Vav2Player"
-"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Vav2Player.vcxproj //p:Configuration=Debug //p:Platform=x64 //v:minimal
+# 전체 Windows 플랫폼 빌드 (모든 컴포넌트)
+cd "D:\Project\video-av1\vav2\platforms\windows"
+./build-all.bat
-# VavCore 라이브러리 빌드
-cd "D:\Project\video-av1\vav2\Vav2Player\VavCore"
-"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" VavCore.vcxproj //p:Configuration=Debug //p:Platform=x64 //v:minimal
+# 개별 컴포넌트 빌드
+# VavCore 라이브러리
+cd "D:\Project\video-av1\vav2\platforms\windows\vavcore"
+./build.bat Debug
-# 헤드리스 테스트 빌드
-cd "D:\Project\video-av1\vav2\Vav2Player\Vav2PlayerHeadless"
-"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Vav2PlayerHeadless.vcxproj //p:Configuration=Debug //p:Platform=x64 //v:minimal
+# Godot Extension
+cd "D:\Project\video-av1\vav2\platforms\windows\godot-plugin"
+./build.bat Debug
-# 유닛 테스트 빌드
-cd "D:\Project\video-av1\vav2\Vav2Player\Vav2UnitTest"
-"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Vav2UnitTest.vcxproj //p:Configuration=Debug //p:Platform=x64 //v:minimal
-
-# 전체 솔루션 빌드
-cd "D:\Project\video-av1\vav2\Vav2Player"
+# GUI 애플리케이션
+cd "D:\Project\video-av1\vav2\platforms\windows\applications\vav2player"
"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Vav2Player.sln //p:Configuration=Debug //p:Platform=x64 //v:minimal
+
+# 모든 테스트 실행
+cd "D:\Project\video-av1\vav2\platforms\windows\tests"
+./run-all-tests.bat Debug
```
-### **실행 파일 경로** (2025-09-25 구조 재편성 완료)
-- **GUI 실행파일**: `D:\Project\video-av1\vav2\Vav2Player\Vav2Player\x64\Debug\Vav2Player\Vav2Player.exe`
-- **헤드리스 실행파일**: `D:\Project\video-av1\vav2\Vav2Player\Vav2PlayerHeadless\x64\Debug\Headless\Vav2PlayerHeadless.exe`
-- **유닛 테스트 DLL**: `D:\Project\video-av1\vav2\Vav2Player\Vav2UnitTest\x64\Debug\UnitTest\Vav2UnitTest.dll`
-- **VavCore 라이브러리**: `D:\Project\video-av1\vav2\Vav2Player\VavCore\x64\Debug\VavCore\VavCore.lib`
+### **실행 파일 경로** (2025-09-28 플랫폼별 구조)
+- **VavCore DLL**: `D:\Project\video-av1\vav2\platforms\windows\vavcore\lib\VavCore-debug.dll`
+- **Godot Extension**: `D:\Project\video-av1\vav2\platforms\windows\godot-plugin\bin\Debug\`
+- **GUI 실행파일**: `D:\Project\video-av1\vav2\platforms\windows\applications\vav2player\x64\Debug\Vav2Player\Vav2Player.exe`
+- **테스트 실행파일들**: `D:\Project\video-av1\vav2\platforms\windows\tests\*\bin\Debug\`
-### **주요 디렉토리** (2025-09-25 구조 재편성 완료)
-- **GUI 소스 코드**: `D:\Project\video-av1\vav2\Vav2Player\Vav2Player\src\`
-- **헤드리스 소스**: `D:\Project\video-av1\vav2\Vav2Player\Vav2PlayerHeadless\src\`
-- **유닛 테스트 소스**: `D:\Project\video-av1\vav2\Vav2Player\Vav2UnitTest\tests\`
-- **VavCore 소스**: `D:\Project\video-av1\vav2\Vav2Player\VavCore\src\`
-- **VavCore 헤더**: `D:\Project\video-av1\vav2\Vav2Player\VavCore\include\VavCore\`
+### **주요 디렉토리** (2025-09-28 플랫폼별 구조)
+- **VavCore 소스**: `D:\Project\video-av1\vav2\platforms\windows\vavcore\src\`
+- **VavCore 헤더**: `D:\Project\video-av1\vav2\platforms\windows\vavcore\include\VavCore\`
+- **Godot Extension 소스**: `D:\Project\video-av1\vav2\platforms\windows\godot-plugin\src\`
+- **GUI 애플리케이션 소스**: `D:\Project\video-av1\vav2\platforms\windows\applications\vav2player\Vav2Player\src\`
+- **테스트 소스들**: `D:\Project\video-av1\vav2\platforms\windows\tests\*\`
-## 프로젝트 구조 (2025-09-25 구조 재편성 완료)
+## 프로젝트 구조 (2025-09-28 플랫폼별 구조 완성)
```
D:\Project\video-av1\
├── vav2/
-│ └── Vav2Player/ # WinUI 3 C++ 프로젝트 루트
-│ ├── Vav2Player.sln # Visual Studio 솔루션
-│ ├── Vav2Player/ # GUI 프로젝트
-│ │ ├── Vav2Player.vcxproj # GUI 프로젝트 파일
-│ │ ├── MainWindow.xaml.* # 메인 윈도우 (네비게이션)
-│ │ ├── MainVideoPage.xaml.* # 메인 비디오 페이지
-│ │ ├── MultiVideoPage.xaml.* # 멀티 비디오 페이지 (이름 변경됨)
-│ │ ├── LayeredVideoPage.xaml.*# 레이어드 비디오 페이지
-│ │ └── VideoPlayerControl.* # 비디오 플레이어 컨트롤
-│ ├── Vav2PlayerHeadless/ # 헤드리스 테스트 프로젝트
-│ │ ├── Vav2PlayerHeadless.vcxproj
-│ │ └── src/ # 헤드리스 소스 코드
-│ ├── Vav2UnitTest/ # 유닛 테스트 프로젝트
-│ │ ├── Vav2UnitTest.vcxproj
-│ │ └── tests/ # 테스트 소스 코드
-│ └── VavCore/ # VavCore 정적 라이브러리
-│ ├── VavCore.vcxproj
-│ ├── include/VavCore/ # Public API 헤더
-│ └── src/ # VavCore 구현 코드
+│ └── platforms/ # 플랫폼별 통합 디렉토리
+│ └── windows/ # Windows 플랫폼 전용
+│ ├── vavcore/ # VavCore 라이브러리
+│ │ ├── VavCore.vcxproj # C/C++ DLL 프로젝트
+│ │ ├── build.bat # VavCore 개별 빌드
+│ │ ├── include/VavCore/ # Public API 헤더
+│ │ └── src/ # VavCore 구현 코드
+│ ├── godot-plugin/ # Godot 4.4.1 Extension
+│ │ ├── src/VavCore.Wrapper/ # C# P/Invoke 래퍼
+│ │ ├── src/VavCore.Godot/ # Godot 플러그인
+│ │ ├── libs/windows-x86_64/ # 빌드된 DLL
+│ │ └── build.bat # Godot 확장 빌드
+│ ├── applications/ # Windows 애플리케이션들
+│ │ └── vav2player/ # Vav2Player GUI 앱
+│ │ ├── Vav2Player.sln # Visual Studio 솔루션
+│ │ └── Vav2Player/ # WinUI3 프로젝트
+│ ├── tests/ # 모든 Windows 테스트
+│ │ ├── vavcore-dll/ # VavCore DLL 연결 테스트
+│ │ ├── godot-extension/ # Godot 확장 테스트
+│ │ ├── integration/ # 통합 테스트
+│ │ ├── unit-tests/ # 유닛 테스트
+│ │ ├── headless/ # 헤드리스 성능 테스트
+│ │ └── run-all-tests.bat # 모든 테스트 실행
+│ └── build-all.bat # 전체 Windows 빌드
├── include/
│ ├── libwebm/ # libwebm 헤더 (mkvparser, mkvmuxer)
-│ └── dav1d/ # dav1d 헤더 (dav1d.h, picture.h 등)
+│ ├── dav1d/ # dav1d 헤더 (dav1d.h, picture.h 등)
+│ ├── amf/ # AMD AMF 헤더
+│ └── libvpl/ # Intel VPL 헤더
└── lib/
├── libwebm/webm.lib # libwebm 정적 라이브러리 (x64)
- └── dav1d/ # dav1d 동적 라이브러리 (x64)
- ├── dav1d.dll
- └── dav1d.lib
+ ├── dav1d/ # dav1d 동적 라이브러리 (x64)
+ ├── amf/ # AMD AMF 라이브러리
+ └── libvpl/ # Intel VPL 라이브러리
```
## 전체 아키텍처 설계
diff --git a/vav2/Vav2Player/Vav2Player/Vav2Player.vcxproj.user b/vav2/Vav2Player/Vav2Player/Vav2Player.vcxproj.user
deleted file mode 100644
index 88a5509..0000000
--- a/vav2/Vav2Player/Vav2Player/Vav2Player.vcxproj.user
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/vav2/Vav2Player/.vscode/settings.json b/vav2/platforms/windows/applications/vav2player/.vscode/settings.json
similarity index 100%
rename from vav2/Vav2Player/.vscode/settings.json
rename to vav2/platforms/windows/applications/vav2player/.vscode/settings.json
diff --git a/vav2/Vav2Player/README.md b/vav2/platforms/windows/applications/vav2player/README.md
similarity index 100%
rename from vav2/Vav2Player/README.md
rename to vav2/platforms/windows/applications/vav2player/README.md
diff --git a/vav2/Vav2Player/Vav2Player.sln b/vav2/platforms/windows/applications/vav2player/Vav2Player.sln
similarity index 62%
rename from vav2/Vav2Player/Vav2Player.sln
rename to vav2/platforms/windows/applications/vav2player/Vav2Player.sln
index b03f84a..f55712f 100644
--- a/vav2/Vav2Player/Vav2Player.sln
+++ b/vav2/platforms/windows/applications/vav2player/Vav2Player.sln
@@ -5,14 +5,7 @@ VisualStudioVersion = 17.14.36511.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vav2Player", "Vav2Player\Vav2Player.vcxproj", "{C52EFC56-E19C-4568-9D83-A5A5E5282E1E}"
EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vav2PlayerHeadless", "Vav2PlayerHeadless\Vav2PlayerHeadless.vcxproj", "{E8B13F42-1234-5678-9ABC-123456789ABC}"
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Vav2UnitTest", "Vav2UnitTest\Vav2UnitTest.vcxproj", "{2F8B5F4C-7E8D-4A9B-8C6D-1E3F5A7B9C2D}"
- ProjectSection(ProjectDependencies) = postProject
- {B8F7E8E0-F8F7-4A8A-9A8A-8A8A8A8A8A8A} = {B8F7E8E0-F8F7-4A8A-9A8A-8A8A8A8A8A8A}
- EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VavCore", "..\VavCore\VavCore.vcxproj", "{B8F7E8E0-F8F7-4A8A-9A8A-8A8A8A8A8A8A}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VavCore", "..\..\vavcore\VavCore.vcxproj", "{B8F7E8E0-F8F7-4A8A-9A8A-8A8A8A8A8A8A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -42,22 +35,6 @@ Global
{C52EFC56-E19C-4568-9D83-A5A5E5282E1E}.Release|x86.ActiveCfg = Release|Win32
{C52EFC56-E19C-4568-9D83-A5A5E5282E1E}.Release|x86.Build.0 = Release|Win32
{C52EFC56-E19C-4568-9D83-A5A5E5282E1E}.Release|x86.Deploy.0 = Release|Win32
- {E8B13F42-1234-5678-9ABC-123456789ABC}.Debug|ARM64.ActiveCfg = Debug|x64
- {E8B13F42-1234-5678-9ABC-123456789ABC}.Debug|x64.ActiveCfg = Debug|x64
- {E8B13F42-1234-5678-9ABC-123456789ABC}.Debug|x64.Build.0 = Debug|x64
- {E8B13F42-1234-5678-9ABC-123456789ABC}.Debug|x86.ActiveCfg = Debug|x64
- {E8B13F42-1234-5678-9ABC-123456789ABC}.Release|ARM64.ActiveCfg = Release|x64
- {E8B13F42-1234-5678-9ABC-123456789ABC}.Release|x64.ActiveCfg = Release|x64
- {E8B13F42-1234-5678-9ABC-123456789ABC}.Release|x64.Build.0 = Release|x64
- {E8B13F42-1234-5678-9ABC-123456789ABC}.Release|x86.ActiveCfg = Release|x64
- {2F8B5F4C-7E8D-4A9B-8C6D-1E3F5A7B9C2D}.Debug|ARM64.ActiveCfg = Debug|x64
- {2F8B5F4C-7E8D-4A9B-8C6D-1E3F5A7B9C2D}.Debug|x64.ActiveCfg = Debug|x64
- {2F8B5F4C-7E8D-4A9B-8C6D-1E3F5A7B9C2D}.Debug|x64.Build.0 = Debug|x64
- {2F8B5F4C-7E8D-4A9B-8C6D-1E3F5A7B9C2D}.Debug|x86.ActiveCfg = Debug|x64
- {2F8B5F4C-7E8D-4A9B-8C6D-1E3F5A7B9C2D}.Release|ARM64.ActiveCfg = Release|x64
- {2F8B5F4C-7E8D-4A9B-8C6D-1E3F5A7B9C2D}.Release|x64.ActiveCfg = Release|x64
- {2F8B5F4C-7E8D-4A9B-8C6D-1E3F5A7B9C2D}.Release|x64.Build.0 = Release|x64
- {2F8B5F4C-7E8D-4A9B-8C6D-1E3F5A7B9C2D}.Release|x86.ActiveCfg = Release|x64
{B8F7E8E0-F8F7-4A8A-9A8A-8A8A8A8A8A8A}.Debug|ARM64.ActiveCfg = Debug|x64
{B8F7E8E0-F8F7-4A8A-9A8A-8A8A8A8A8A8A}.Debug|x64.ActiveCfg = Debug|x64
{B8F7E8E0-F8F7-4A8A-9A8A-8A8A8A8A8A8A}.Debug|x64.Build.0 = Debug|x64
diff --git a/vav2/Vav2Player/Vav2Player/App.xaml b/vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/App.xaml
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml
diff --git a/vav2/Vav2Player/Vav2Player/App.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/App.xaml.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml.cpp
diff --git a/vav2/Vav2Player/Vav2Player/App.xaml.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/App.xaml.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml.h
diff --git a/vav2/Vav2Player/Vav2Player/Assets/LockScreenLogo.scale-200.png b/vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/LockScreenLogo.scale-200.png
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Assets/LockScreenLogo.scale-200.png
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/LockScreenLogo.scale-200.png
diff --git a/vav2/Vav2Player/Vav2Player/Assets/SplashScreen.scale-200.png b/vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/SplashScreen.scale-200.png
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Assets/SplashScreen.scale-200.png
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/SplashScreen.scale-200.png
diff --git a/vav2/Vav2Player/Vav2Player/Assets/Square150x150Logo.scale-200.png b/vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/Square150x150Logo.scale-200.png
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Assets/Square150x150Logo.scale-200.png
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/Square150x150Logo.scale-200.png
diff --git a/vav2/Vav2Player/Vav2Player/Assets/Square44x44Logo.scale-200.png b/vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/Square44x44Logo.scale-200.png
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Assets/Square44x44Logo.scale-200.png
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/Square44x44Logo.scale-200.png
diff --git a/vav2/Vav2Player/Vav2Player/Assets/Square44x44Logo.targetsize-24_altform-unplated.png b/vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
diff --git a/vav2/Vav2Player/Vav2Player/Assets/StoreLogo.png b/vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/StoreLogo.png
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Assets/StoreLogo.png
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/StoreLogo.png
diff --git a/vav2/Vav2Player/Vav2Player/Assets/Wide310x150Logo.scale-200.png b/vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/Wide310x150Logo.scale-200.png
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Assets/Wide310x150Logo.scale-200.png
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Assets/Wide310x150Logo.scale-200.png
diff --git a/vav2/Vav2Player/Vav2Player/LayeredVideoPage.idl b/vav2/platforms/windows/applications/vav2player/Vav2Player/LayeredVideoPage.idl
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/LayeredVideoPage.idl
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/LayeredVideoPage.idl
diff --git a/vav2/Vav2Player/Vav2Player/LayeredVideoPage.xaml b/vav2/platforms/windows/applications/vav2player/Vav2Player/LayeredVideoPage.xaml
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/LayeredVideoPage.xaml
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/LayeredVideoPage.xaml
diff --git a/vav2/Vav2Player/Vav2Player/LayeredVideoPage.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/LayeredVideoPage.xaml.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/LayeredVideoPage.xaml.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/LayeredVideoPage.xaml.cpp
diff --git a/vav2/Vav2Player/Vav2Player/LayeredVideoPage.xaml.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/LayeredVideoPage.xaml.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/LayeredVideoPage.xaml.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/LayeredVideoPage.xaml.h
diff --git a/vav2/Vav2Player/Vav2Player/LogMessagePage.idl b/vav2/platforms/windows/applications/vav2player/Vav2Player/LogMessagePage.idl
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/LogMessagePage.idl
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/LogMessagePage.idl
diff --git a/vav2/Vav2Player/Vav2Player/LogMessagePage.xaml b/vav2/platforms/windows/applications/vav2player/Vav2Player/LogMessagePage.xaml
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/LogMessagePage.xaml
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/LogMessagePage.xaml
diff --git a/vav2/Vav2Player/Vav2Player/LogMessagePage.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/LogMessagePage.xaml.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/LogMessagePage.xaml.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/LogMessagePage.xaml.cpp
diff --git a/vav2/Vav2Player/Vav2Player/LogMessagePage.xaml.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/LogMessagePage.xaml.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/LogMessagePage.xaml.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/LogMessagePage.xaml.h
diff --git a/vav2/Vav2Player/Vav2Player/MainVideoPage.idl b/vav2/platforms/windows/applications/vav2player/Vav2Player/MainVideoPage.idl
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MainVideoPage.idl
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MainVideoPage.idl
diff --git a/vav2/Vav2Player/Vav2Player/MainVideoPage.xaml b/vav2/platforms/windows/applications/vav2player/Vav2Player/MainVideoPage.xaml
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MainVideoPage.xaml
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MainVideoPage.xaml
diff --git a/vav2/Vav2Player/Vav2Player/MainVideoPage.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/MainVideoPage.xaml.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MainVideoPage.xaml.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MainVideoPage.xaml.cpp
diff --git a/vav2/Vav2Player/Vav2Player/MainVideoPage.xaml.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/MainVideoPage.xaml.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MainVideoPage.xaml.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MainVideoPage.xaml.h
diff --git a/vav2/Vav2Player/Vav2Player/MainWindow.idl b/vav2/platforms/windows/applications/vav2player/Vav2Player/MainWindow.idl
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MainWindow.idl
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MainWindow.idl
diff --git a/vav2/Vav2Player/Vav2Player/MainWindow.xaml b/vav2/platforms/windows/applications/vav2player/Vav2Player/MainWindow.xaml
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MainWindow.xaml
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MainWindow.xaml
diff --git a/vav2/Vav2Player/Vav2Player/MainWindow.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/MainWindow.xaml.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MainWindow.xaml.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MainWindow.xaml.cpp
diff --git a/vav2/Vav2Player/Vav2Player/MainWindow.xaml.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/MainWindow.xaml.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MainWindow.xaml.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MainWindow.xaml.h
diff --git a/vav2/Vav2Player/Vav2Player/MultiVideoPage.idl b/vav2/platforms/windows/applications/vav2player/Vav2Player/MultiVideoPage.idl
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MultiVideoPage.idl
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MultiVideoPage.idl
diff --git a/vav2/Vav2Player/Vav2Player/MultiVideoPage.xaml b/vav2/platforms/windows/applications/vav2player/Vav2Player/MultiVideoPage.xaml
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MultiVideoPage.xaml
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MultiVideoPage.xaml
diff --git a/vav2/Vav2Player/Vav2Player/MultiVideoPage.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/MultiVideoPage.xaml.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MultiVideoPage.xaml.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MultiVideoPage.xaml.cpp
diff --git a/vav2/Vav2Player/Vav2Player/MultiVideoPage.xaml.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/MultiVideoPage.xaml.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/MultiVideoPage.xaml.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/MultiVideoPage.xaml.h
diff --git a/vav2/Vav2Player/Vav2Player/Package.appxmanifest b/vav2/platforms/windows/applications/vav2player/Vav2Player/Package.appxmanifest
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Package.appxmanifest
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Package.appxmanifest
diff --git a/vav2/Vav2Player/Vav2Player/SettingsPage.idl b/vav2/platforms/windows/applications/vav2player/Vav2Player/SettingsPage.idl
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/SettingsPage.idl
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/SettingsPage.idl
diff --git a/vav2/Vav2Player/Vav2Player/SettingsPage.xaml b/vav2/platforms/windows/applications/vav2player/Vav2Player/SettingsPage.xaml
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/SettingsPage.xaml
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/SettingsPage.xaml
diff --git a/vav2/Vav2Player/Vav2Player/SettingsPage.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/SettingsPage.xaml.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/SettingsPage.xaml.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/SettingsPage.xaml.cpp
diff --git a/vav2/Vav2Player/Vav2Player/SettingsPage.xaml.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/SettingsPage.xaml.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/SettingsPage.xaml.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/SettingsPage.xaml.h
diff --git a/vav2/Vav2Player/Vav2Player/Vav2Player.vcxproj b/vav2/platforms/windows/applications/vav2player/Vav2Player/Vav2Player.vcxproj
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Vav2Player.vcxproj
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Vav2Player.vcxproj
diff --git a/vav2/Vav2Player/Vav2Player/Vav2Player.vcxproj.filters b/vav2/platforms/windows/applications/vav2player/Vav2Player/Vav2Player.vcxproj.filters
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/Vav2Player.vcxproj.filters
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/Vav2Player.vcxproj.filters
diff --git a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.idl b/vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl.idl
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/VideoPlayerControl.idl
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl.idl
diff --git a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml b/vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl.xaml
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl.xaml
diff --git a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl.xaml.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl.xaml.cpp
diff --git a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl.xaml.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl.xaml.h
diff --git a/vav2/Vav2Player/Vav2Player/app.manifest b/vav2/platforms/windows/applications/vav2player/Vav2Player/app.manifest
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/app.manifest
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/app.manifest
diff --git a/vav2/Vav2Player/Vav2Player/packages.config b/vav2/platforms/windows/applications/vav2player/Vav2Player/packages.config
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/packages.config
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/packages.config
diff --git a/vav2/Vav2Player/Vav2Player/pch.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/pch.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/pch.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/pch.cpp
diff --git a/vav2/Vav2Player/Vav2Player/pch.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/pch.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/pch.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/pch.h
diff --git a/vav2/Vav2Player/Vav2Player/readme.txt b/vav2/platforms/windows/applications/vav2player/Vav2Player/readme.txt
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/readme.txt
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/readme.txt
diff --git a/vav2/Vav2Player/Vav2Player/src/Common/D3D12Helpers.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Common/D3D12Helpers.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Common/D3D12Helpers.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Common/D3D12Helpers.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Common/VavCoreVideoTypes.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Common/VavCoreVideoTypes.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Common/VavCoreVideoTypes.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Common/VavCoreVideoTypes.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Common/VideoTypes.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Common/VideoTypes.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Common/VideoTypes.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Common/VideoTypes.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/AV1Decoder.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AV1Decoder.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/AV1Decoder.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AV1Decoder.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/AV1Decoder.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AV1Decoder.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/AV1Decoder.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AV1Decoder.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveAV1Decoder.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveAV1Decoder.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveAV1Decoder.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveAV1Decoder.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveAV1Decoder.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveAV1Decoder.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveAV1Decoder.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveAV1Decoder.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveDecodingExample.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveDecodingExample.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveDecodingExample.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveDecodingExample.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveNVDECDecoder.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveNVDECDecoder.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveNVDECDecoder.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveNVDECDecoder.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveNVDECDecoder.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveNVDECDecoder.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/AdaptiveNVDECDecoder.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/AdaptiveNVDECDecoder.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/IVideoDecoder.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/IVideoDecoder.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/IVideoDecoder.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/IVideoDecoder.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/MediaFoundationAV1Decoder.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/MediaFoundationAV1Decoder.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/MediaFoundationAV1Decoder.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/MediaFoundationAV1Decoder.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/MediaFoundationAV1Decoder.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/MediaFoundationAV1Decoder.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/MediaFoundationAV1Decoder.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/MediaFoundationAV1Decoder.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/NVDECAV1Decoder.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/NVDECAV1Decoder.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/NVDECAV1Decoder.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/NVDECAV1Decoder.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/NVDECAV1Decoder.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/NVDECAV1Decoder.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/NVDECAV1Decoder.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/NVDECAV1Decoder.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/VideoDecoderFactory.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/VideoDecoderFactory.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/VideoDecoderFactory.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/VideoDecoderFactory.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Decoder/VideoDecoderFactory.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/VideoDecoderFactory.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Decoder/VideoDecoderFactory.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Decoder/VideoDecoderFactory.h
diff --git a/vav2/Vav2Player/Vav2Player/src/FileIO/IWebMFileReader.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/FileIO/IWebMFileReader.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/FileIO/IWebMFileReader.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/FileIO/IWebMFileReader.h
diff --git a/vav2/Vav2Player/Vav2Player/src/FileIO/WebMFileReader.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/FileIO/WebMFileReader.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/FileIO/WebMFileReader.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/FileIO/WebMFileReader.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/FileIO/WebMFileReader.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/FileIO/WebMFileReader.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/FileIO/WebMFileReader.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/FileIO/WebMFileReader.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Logger/ILogManager.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/ILogManager.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Logger/ILogManager.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/ILogManager.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Logger/ILogOutput.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/ILogOutput.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Logger/ILogOutput.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/ILogOutput.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Logger/LogManager.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/LogManager.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Logger/LogManager.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/LogManager.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Logger/LogManager.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/LogManager.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Logger/LogManager.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/LogManager.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Logger/LogOutputs.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/LogOutputs.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Logger/LogOutputs.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/LogOutputs.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Logger/LogOutputs.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/LogOutputs.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Logger/LogOutputs.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/LogOutputs.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Logger/SimpleLogger.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/SimpleLogger.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Logger/SimpleLogger.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Logger/SimpleLogger.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Rendering/D3D12VideoRenderer.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/D3D12VideoRenderer.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Rendering/D3D12VideoRenderer.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/D3D12VideoRenderer.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Rendering/D3D12VideoRenderer.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/D3D12VideoRenderer.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Rendering/D3D12VideoRenderer.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/D3D12VideoRenderer.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Rendering/GlobalD3D12SyncManager.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/GlobalD3D12SyncManager.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Rendering/GlobalD3D12SyncManager.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/GlobalD3D12SyncManager.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Rendering/GlobalD3D12SyncManager.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/GlobalD3D12SyncManager.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Rendering/GlobalD3D12SyncManager.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/GlobalD3D12SyncManager.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Rendering/IVideoRenderer.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/IVideoRenderer.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Rendering/IVideoRenderer.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/IVideoRenderer.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Rendering/SimpleGPURenderer.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/SimpleGPURenderer.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Rendering/SimpleGPURenderer.cpp
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/SimpleGPURenderer.cpp
diff --git a/vav2/Vav2Player/Vav2Player/src/Rendering/SimpleGPURenderer.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/SimpleGPURenderer.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Rendering/SimpleGPURenderer.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/SimpleGPURenderer.h
diff --git a/vav2/Vav2Player/Vav2Player/src/Rendering/d3dx12.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/d3dx12.h
similarity index 100%
rename from vav2/Vav2Player/Vav2Player/src/Rendering/d3dx12.h
rename to vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/d3dx12.h
diff --git a/vav2/platforms/windows/build-all.bat b/vav2/platforms/windows/build-all.bat
new file mode 100644
index 0000000..30c7cab
--- /dev/null
+++ b/vav2/platforms/windows/build-all.bat
@@ -0,0 +1,119 @@
+@echo off
+REM =============================================================================
+REM Windows Platform Build Script - All Components
+REM =============================================================================
+
+echo [BUILD] Starting Windows platform build process...
+
+REM Set build configuration
+set BUILD_CONFIG=Debug
+set PLATFORM=x64
+
+REM Build directories
+set VAVCORE_DIR=%~dp0vavcore
+set GODOT_DIR=%~dp0godot-plugin
+set APP_DIR=%~dp0applications\vav2player
+set TEST_DIR=%~dp0tests
+
+echo.
+echo ============================================================
+echo BUILDING VAVCORE LIBRARY
+echo ============================================================
+cd /d "%VAVCORE_DIR%"
+echo [BUILD] Building VavCore library...
+"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" VavCore.vcxproj /p:Configuration=%BUILD_CONFIG% /p:Platform=%PLATFORM% /v:minimal
+if errorlevel 1 (
+ echo [ERROR] VavCore build failed!
+ exit /b 1
+)
+echo [SUCCESS] VavCore library built successfully
+
+echo.
+echo ============================================================
+echo BUILDING GODOT EXTENSION
+echo ============================================================
+cd /d "%GODOT_DIR%"
+echo [BUILD] Building Godot extension...
+dotnet build src\VavCore.Wrapper\VavCore.Wrapper.csproj -c %BUILD_CONFIG%
+if errorlevel 1 (
+ echo [ERROR] VavCore.Wrapper build failed!
+ exit /b 1
+)
+
+dotnet build src\VavCore.Godot\VavCore.Godot.csproj -c %BUILD_CONFIG%
+if errorlevel 1 (
+ echo [ERROR] VavCore.Godot build failed!
+ exit /b 1
+)
+echo [SUCCESS] Godot extension built successfully
+
+echo.
+echo ============================================================
+echo BUILDING APPLICATIONS
+echo ============================================================
+cd /d "%APP_DIR%"
+echo [BUILD] Building Vav2Player application...
+"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Vav2Player.sln /p:Configuration=%BUILD_CONFIG% /p:Platform=%PLATFORM% /v:minimal
+if errorlevel 1 (
+ echo [ERROR] Vav2Player build failed!
+ exit /b 1
+)
+echo [SUCCESS] Vav2Player application built successfully
+
+echo.
+echo ============================================================
+echo BUILDING TESTS
+echo ============================================================
+cd /d "%TEST_DIR%"
+
+REM Build VavCore DLL Test
+echo [BUILD] Building VavCore DLL test...
+cd vavcore-dll
+dotnet build TestVavCoreDLL.csproj -c %BUILD_CONFIG%
+if errorlevel 1 (
+ echo [ERROR] VavCore DLL test build failed!
+ exit /b 1
+)
+
+REM Build Integration Test
+echo [BUILD] Building integration test...
+cd ..\integration
+dotnet build VavCoreTest.csproj -c %BUILD_CONFIG%
+if errorlevel 1 (
+ echo [ERROR] Integration test build failed!
+ exit /b 1
+)
+
+REM Build Unit Tests
+echo [BUILD] Building unit tests...
+cd ..\unit-tests\Vav2UnitTest
+"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Vav2UnitTest.vcxproj /p:Configuration=%BUILD_CONFIG% /p:Platform=%PLATFORM% /v:minimal
+if errorlevel 1 (
+ echo [ERROR] Unit tests build failed!
+ exit /b 1
+)
+
+REM Build Headless Test
+echo [BUILD] Building headless test...
+cd ..\..\headless
+"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" Vav2PlayerHeadless.vcxproj /p:Configuration=%BUILD_CONFIG% /p:Platform=%PLATFORM% /v:minimal
+if errorlevel 1 (
+ echo [ERROR] Headless test build failed!
+ exit /b 1
+)
+
+echo [SUCCESS] All tests built successfully
+
+echo.
+echo ============================================================
+echo BUILD COMPLETE
+echo ============================================================
+echo [SUCCESS] All Windows platform components built successfully!
+echo.
+echo Built components:
+echo - VavCore Library (C/C++)
+echo - Godot Extension (C# Wrapper + Godot Plugin)
+echo - Vav2Player Application (WinUI3)
+echo - All Test Projects
+echo.
+echo Build artifacts are located in respective output directories.
\ No newline at end of file
diff --git a/vav2/VavCoreTest/Program.cs b/vav2/platforms/windows/godot-plugin/Program.cs
similarity index 94%
rename from vav2/VavCoreTest/Program.cs
rename to vav2/platforms/windows/godot-plugin/Program.cs
index f565171..2fdbb93 100644
--- a/vav2/VavCoreTest/Program.cs
+++ b/vav2/platforms/windows/godot-plugin/Program.cs
@@ -26,10 +26,7 @@ class Program
{
Console.WriteLine($" ERROR: {ex.Message}");
Console.WriteLine($" Exception Type: {ex.GetType().Name}");
- if (ex.InnerException != null)
- {
- Console.WriteLine($" Inner Exception: {ex.InnerException.Message}");
- }
+ Console.WriteLine($" Stack Trace: {ex.StackTrace}");
}
Console.WriteLine();
@@ -92,10 +89,6 @@ class Program
catch (Exception ex)
{
Console.WriteLine($" ERROR creating player: {ex.Message}");
- if (ex.InnerException != null)
- {
- Console.WriteLine($" Inner Exception: {ex.InnerException.Message}");
- }
}
finally
{
@@ -160,5 +153,7 @@ class Program
Console.WriteLine();
Console.WriteLine("=== VavCore.Wrapper Test Completed ===");
+ Console.WriteLine("Press any key to exit...");
+ Console.ReadKey();
}
}
\ No newline at end of file
diff --git a/vav2/platforms/windows/godot-plugin/README.md b/vav2/platforms/windows/godot-plugin/README.md
new file mode 100644
index 0000000..acce181
--- /dev/null
+++ b/vav2/platforms/windows/godot-plugin/README.md
@@ -0,0 +1,395 @@
+# VavCore Godot 4.x Extension
+
+Cross-platform C# extension for hardware-accelerated AV1 video decoding in Godot 4.x using VavCore library.
+
+## 🎯 **Features**
+
+### **🚀 Hardware-Accelerated AV1 Decoding**
+- **Windows**: NVIDIA NVDEC, Intel VPL, AMD AMF, Media Foundation
+- **Linux**: NVIDIA NVDEC, Intel VPL, AMD AMF, dav1d fallback
+- **macOS**: VideoToolbox, dav1d fallback
+- **Android**: MediaCodec, dav1d fallback (via Android plugin)
+- **iOS**: VideoToolbox, dav1d fallback
+
+### **🎮 Godot 4.x Integration**
+- **High-level Nodes**: Easy-to-use video player components
+- **Low-level API**: Direct decoder control for advanced use cases
+- **Resource System**: Godot-native video file and settings resources
+- **Editor Integration**: Asset importers, custom inspectors, dock widgets
+
+### **🔧 Cross-Platform Architecture**
+- **VavCore.Wrapper**: P/Invoke layer for C API access
+- **VavCore.Godot**: Godot-specific nodes and utilities
+- **Platform Plugins**: Native Android/iOS integration when needed
+
+## 📁 **Project Structure**
+
+```
+vav2/godot_extension/
+├── VavCoreGodot.sln # Visual Studio solution
+├── src/
+│ ├── VavCore.Wrapper/ # P/Invoke wrapper library
+│ │ ├── VavCore.Wrapper.csproj # .NET 6.0 library project
+│ │ ├── VavCoreTypes.cs # C# data types matching C API
+│ │ ├── VavCoreNative.cs # P/Invoke declarations
+│ │ └── VavCoreWrapper.cs # High-level C# wrapper
+│ └── VavCore.Godot/ # Godot extension library
+│ ├── VavCore.Godot.csproj # Godot 4.x project
+│ ├── Nodes/ # Godot nodes
+│ │ ├── VavCoreVideoPlayer.cs # High-level video player
+│ │ ├── VavCoreVideoTexture.cs # Video texture with YUV conversion
+│ │ └── VavCoreVideoStream.cs # Low-level stream control
+│ ├── Resources/ # Godot resources
+│ │ ├── VavCoreVideoFile.cs # Video file metadata resource
+│ │ └── VavCoreDecoderSettings.cs # Decoder configuration resource
+│ ├── Utilities/ # Helper utilities
+│ │ ├── VavCoreGodotUtils.cs # Platform detection and optimization
+│ │ └── VavCoreImageConverter.cs # Optimized YUV→RGB conversion
+│ └── Plugin/ # Editor integration
+│ └── VavCorePlugin.cs # Editor plugin and importers
+├── libs/ # Native library binaries
+│ ├── windows-x86_64/ # Windows VavCore.dll
+│ ├── linux-x86_64/ # Linux libVavCore.so
+│ └── osx-x86_64/ # macOS libVavCore.dylib
+└── README.md # This file
+```
+
+## 🚀 **Getting Started**
+
+### **1. Prerequisites**
+
+- **Godot 4.2.1+** with C# support
+- **.NET 6.0 SDK** or higher
+- **Visual Studio 2022** or **VS Code** with C# extension
+- **VavCore library** binaries for your platform
+- **VavCore C API** implementation (vavcore_* functions)
+
+### **2. Building the Extension**
+
+```bash
+# Clone or navigate to the extension directory
+cd vav2/godot_extension/
+
+# Restore NuGet packages
+dotnet restore
+
+# Build the solution
+dotnet build --configuration Release
+
+# Or build specific projects
+dotnet build src/VavCore.Wrapper/VavCore.Wrapper.csproj --configuration Release
+dotnet build src/VavCore.Godot/VavCore.Godot.csproj --configuration Release
+```
+
+### **3. Installing in Godot Project**
+
+#### **Option A: Add as Project Reference**
+```xml
+
+
+
+
+```
+
+#### **Option B: Copy Built Assemblies**
+```bash
+# Copy built DLLs to your Godot project
+cp src/VavCore.Wrapper/bin/Release/net6.0/VavCore.Wrapper.dll /path/to/godot/project/
+cp src/VavCore.Godot/bin/Release/net6.0/VavCore.Godot.dll /path/to/godot/project/
+
+# Copy native libraries
+cp libs/windows-x86_64/* /path/to/godot/project/ # Windows
+cp libs/linux-x86_64/* /path/to/godot/project/ # Linux
+cp libs/osx-x86_64/* /path/to/godot/project/ # macOS
+```
+
+## 🎮 **Usage Examples**
+
+### **Simple Video Player**
+
+```csharp
+using Godot;
+using VavCore.Wrapper;
+
+public partial class MyVideoPlayer : Control
+{
+ private VavCoreWrapper _player;
+
+ public override void _Ready()
+ {
+ // Initialize VavCore library
+ if (!VavCoreWrapper.Initialize())
+ {
+ GD.PrintErr("Failed to initialize VavCore");
+ return;
+ }
+
+ // Create video player
+ _player = new VavCoreWrapper();
+
+ // Open and play video
+ if (_player.OpenFile("res://videos/sample.webm"))
+ {
+ // Get metadata
+ if (_player.GetMetadata(out var metadata))
+ {
+ GD.Print($"Video: {metadata.Width}x{metadata.Height}, {metadata.DurationSeconds:F2}s");
+ }
+
+ // Decode frames
+ DecodeFrames();
+ }
+ }
+
+ private void DecodeFrames()
+ {
+ while (!_player.IsEndOfFile)
+ {
+ if (_player.DecodeNextFrame(out var frame))
+ {
+ GD.Print($"Decoded frame {frame.FrameNumber}: {frame.Width}x{frame.Height}");
+
+ // Convert to RGB if needed
+ // VavCoreWrapper.ConvertYuvToRgb(frame, rgbBuffer, stride);
+ }
+ }
+ }
+
+ public override void _ExitTree()
+ {
+ _player?.Dispose();
+ VavCoreWrapper.Cleanup();
+ }
+}
+```
+
+### **Advanced Stream Control**
+
+```csharp
+using VavCore.Godot.Nodes;
+using VavCore.Wrapper;
+
+public partial class AdvancedVideoControl : Node
+{
+ private VavCoreVideoStream _videoStream;
+
+ public override void _Ready()
+ {
+ _videoStream = new VavCoreVideoStream();
+
+ // Connect to low-level events
+ _videoStream.PacketRead += OnPacketRead;
+ _videoStream.FrameDecoded += OnFrameDecoded;
+ _videoStream.StreamError += OnStreamError;
+
+ // Open stream with specific decoder
+ _videoStream.OpenStream("res://videos/4k_video.webm", VavCoreTypes.DecoderType.NVDEC);
+ }
+
+ private void DecodeManualFrame()
+ {
+ // Manual frame-by-frame decoding
+ if (_videoStream.ReadNextPacket(out var packet))
+ {
+ if (_videoStream.DecodePacket(packet, out var frame))
+ {
+ // Process decoded frame
+ GD.Print($"Decoded frame {frame.FrameIndex}: {frame.Width}x{frame.Height}");
+ }
+ }
+ }
+
+ private void OnPacketRead(ulong frameIndex, double timestamp, uint packetSize)
+ {
+ GD.Print($"Read packet {frameIndex}: {packetSize} bytes at {timestamp:F3}s");
+ }
+
+ private void OnFrameDecoded(ulong frameIndex, double timestamp, Vector2I resolution)
+ {
+ GD.Print($"Decoded frame {frameIndex}: {resolution.X}x{resolution.Y} at {timestamp:F3}s");
+ }
+
+ private void OnStreamError(string errorMessage)
+ {
+ GD.PrintErr($"Stream error: {errorMessage}");
+ }
+}
+```
+
+### **Custom Decoder Settings**
+
+```csharp
+using VavCore.Godot.Resources;
+
+public partial class VideoSettings : Control
+{
+ public override void _Ready()
+ {
+ // Create optimal settings for current platform
+ var settings = VavCore.Godot.Utilities.VavCoreGodotUtils.CreateOptimalSettings();
+
+ // Customize settings
+ settings.PreferredDecoderType = VavCoreTypes.DecoderType.NVDEC;
+ settings.EnableHardwareAcceleration = true;
+ settings.MaxFrameBufferSize = 15;
+ settings.EnableZeroCopyDecoding = true;
+
+ // Apply quality preset
+ settings.ApplyPreset(VavCoreDecoderSettings.QualityPreset.Ultra);
+
+ // Save settings as resource
+ ResourceSaver.Save(settings, "user://vavcore_settings.tres");
+
+ // Load settings
+ var loadedSettings = GD.Load("user://vavcore_settings.tres");
+ }
+}
+```
+
+### **Video File Metadata**
+
+```csharp
+using VavCore.Godot.Resources;
+
+public partial class VideoMetadata : Control
+{
+ public override void _Ready()
+ {
+ // Create video file resource
+ var videoFile = new VavCoreVideoFile("res://videos/sample.webm");
+
+ if (videoFile.IsValid)
+ {
+ // Access metadata
+ GD.Print($"Resolution: {videoFile.VideoWidth}x{videoFile.VideoHeight}");
+ GD.Print($"Duration: {videoFile.DurationSeconds:F2} seconds");
+ GD.Print($"Frame rate: {videoFile.FrameRate:F2} FPS");
+ GD.Print($"Codec: {videoFile.CodecType}");
+ GD.Print($"File size: {videoFile.GetFormattedFileSize()}");
+
+ // Get detailed info
+ var info = videoFile.GetVideoInfo();
+ foreach (var key in info.Keys)
+ {
+ GD.Print($"{key}: {info[key]}");
+ }
+
+ // Check decoder compatibility
+ var compatibleDecoders = videoFile.GetCompatibleDecoders();
+ GD.Print($"Compatible decoders: {string.Join(", ", compatibleDecoders)}");
+
+ var recommendedDecoder = videoFile.GetRecommendedDecoder();
+ GD.Print($"Recommended decoder: {recommendedDecoder}");
+ }
+ else
+ {
+ GD.PrintErr($"Invalid video file: {videoFile.ErrorMessage}");
+ }
+ }
+}
+```
+
+## 🔧 **Configuration**
+
+### **Decoder Settings Presets**
+
+```csharp
+// Ultra Quality (High-end systems)
+settings.ApplyPreset(VavCoreDecoderSettings.QualityPreset.Ultra);
+
+// High Quality (Gaming systems)
+settings.ApplyPreset(VavCoreDecoderSettings.QualityPreset.High);
+
+// Balanced (Most systems)
+settings.ApplyPreset(VavCoreDecoderSettings.QualityPreset.Balanced);
+
+// Performance (Lower-end systems)
+settings.ApplyPreset(VavCoreDecoderSettings.QualityPreset.Performance);
+
+// Power Saver (Mobile/battery)
+settings.ApplyPreset(VavCoreDecoderSettings.QualityPreset.PowerSaver);
+```
+
+### **Platform-Specific Optimization**
+
+```csharp
+// Get platform information
+var platformInfo = VavCoreGodotUtils.GetPlatformInfo();
+GD.Print($"Platform: {platformInfo["platform"]}");
+GD.Print($"Optimal decoder: {platformInfo["optimal_decoder"]}");
+GD.Print($"Hardware acceleration: {platformInfo["hardware_acceleration"]}");
+
+// Check hardware acceleration support
+bool hwSupported = VavCoreGodotUtils.IsHardwareAccelerationSupported();
+string perfCategory = VavCoreGodotUtils.GetPerformanceCategory();
+string optimalAPI = VavCoreGodotUtils.GetOptimalGraphicsAPI();
+
+// Validate video file
+var (isValid, errorMessage) = VavCoreGodotUtils.ValidateVideoFile("path/to/video.webm");
+```
+
+## 📊 **Performance Monitoring**
+
+```csharp
+// Get performance statistics
+var stats = videoPlayer.GetPerformanceStats();
+GD.Print($"Frames decoded: {stats["frames_decoded"]}");
+GD.Print($"Frames dropped: {stats["frames_dropped"]}");
+GD.Print($"Average decode time: {stats["avg_decode_time_ms"]} ms");
+
+// Format stats for display
+string formattedStats = VavCoreGodotUtils.FormatPerformanceStats(stats);
+GD.Print(formattedStats);
+
+// Monitor hardware capabilities
+var capabilities = videoPlayer.GetHardwareCapabilities();
+GD.Print($"Hardware acceleration: {capabilities["hardware_acceleration"]}");
+GD.Print($"Zero-copy decoding: {capabilities["zero_copy_decoding"]}");
+```
+
+## 🐛 **Troubleshooting**
+
+### **Common Issues**
+
+1. **VavCore library not found**
+ ```
+ Error: Could not load VavCore.dll/libVavCore.so
+ Solution: Ensure native libraries are in the correct path
+ ```
+
+2. **Hardware acceleration not available**
+ ```
+ Check: VavCoreGodotUtils.IsHardwareAccelerationSupported()
+ Solution: Use software decoder fallback
+ ```
+
+3. **Video file not supported**
+ ```
+ Check: VavCoreVideoFile.IsFormatSupported(filePath)
+ Solution: Convert to WebM/MKV with AV1 codec
+ ```
+
+### **Debug Information**
+
+```csharp
+// Log comprehensive system information
+VavCoreGodotUtils.LogSystemInfo();
+
+// Create detailed system report
+var systemReport = VavCoreGodotUtils.CreateSystemReport();
+
+// Check video file validation
+var (isValid, error) = VavCoreGodotUtils.ValidateVideoFile(videoPath);
+```
+
+## 🎯 **Next Steps**
+
+1. **Audio Support**: Future integration with VavCore audio decoding
+2. **Streaming**: Network video streaming support
+3. **GPU Integration**: Direct GPU surface rendering optimization
+4. **Mobile Optimization**: Enhanced Android/iOS performance
+
+---
+
+🎮 **Cross-platform AV1 video decoding made easy for Godot 4.x!**
+⚡ **Hardware acceleration with software fallback for maximum compatibility!**
\ No newline at end of file
diff --git a/vav2/platforms/windows/godot-plugin/VavCoreGodot.sln b/vav2/platforms/windows/godot-plugin/VavCoreGodot.sln
new file mode 100644
index 0000000..a8a97a4
--- /dev/null
+++ b/vav2/platforms/windows/godot-plugin/VavCoreGodot.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31903.59
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VavCore.Wrapper", "src\VavCore.Wrapper\VavCore.Wrapper.csproj", "{A1B2C3D4-E5F6-7890-ABCD-123456789ABC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VavCore.Godot", "src\VavCore.Godot\VavCore.Godot.csproj", "{B2C3D4E5-F6A7-8901-BCDE-234567890BCD}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A1B2C3D4-E5F6-7890-ABCD-123456789ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {A1B2C3D4-E5F6-7890-ABCD-123456789ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {A1B2C3D4-E5F6-7890-ABCD-123456789ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {A1B2C3D4-E5F6-7890-ABCD-123456789ABC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B2C3D4E5-F6A7-8901-BCDE-234567890BCD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B2C3D4E5-F6A7-8901-BCDE-234567890BCD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B2C3D4E5-F6A7-8901-BCDE-234567890BCD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B2C3D4E5-F6A7-8901-BCDE-234567890BCD}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {C3D4E5F6-A7B8-9012-CDEF-345678901CDE}
+ EndGlobalSection
+EndGlobal
\ No newline at end of file
diff --git a/vav2/platforms/windows/godot-plugin/build.bat b/vav2/platforms/windows/godot-plugin/build.bat
new file mode 100644
index 0000000..6100e8d
--- /dev/null
+++ b/vav2/platforms/windows/godot-plugin/build.bat
@@ -0,0 +1,26 @@
+@echo off
+REM Godot Extension Build Script
+
+echo [BUILD] Building Godot extension...
+
+set BUILD_CONFIG=%1
+if "%BUILD_CONFIG%"=="" set BUILD_CONFIG=Debug
+
+echo Configuration: %BUILD_CONFIG%
+
+echo [BUILD] Building VavCore.Wrapper...
+dotnet build src\VavCore.Wrapper\VavCore.Wrapper.csproj -c %BUILD_CONFIG%
+if errorlevel 1 (
+ echo [ERROR] VavCore.Wrapper build failed!
+ exit /b 1
+)
+
+echo [BUILD] Building VavCore.Godot...
+dotnet build src\VavCore.Godot\VavCore.Godot.csproj -c %BUILD_CONFIG%
+if errorlevel 1 (
+ echo [ERROR] VavCore.Godot build failed!
+ exit /b 1
+)
+
+echo [SUCCESS] Godot extension built successfully
+echo Output: bin\%BUILD_CONFIG%\
\ No newline at end of file
diff --git a/vav2/platforms/windows/godot-plugin/src/VavCore.Godot/VavCore.Godot.csproj b/vav2/platforms/windows/godot-plugin/src/VavCore.Godot/VavCore.Godot.csproj
new file mode 100644
index 0000000..2f5dbe3
--- /dev/null
+++ b/vav2/platforms/windows/godot-plugin/src/VavCore.Godot/VavCore.Godot.csproj
@@ -0,0 +1,58 @@
+
+
+
+ net8.0
+ 11
+ enable
+ enable
+ true
+
+
+ VavCore Godot Extension
+ High-level Godot 4.x extension for VavCore AV1 decoder with managed nodes and resources
+ 1.0.0.0
+ 1.0.0.0
+ VavCore Team
+ VavCore Godot Extension
+ Copyright © 2024 VavCore Team
+
+
+
+ DEBUG;TRACE;GODOT
+ full
+ true
+
+
+
+ TRACE;GODOT
+ true
+ portable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ bin\$(Configuration)\$(TargetFramework)\VavCore.Godot.xml
+
+
+
\ No newline at end of file
diff --git a/vav2/platforms/windows/godot-plugin/src/VavCore.Godot/VavCorePlayer.cs b/vav2/platforms/windows/godot-plugin/src/VavCore.Godot/VavCorePlayer.cs
new file mode 100644
index 0000000..e4e5903
--- /dev/null
+++ b/vav2/platforms/windows/godot-plugin/src/VavCore.Godot/VavCorePlayer.cs
@@ -0,0 +1,1177 @@
+using Godot;
+using VavCore.Wrapper;
+using VavCoreClass = VavCore.Wrapper.VavCore;
+
+namespace VavCore.Godot;
+
+///
+/// Simple VavCore video player for Godot 4.x
+/// Direct VavCore API exposure with minimal overhead
+///
+[GlobalClass]
+public partial class VavCorePlayer : Control
+{
+ // ================================================
+ // Exported Properties
+ // ================================================
+
+ [Export] public string VideoPath { get; set; } = "";
+ [Export] public bool AutoPlay { get; set; } = false;
+ [Export] public bool Loop { get; set; } = false;
+ [Export] public bool UseGPUDecoding { get; set; } = true; // Default to GPU
+
+ // ================================================
+ // Public API - Direct VavCore Access
+ // ================================================
+
+ public VavCoreClass Core { get; private set; } = new();
+ public bool IsPlaying { get; private set; } = false;
+ public bool IsLoaded => Core?.IsOpen ?? false;
+
+ // GPU rendering components
+ private RenderingDevice _renderingDevice;
+ private Rid _yTextureRid;
+ private Rid _uvTextureRid;
+ private ShaderMaterial _videoMaterial;
+ private TextureRect _videoDisplay;
+
+ // ================================================
+ // Simple Video Control
+ // ================================================
+
+ public override void _Ready()
+ {
+ // Test VavCore DLL connection first
+ TestVavCoreDLLConnection();
+
+ // Initialize VavCore
+ if (!VavCoreClass.Initialize())
+ {
+ GD.PrintErr("VavCorePlayer: Failed to initialize VavCore");
+ return;
+ }
+
+ // Initialize GPU rendering if enabled
+ if (UseGPUDecoding)
+ {
+ InitializeGPURendering();
+ }
+
+ // Auto-load and play
+ if (!string.IsNullOrEmpty(VideoPath))
+ {
+ LoadVideo(VideoPath);
+ if (AutoPlay) Play();
+ }
+ }
+
+ // ================================================
+ // VavCore DLL Connection Test
+ // ================================================
+
+ private void TestVavCoreDLLConnection()
+ {
+ try
+ {
+ GD.Print("VavCorePlayer: Testing VavCore DLL connection...");
+
+ // Test 1: Version string
+ var version = VavCoreClass.GetVersion();
+ GD.Print($"VavCorePlayer: VavCore version: {version}");
+
+ // Test 2: Optimal decoder type
+ var optimalDecoder = VavCoreClass.GetOptimalDecoderType();
+ GD.Print($"VavCorePlayer: Optimal decoder type: {optimalDecoder}");
+
+ // Test 3: Initialize/Cleanup test
+ bool initResult = VavCoreClass.Initialize();
+ GD.Print($"VavCorePlayer: VavCore initialization: {(initResult ? "SUCCESS" : "FAILED")}");
+
+ if (initResult)
+ {
+ // Test 4: Create/Destroy player test
+ var testCore = new VavCoreClass();
+ GD.Print($"VavCorePlayer: Test player created successfully");
+
+ testCore.Dispose();
+ GD.Print($"VavCorePlayer: Test player disposed successfully");
+ }
+
+ GD.Print("VavCorePlayer: VavCore DLL connection test completed successfully!");
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: VavCore DLL connection test FAILED: {ex.Message}");
+ GD.PrintErr($"VavCorePlayer: Exception type: {ex.GetType().Name}");
+ GD.PrintErr($"VavCorePlayer: Stack trace: {ex.StackTrace}");
+ }
+ }
+
+ public bool LoadVideo(string path)
+ {
+ if (Core?.OpenFile(path) == true)
+ {
+ VideoPath = path;
+ GD.Print($"VavCorePlayer: Loaded {path}");
+ return true;
+ }
+ return false;
+ }
+
+ public void Play()
+ {
+ if (IsLoaded && !IsPlaying)
+ {
+ IsPlaying = true;
+ GD.Print("VavCorePlayer: Playing");
+ }
+ }
+
+ public void Stop()
+ {
+ IsPlaying = false;
+ Core?.Reset();
+ GD.Print("VavCorePlayer: Stopped");
+ }
+
+ // ================================================
+ // Frame Processing (CPU fallback + GPU surface options)
+ // ================================================
+
+ public override void _Process(double delta)
+ {
+ if (IsPlaying && Core != null)
+ {
+ bool frameDecoded = false;
+
+ if (UseGPUDecoding)
+ {
+ // GPU surface decode (default)
+ frameDecoded = DecodeToGPUSurface();
+ }
+ else
+ {
+ // CPU fallback for low-end devices
+ if (Core.DecodeNextFrame(out var frame))
+ {
+ frameDecoded = ConvertFrameAndDisplay(frame);
+ }
+ }
+
+ if (!frameDecoded)
+ {
+ // End of video
+ if (Loop)
+ Core.Reset();
+ else
+ Stop();
+ }
+ }
+ }
+
+ // ================================================
+ // Direct VavCore API Access
+ // ================================================
+
+ public bool SeekToTime(double seconds) => Core?.SeekToTime(seconds) ?? false;
+ public bool SeekToFrame(ulong frame) => Core?.SeekToFrame(frame) ?? false;
+ public Dictionary GetVideoInfo()
+ {
+ var info = new Dictionary();
+ var coreInfo = Core?.GetVideoInfo();
+ if (coreInfo != null)
+ {
+ foreach (var kvp in coreInfo)
+ info[kvp.Key] = Variant.From(kvp.Value);
+ }
+ return info;
+ }
+
+ // ================================================
+ // GPU Rendering Implementation
+ // ================================================
+
+ private void InitializeGPURendering()
+ {
+ try
+ {
+ _renderingDevice = RenderingServer.CreateLocalRenderingDevice();
+ if (_renderingDevice == null)
+ {
+ GD.PrintErr("VavCorePlayer: Failed to create RenderingDevice, falling back to CPU");
+ UseGPUDecoding = false;
+ return;
+ }
+
+ // Create video display TextureRect
+ _videoDisplay = new TextureRect();
+ _videoDisplay.ExpandMode = TextureRect.ExpandModeEnum.FitWidthProportional;
+ AddChild(_videoDisplay);
+
+ // Create YUV to RGB shader material
+ CreateYUVShader();
+
+ GD.Print("VavCorePlayer: GPU rendering initialized");
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: GPU initialization failed: {ex.Message}");
+ UseGPUDecoding = false;
+ }
+ }
+
+ private void CreateYUVShader()
+ {
+ var shader = new Shader();
+ shader.Code = """
+shader_type canvas_item;
+
+uniform sampler2D y_texture : source_color;
+uniform sampler2D uv_texture : source_color;
+
+void fragment() {
+ float y = texture(y_texture, UV).r;
+ vec2 chroma = texture(uv_texture, UV).rg;
+ float u = chroma.r - 0.5;
+ float v = chroma.g - 0.5;
+
+ // BT.709 YUV to RGB conversion
+ COLOR.r = y + 1.5748 * v;
+ COLOR.g = y - 0.1873 * u - 0.4681 * v;
+ COLOR.b = y + 1.8556 * u;
+ COLOR.a = 1.0;
+}
+""";
+
+ _videoMaterial = new ShaderMaterial();
+ _videoMaterial.Shader = shader;
+ _videoDisplay.Material = _videoMaterial;
+ }
+
+ private bool DecodeToGPUSurface()
+ {
+ if (_renderingDevice == null || Core == null)
+ return false;
+
+ try
+ {
+ // Get optimal surface type for current platform
+ var surfaceType = GetOptimalSurfaceType();
+
+ // Create GPU surface handles based on surface type
+ if (CreateGPUSurfaceHandles(surfaceType, out var ySurface, out var uvSurface))
+ {
+ if (Core.DecodeToSurface(surfaceType, ySurface, out var surfaceFrame))
+ {
+ // Update GPU textures with decoded surface data
+ return UpdateGPUTextures(surfaceFrame, ySurface, uvSurface);
+ }
+ }
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: GPU decode failed: {ex.Message}");
+ // Fallback to CPU decode
+ UseGPUDecoding = false;
+ }
+
+ return false;
+ }
+
+ private VavCoreClass.SurfaceType GetOptimalSurfaceType()
+ {
+ // Determine optimal surface type based on Godot rendering backend
+ var renderingMethod = ProjectSettings.GetSetting("rendering/renderer/rendering_method").AsString();
+
+ return renderingMethod switch
+ {
+ "forward_plus" => VavCoreClass.SurfaceType.VulkanImage,
+ "mobile" => VavCoreClass.SurfaceType.VulkanImage,
+ "gl_compatibility" => VavCoreClass.SurfaceType.OpenGLTexture,
+ _ => VavCoreClass.SurfaceType.VulkanImage
+ };
+ }
+
+ private bool CreateGPUSurfaceHandles(VavCoreClass.SurfaceType surfaceType, out IntPtr ySurface, out IntPtr uvSurface)
+ {
+ ySurface = IntPtr.Zero;
+ uvSurface = IntPtr.Zero;
+
+ try
+ {
+ // Get video metadata for texture dimensions
+ if (!Core.GetMetadata(out var metadata))
+ {
+ GD.PrintErr("VavCorePlayer: Failed to get video metadata");
+ return false;
+ }
+
+ switch (surfaceType)
+ {
+ case VavCoreClass.SurfaceType.VulkanImage:
+ return CreateVulkanSurfaces(metadata.Width, metadata.Height, out ySurface, out uvSurface);
+
+ case VavCoreClass.SurfaceType.OpenGLTexture:
+ case VavCoreClass.SurfaceType.OpenGLESTexture:
+ return CreateOpenGLSurfaces(metadata.Width, metadata.Height, out ySurface, out uvSurface);
+
+ default:
+ GD.PrintErr($"VavCorePlayer: Unsupported surface type: {surfaceType}");
+ return false;
+ }
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Failed to create GPU surfaces: {ex.Message}");
+ return false;
+ }
+ }
+
+ private bool CreateVulkanSurfaces(int width, int height, out IntPtr ySurface, out IntPtr uvSurface)
+ {
+ ySurface = IntPtr.Zero;
+ uvSurface = IntPtr.Zero;
+
+ try
+ {
+ // Create Y texture (luminance - full resolution) using RenderingDevice
+ var yFormat = new RDTextureFormat();
+ yFormat.Width = (uint)width;
+ yFormat.Height = (uint)height;
+ yFormat.Depth = 1;
+ yFormat.ArrayLayers = 1;
+ yFormat.Mipmaps = 1;
+ yFormat.Format = RenderingDevice.DataFormat.R8Unorm;
+ yFormat.UsageBits = RenderingDevice.TextureUsageBits.SamplingBit |
+ RenderingDevice.TextureUsageBits.CanUpdateBit;
+
+ var yView = new RDTextureView();
+ _yTextureRid = _renderingDevice.TextureCreate(yFormat, yView);
+
+ // Create UV texture (chrominance - half resolution for 420 format)
+ var uvFormat = new RDTextureFormat();
+ uvFormat.Width = (uint)(width / 2);
+ uvFormat.Height = (uint)(height / 2);
+ uvFormat.Depth = 1;
+ uvFormat.ArrayLayers = 1;
+ uvFormat.Mipmaps = 1;
+ uvFormat.Format = RenderingDevice.DataFormat.R8G8Unorm;
+ uvFormat.UsageBits = RenderingDevice.TextureUsageBits.SamplingBit |
+ RenderingDevice.TextureUsageBits.CanUpdateBit;
+
+ var uvView = new RDTextureView();
+ _uvTextureRid = _renderingDevice.TextureCreate(uvFormat, uvView);
+
+ // Get native handles (platform-specific implementation needed)
+ ySurface = GetNativeTextureHandle(_yTextureRid);
+ uvSurface = GetNativeTextureHandle(_uvTextureRid);
+
+ return ySurface != IntPtr.Zero && uvSurface != IntPtr.Zero;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Failed to create Vulkan surfaces: {ex.Message}");
+ return false;
+ }
+ }
+
+ private bool CreateOpenGLSurfaces(int width, int height, out IntPtr ySurface, out IntPtr uvSurface)
+ {
+ ySurface = IntPtr.Zero;
+ uvSurface = IntPtr.Zero;
+
+ // For OpenGL, we'll need to use different approach
+ // This is a simplified implementation
+ GD.Print("VavCorePlayer: OpenGL surface creation not fully implemented");
+ return false;
+ }
+
+ private IntPtr GetNativeTextureHandle(Rid textureRid)
+ {
+ // This would require platform-specific implementation
+ // For now, return the RID as IntPtr (placeholder)
+ return new IntPtr((long)textureRid.Id);
+ }
+
+ private bool UpdateGPUTextures(VavCoreClass.VideoFrameSurface surfaceFrame, IntPtr ySurface, IntPtr uvSurface)
+ {
+ try
+ {
+ if (_yTextureRid.IsValid && _uvTextureRid.IsValid && _videoMaterial != null)
+ {
+ // Update GPU textures with actual surface data from VavCore
+ if (surfaceFrame.YSurface != IntPtr.Zero && surfaceFrame.UVSurface != IntPtr.Zero)
+ {
+ // Method 1: Direct GPU surface binding (ideal for zero-copy)
+ if (UpdateTexturesFromGPUSurfaces(surfaceFrame))
+ {
+ GD.Print("VavCorePlayer: GPU textures updated from surfaces");
+ return true;
+ }
+ }
+
+ // Method 2: Fallback - update textures with new RIDs if available
+ if (UpdateTexturesFromRenderingDevice())
+ {
+ GD.Print("VavCorePlayer: GPU textures updated from RenderingDevice");
+ return true;
+ }
+
+ GD.Print("VavCorePlayer: Using placeholder textures");
+ return false;
+ }
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Failed to update GPU textures: {ex.Message}");
+ }
+
+ return false;
+ }
+
+ private bool UpdateTexturesFromGPUSurfaces(VavCoreClass.VideoFrameSurface surfaceFrame)
+ {
+ try
+ {
+ // Zero-copy GPU surface binding based on platform
+ switch (surfaceFrame.SurfaceType)
+ {
+ case VavCoreClass.SurfaceType.VulkanImage:
+ return UpdateVulkanSurfaceTextures(surfaceFrame);
+
+ case VavCoreClass.SurfaceType.OpenGLTexture:
+ case VavCoreClass.SurfaceType.OpenGLESTexture:
+ return UpdateOpenGLSurfaceTextures(surfaceFrame);
+
+ case VavCoreClass.SurfaceType.D3D11Texture:
+ return UpdateD3D11SurfaceTextures(surfaceFrame);
+
+ case VavCoreClass.SurfaceType.MetalTexture:
+ return UpdateMetalSurfaceTextures(surfaceFrame);
+
+ default:
+ GD.PrintErr($"VavCorePlayer: Unsupported surface type for zero-copy: {surfaceFrame.SurfaceType}");
+ return false;
+ }
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: GPU surface binding failed: {ex.Message}");
+ return false;
+ }
+ }
+
+ private bool UpdateTexturesFromRenderingDevice()
+ {
+ try
+ {
+ if (_renderingDevice == null || !_yTextureRid.IsValid || !_uvTextureRid.IsValid)
+ {
+ GD.PrintErr("VavCorePlayer: RenderingDevice or texture RIDs not available");
+ return false;
+ }
+
+ // Method 1: Update RenderingDevice textures with actual frame data
+ if (UpdateRenderingDeviceTextures())
+ {
+ // Convert RenderingDevice textures to Texture2D for shader binding
+ var yTexture2D = CreateTexture2DFromRenderingDevice(_yTextureRid);
+ var uvTexture2D = CreateTexture2DFromRenderingDevice(_uvTextureRid);
+
+ if (yTexture2D != null && uvTexture2D != null)
+ {
+ _videoMaterial.SetShaderParameter("y_texture", yTexture2D);
+ _videoMaterial.SetShaderParameter("uv_texture", uvTexture2D);
+
+ GD.Print("VavCorePlayer: RenderingDevice textures updated successfully");
+ return true;
+ }
+ }
+
+ // Method 2: Fallback to ImageTexture creation with CPU data
+ return CreateFallbackImageTextures();
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Failed to update from RenderingDevice: {ex.Message}");
+ return false;
+ }
+ }
+
+ private bool UpdateRenderingDeviceTextures()
+ {
+ try
+ {
+ // Update RenderingDevice textures with GPU surface data
+ // This requires actual YUV frame data from VavCore
+
+ // Get video metadata for texture dimensions
+ if (!Core.GetMetadata(out var metadata))
+ {
+ GD.PrintErr("VavCorePlayer: Failed to get video metadata for texture update");
+ return false;
+ }
+
+ // Create buffer data for texture update (placeholder implementation)
+ // In real implementation, this would come from VavCore surface data
+ byte[] yData = CreatePlaceholderYData(metadata.Width, metadata.Height);
+ byte[] uvData = CreatePlaceholderUVData(metadata.Width / 2, metadata.Height / 2);
+
+ // Update Y texture
+ if (!UpdateTextureData(_yTextureRid, yData, metadata.Width, metadata.Height, 1))
+ {
+ GD.PrintErr("VavCorePlayer: Failed to update Y texture data");
+ return false;
+ }
+
+ // Update UV texture
+ if (!UpdateTextureData(_uvTextureRid, uvData, metadata.Width / 2, metadata.Height / 2, 2))
+ {
+ GD.PrintErr("VavCorePlayer: Failed to update UV texture data");
+ return false;
+ }
+
+ return true;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Failed to update RenderingDevice textures: {ex.Message}");
+ return false;
+ }
+ }
+
+ private bool UpdateTextureData(Rid textureRid, byte[] data, int width, int height, int channels)
+ {
+ try
+ {
+ // Update RenderingDevice texture with raw data
+ // This uses RenderingDevice.TextureUpdate() method
+ _renderingDevice.TextureUpdate(textureRid, 0, data);
+
+ GD.Print($"VavCorePlayer: Updated texture {textureRid} ({width}x{height}, {channels} channels, {data.Length} bytes)");
+ return true;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Failed to update texture data: {ex.Message}");
+ return false;
+ }
+ }
+
+ private Texture2D CreateTexture2DFromRenderingDevice(Rid textureRid)
+ {
+ try
+ {
+ // Create Texture2D from RenderingDevice RID
+ // This bridges low-level RenderingDevice to high-level Texture2D
+
+ // For now, create ImageTexture as placeholder
+ // Real implementation would convert RID to Texture2D
+ var texture = new ImageTexture();
+
+ // Note: Godot 4.4 may have RID → Texture2D conversion methods
+ // texture.CreateFromRenderingDeviceTexture(_renderingDevice, textureRid);
+
+ return texture;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Failed to create Texture2D from RID: {ex.Message}");
+ return null;
+ }
+ }
+
+ private bool CreateFallbackImageTextures()
+ {
+ try
+ {
+ // Fallback method: Create ImageTextures with CPU-generated data
+ // This ensures something is displayed even if GPU surface binding fails
+
+ if (!Core.GetMetadata(out var metadata))
+ {
+ return false;
+ }
+
+ // Create Y texture (luminance)
+ var yImage = Image.CreateEmpty(metadata.Width, metadata.Height, false, Image.Format.R8);
+ byte[] yData = CreatePlaceholderYData(metadata.Width, metadata.Height);
+ yImage.SetData(metadata.Width, metadata.Height, false, Image.Format.R8, yData);
+
+ var yTexture = ImageTexture.CreateFromImage(yImage);
+
+ // Create UV texture (chrominance)
+ var uvImage = Image.CreateEmpty(metadata.Width / 2, metadata.Height / 2, false, Image.Format.Rg8);
+ byte[] uvData = CreatePlaceholderUVData(metadata.Width / 2, metadata.Height / 2);
+ uvImage.SetData(metadata.Width / 2, metadata.Height / 2, false, Image.Format.Rg8, uvData);
+
+ var uvTexture = ImageTexture.CreateFromImage(uvImage);
+
+ // Bind to shader
+ _videoMaterial.SetShaderParameter("y_texture", yTexture);
+ _videoMaterial.SetShaderParameter("uv_texture", uvTexture);
+
+ GD.Print("VavCorePlayer: Created fallback ImageTextures");
+ return true;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Failed to create fallback textures: {ex.Message}");
+ return false;
+ }
+ }
+
+ private byte[] CreatePlaceholderYData(int width, int height)
+ {
+ // Create placeholder Y (luminance) data
+ // This generates a gradient pattern for testing
+ byte[] data = new byte[width * height];
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ // Simple gradient pattern
+ data[y * width + x] = (byte)((x + y) % 256);
+ }
+ }
+ return data;
+ }
+
+ private byte[] CreatePlaceholderUVData(int width, int height)
+ {
+ // Create placeholder UV (chrominance) data
+ // This generates a color pattern for testing
+ byte[] data = new byte[width * height * 2]; // 2 channels (U, V)
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ int index = (y * width + x) * 2;
+ data[index] = (byte)(128 + (x % 128)); // U channel
+ data[index + 1] = (byte)(128 + (y % 128)); // V channel
+ }
+ }
+ return data;
+ }
+
+ // ================================================
+ // Platform-Specific GPU Surface Binding Methods
+ // ================================================
+
+ private bool UpdateVulkanSurfaceTextures(VavCoreClass.VideoFrameSurface surfaceFrame)
+ {
+ try
+ {
+ if (_renderingDevice == null || !_yTextureRid.IsValid || !_uvTextureRid.IsValid)
+ return false;
+
+ // Vulkan zero-copy surface binding
+ // Direct Vulkan surface handles from VavCore to Godot RenderingDevice
+ if (surfaceFrame.YSurface != IntPtr.Zero && surfaceFrame.UVSurface != IntPtr.Zero)
+ {
+ // Import external Vulkan surfaces into RenderingDevice
+ // This requires Godot 4.4's RenderingDevice.TextureCreateFromNative() method
+ var yTextureFromSurface = ImportVulkanSurface(surfaceFrame.YSurface,
+ RenderingDevice.DataFormat.R8Unorm, surfaceFrame.Width, surfaceFrame.Height);
+ var uvTextureFromSurface = ImportVulkanSurface(surfaceFrame.UVSurface,
+ RenderingDevice.DataFormat.R8G8Unorm, surfaceFrame.Width / 2, surfaceFrame.Height / 2);
+
+ if (yTextureFromSurface.IsValid && uvTextureFromSurface.IsValid)
+ {
+ // Update shader parameters with zero-copy textures
+ var yTexture2D = CreateTexture2DFromRID(yTextureFromSurface);
+ var uvTexture2D = CreateTexture2DFromRID(uvTextureFromSurface);
+
+ _videoMaterial.SetShaderParameter("y_texture", yTexture2D);
+ _videoMaterial.SetShaderParameter("uv_texture", uvTexture2D);
+
+ GD.Print("VavCorePlayer: Vulkan zero-copy surface binding successful");
+ return true;
+ }
+ }
+
+ GD.Print("VavCorePlayer: Vulkan surface binding failed, falling back");
+ return false;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Vulkan surface update failed: {ex.Message}");
+ return false;
+ }
+ }
+
+ private bool UpdateOpenGLSurfaceTextures(VavCoreClass.VideoFrameSurface surfaceFrame)
+ {
+ try
+ {
+ // OpenGL texture zero-copy binding
+ // Use glTexSubImage2D to update existing textures with VavCore surface data
+ if (surfaceFrame.YSurface != IntPtr.Zero && surfaceFrame.UVSurface != IntPtr.Zero)
+ {
+ // Extract OpenGL texture IDs from VavCore surfaces
+ var yTextureId = ExtractOpenGLTextureId(surfaceFrame.YSurface);
+ var uvTextureId = ExtractOpenGLTextureId(surfaceFrame.UVSurface);
+
+ if (yTextureId > 0 && uvTextureId > 0)
+ {
+ // Import OpenGL textures into Godot RenderingDevice
+ var yTexture2D = CreateTexture2DFromOpenGLId(yTextureId);
+ var uvTexture2D = CreateTexture2DFromOpenGLId(uvTextureId);
+
+ _videoMaterial.SetShaderParameter("y_texture", yTexture2D);
+ _videoMaterial.SetShaderParameter("uv_texture", uvTexture2D);
+
+ GD.Print("VavCorePlayer: OpenGL zero-copy surface binding successful");
+ return true;
+ }
+ }
+
+ GD.Print("VavCorePlayer: OpenGL surface binding not yet fully implemented");
+ return false;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: OpenGL surface update failed: {ex.Message}");
+ return false;
+ }
+ }
+
+ private bool UpdateD3D11SurfaceTextures(VavCoreClass.VideoFrameSurface surfaceFrame)
+ {
+ try
+ {
+ // D3D11 texture zero-copy binding for Windows
+ // Direct ID3D11Texture2D surface sharing with Godot
+ if (surfaceFrame.YSurface != IntPtr.Zero && surfaceFrame.UVSurface != IntPtr.Zero)
+ {
+ // Windows-specific D3D11 texture sharing
+ // This requires interop with Godot's D3D11 device
+ var yD3DTexture = ConvertIntPtrToD3D11Texture(surfaceFrame.YSurface);
+ var uvD3DTexture = ConvertIntPtrToD3D11Texture(surfaceFrame.UVSurface);
+
+ if (yD3DTexture != IntPtr.Zero && uvD3DTexture != IntPtr.Zero)
+ {
+ // Create Godot textures from D3D11 shared resources
+ var yTexture2D = CreateTexture2DFromD3D11(yD3DTexture);
+ var uvTexture2D = CreateTexture2DFromD3D11(uvD3DTexture);
+
+ _videoMaterial.SetShaderParameter("y_texture", yTexture2D);
+ _videoMaterial.SetShaderParameter("uv_texture", uvTexture2D);
+
+ GD.Print("VavCorePlayer: D3D11 zero-copy surface binding successful");
+ return true;
+ }
+ }
+
+ GD.Print("VavCorePlayer: D3D11 surface binding not yet fully implemented");
+ return false;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: D3D11 surface update failed: {ex.Message}");
+ return false;
+ }
+ }
+
+ private bool UpdateMetalSurfaceTextures(VavCoreClass.VideoFrameSurface surfaceFrame)
+ {
+ try
+ {
+ // Metal texture zero-copy binding for macOS/iOS
+ // Direct MTLTexture surface sharing with Godot
+ if (surfaceFrame.YSurface != IntPtr.Zero && surfaceFrame.UVSurface != IntPtr.Zero)
+ {
+ // macOS/iOS-specific Metal texture sharing
+ var yMetalTexture = ConvertIntPtrToMetalTexture(surfaceFrame.YSurface);
+ var uvMetalTexture = ConvertIntPtrToMetalTexture(surfaceFrame.UVSurface);
+
+ if (yMetalTexture != IntPtr.Zero && uvMetalTexture != IntPtr.Zero)
+ {
+ // Create Godot textures from Metal shared resources
+ var yTexture2D = CreateTexture2DFromMetal(yMetalTexture);
+ var uvTexture2D = CreateTexture2DFromMetal(uvMetalTexture);
+
+ _videoMaterial.SetShaderParameter("y_texture", yTexture2D);
+ _videoMaterial.SetShaderParameter("uv_texture", uvTexture2D);
+
+ GD.Print("VavCorePlayer: Metal zero-copy surface binding successful");
+ return true;
+ }
+ }
+
+ GD.Print("VavCorePlayer: Metal surface binding not yet fully implemented");
+ return false;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: Metal surface update failed: {ex.Message}");
+ return false;
+ }
+ }
+
+ // ================================================
+ // GPU Surface Helper Methods
+ // ================================================
+
+ private Rid ImportVulkanSurface(IntPtr vulkanSurface, RenderingDevice.DataFormat format, int width, int height)
+ {
+ // Import external Vulkan surface into RenderingDevice
+ // This would use Godot's TextureCreateFromNative API when available
+ GD.Print($"VavCorePlayer: Importing Vulkan surface {vulkanSurface} ({width}x{height})");
+ return new Rid(); // Placeholder - requires Godot 4.4+ native surface import
+ }
+
+ private Texture2D CreateTexture2DFromRID(Rid textureRid)
+ {
+ // Create Texture2D wrapper from RenderingDevice RID
+ // This bridges RenderingDevice low-level textures to high-level Texture2D
+ var texture = new ImageTexture();
+ // Note: Actual implementation would require RID → Texture2D conversion
+ return texture;
+ }
+
+ private uint ExtractOpenGLTextureId(IntPtr glSurface)
+ {
+ // Extract OpenGL texture ID from VavCore surface handle
+ // Platform-specific implementation to get GLuint from IntPtr
+ return (uint)glSurface.ToInt64(); // Simplified assumption
+ }
+
+ private Texture2D CreateTexture2DFromOpenGLId(uint textureId)
+ {
+ // Create Godot Texture2D from OpenGL texture ID
+ // This would use OpenGL texture sharing APIs
+ GD.Print($"VavCorePlayer: Creating Texture2D from OpenGL ID {textureId}");
+ return new ImageTexture(); // Placeholder
+ }
+
+ private IntPtr ConvertIntPtrToD3D11Texture(IntPtr d3dSurface)
+ {
+ // Convert VavCore D3D11 surface handle to ID3D11Texture2D*
+ return d3dSurface; // Direct pointer assumption
+ }
+
+ private Texture2D CreateTexture2DFromD3D11(IntPtr d3dTexture)
+ {
+ // Create Godot Texture2D from D3D11 texture
+ // This would use D3D11 shared resource APIs
+ GD.Print($"VavCorePlayer: Creating Texture2D from D3D11 texture {d3dTexture}");
+ return new ImageTexture(); // Placeholder
+ }
+
+ private IntPtr ConvertIntPtrToMetalTexture(IntPtr metalSurface)
+ {
+ // Convert VavCore Metal surface handle to MTLTexture
+ return metalSurface; // Direct pointer assumption
+ }
+
+ private Texture2D CreateTexture2DFromMetal(IntPtr metalTexture)
+ {
+ // Create Godot Texture2D from Metal texture
+ // This would use Metal shared resource APIs
+ GD.Print($"VavCorePlayer: Creating Texture2D from Metal texture {metalTexture}");
+ return new ImageTexture(); // Placeholder
+ }
+
+ private bool ConvertFrameAndDisplay(VavCoreClass.VideoFrame frame)
+ {
+ try
+ {
+ // CPU fallback implementation for low-end devices
+ GD.Print("VavCorePlayer: Using CPU fallback mode");
+
+ // Validate frame data
+ if (!ValidateVideoFrame(frame))
+ {
+ GD.PrintErr("VavCorePlayer: Invalid video frame data for CPU conversion");
+ return false;
+ }
+
+ // Method 1: Direct YUV to RGB conversion + ImageTexture
+ if (ConvertYUVToRGBImageTexture(frame))
+ {
+ GD.Print("VavCorePlayer: CPU YUV→RGB conversion successful");
+ return true;
+ }
+
+ // Method 2: Separate Y/UV ImageTextures (preserves YUV in shader)
+ if (CreateSeparateYUVImageTextures(frame))
+ {
+ GD.Print("VavCorePlayer: CPU YUV texture creation successful");
+ return true;
+ }
+
+ GD.PrintErr("VavCorePlayer: All CPU fallback methods failed");
+ return false;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: CPU fallback conversion failed: {ex.Message}");
+ return false;
+ }
+ }
+
+ // ================================================
+ // CPU Fallback Implementation Methods
+ // ================================================
+
+ private bool ValidateVideoFrame(VavCoreClass.VideoFrame frame)
+ {
+ // Validate frame dimensions
+ if (frame.Width <= 0 || frame.Height <= 0)
+ {
+ GD.PrintErr($"VavCorePlayer: Invalid frame dimensions: {frame.Width}x{frame.Height}");
+ return false;
+ }
+
+ // Validate YUV plane pointers
+ if (frame.YPlane == IntPtr.Zero || frame.UPlane == IntPtr.Zero || frame.VPlane == IntPtr.Zero)
+ {
+ GD.PrintErr("VavCorePlayer: Null YUV plane pointers");
+ return false;
+ }
+
+ // Validate strides
+ if (frame.YStride <= 0 || frame.UStride <= 0 || frame.VStride <= 0)
+ {
+ GD.PrintErr($"VavCorePlayer: Invalid YUV strides: Y={frame.YStride}, U={frame.UStride}, V={frame.VStride}");
+ return false;
+ }
+
+ GD.Print($"VavCorePlayer: Frame validation passed - {frame.Width}x{frame.Height}, Frame#{frame.FrameNumber}");
+ return true;
+ }
+
+ private bool ConvertYUVToRGBImageTexture(VavCoreClass.VideoFrame frame)
+ {
+ try
+ {
+ // Method 1: CPU YUV→RGB conversion then single RGB ImageTexture
+ GD.Print("VavCorePlayer: Starting CPU YUV→RGB conversion");
+
+ // Extract YUV data from frame
+ byte[] yData = ExtractYPlaneData(frame);
+ byte[] uData = ExtractUPlaneData(frame);
+ byte[] vData = ExtractVPlaneData(frame);
+
+ // Convert YUV to RGB
+ byte[] rgbData = ConvertYUVToRGB(yData, uData, vData, frame.Width, frame.Height);
+
+ // Create RGB ImageTexture
+ var rgbImage = Image.CreateEmpty(frame.Width, frame.Height, false, Image.Format.Rgb8);
+ rgbImage.SetData(frame.Width, frame.Height, false, Image.Format.Rgb8, rgbData);
+
+ var rgbTexture = ImageTexture.CreateFromImage(rgbImage);
+
+ // For RGB texture, we need a different shader or direct display
+ if (_videoDisplay != null)
+ {
+ _videoDisplay.Texture = rgbTexture;
+ GD.Print("VavCorePlayer: RGB texture applied directly to TextureRect");
+ return true;
+ }
+
+ return false;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: YUV→RGB conversion failed: {ex.Message}");
+ return false;
+ }
+ }
+
+ private bool CreateSeparateYUVImageTextures(VavCoreClass.VideoFrame frame)
+ {
+ try
+ {
+ // Method 2: Keep YUV separate and use existing YUV shader
+ GD.Print("VavCorePlayer: Creating separate YUV ImageTextures");
+
+ // Extract YUV plane data
+ byte[] yData = ExtractYPlaneData(frame);
+ byte[] uData = ExtractUPlaneData(frame);
+ byte[] vData = ExtractVPlaneData(frame);
+
+ // Create Y texture (luminance)
+ var yImage = Image.CreateEmpty(frame.Width, frame.Height, false, Image.Format.R8);
+ yImage.SetData(frame.Width, frame.Height, false, Image.Format.R8, yData);
+ var yTexture = ImageTexture.CreateFromImage(yImage);
+
+ // Create UV texture (chrominance) - combine U and V into RG format
+ int uvWidth = frame.Width / 2;
+ int uvHeight = frame.Height / 2;
+ byte[] uvData = CombineUVPlanes(uData, vData, uvWidth, uvHeight);
+
+ var uvImage = Image.CreateEmpty(uvWidth, uvHeight, false, Image.Format.Rg8);
+ uvImage.SetData(uvWidth, uvHeight, false, Image.Format.Rg8, uvData);
+ var uvTexture = ImageTexture.CreateFromImage(uvImage);
+
+ // Apply to existing YUV shader
+ if (_videoMaterial != null)
+ {
+ _videoMaterial.SetShaderParameter("y_texture", yTexture);
+ _videoMaterial.SetShaderParameter("uv_texture", uvTexture);
+ GD.Print("VavCorePlayer: YUV ImageTextures bound to shader");
+ return true;
+ }
+
+ GD.PrintErr("VavCorePlayer: Video material not available for YUV binding");
+ return false;
+ }
+ catch (System.Exception ex)
+ {
+ GD.PrintErr($"VavCorePlayer: YUV ImageTexture creation failed: {ex.Message}");
+ return false;
+ }
+ }
+
+ // ================================================
+ // YUV Data Extraction Methods
+ // ================================================
+
+ private byte[] ExtractYPlaneData(VavCoreClass.VideoFrame frame)
+ {
+ // Extract Y plane data from VideoFrame
+ int yDataSize = frame.Height * frame.YStride;
+ byte[] yData = new byte[frame.Width * frame.Height]; // Actual data without stride padding
+
+ unsafe
+ {
+ byte* yPtr = (byte*)frame.YPlane.ToPointer();
+ int destIndex = 0;
+
+ for (int y = 0; y < frame.Height; y++)
+ {
+ for (int x = 0; x < frame.Width; x++)
+ {
+ yData[destIndex++] = yPtr[y * frame.YStride + x];
+ }
+ }
+ }
+
+ GD.Print($"VavCorePlayer: Extracted Y plane: {yData.Length} bytes");
+ return yData;
+ }
+
+ private byte[] ExtractUPlaneData(VavCoreClass.VideoFrame frame)
+ {
+ // Extract U plane data (typically half width/height for 420 format)
+ int uWidth = frame.Width / 2;
+ int uHeight = frame.Height / 2;
+ byte[] uData = new byte[uWidth * uHeight];
+
+ unsafe
+ {
+ byte* uPtr = (byte*)frame.UPlane.ToPointer();
+ int destIndex = 0;
+
+ for (int y = 0; y < uHeight; y++)
+ {
+ for (int x = 0; x < uWidth; x++)
+ {
+ uData[destIndex++] = uPtr[y * frame.UStride + x];
+ }
+ }
+ }
+
+ GD.Print($"VavCorePlayer: Extracted U plane: {uData.Length} bytes");
+ return uData;
+ }
+
+ private byte[] ExtractVPlaneData(VavCoreClass.VideoFrame frame)
+ {
+ // Extract V plane data (typically half width/height for 420 format)
+ int vWidth = frame.Width / 2;
+ int vHeight = frame.Height / 2;
+ byte[] vData = new byte[vWidth * vHeight];
+
+ unsafe
+ {
+ byte* vPtr = (byte*)frame.VPlane.ToPointer();
+ int destIndex = 0;
+
+ for (int y = 0; y < vHeight; y++)
+ {
+ for (int x = 0; x < vWidth; x++)
+ {
+ vData[destIndex++] = vPtr[y * frame.VStride + x];
+ }
+ }
+ }
+
+ GD.Print($"VavCorePlayer: Extracted V plane: {vData.Length} bytes");
+ return vData;
+ }
+
+ // ================================================
+ // YUV to RGB Conversion
+ // ================================================
+
+ private byte[] ConvertYUVToRGB(byte[] yData, byte[] uData, byte[] vData, int width, int height)
+ {
+ // CPU YUV→RGB conversion using BT.709 standard (same as shader)
+ byte[] rgbData = new byte[width * height * 3]; // RGB format
+ int uvWidth = width / 2;
+ int uvHeight = height / 2;
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ // Get Y component
+ float yVal = yData[y * width + x] / 255.0f;
+
+ // Get UV components (subsample for 420 format)
+ int uvX = x / 2;
+ int uvY = y / 2;
+ int uvIndex = uvY * uvWidth + uvX;
+
+ float uVal = (uData[uvIndex] / 255.0f) - 0.5f;
+ float vVal = (vData[uvIndex] / 255.0f) - 0.5f;
+
+ // BT.709 YUV to RGB conversion (same coefficients as shader)
+ float r = yVal + 1.5748f * vVal;
+ float g = yVal - 0.1873f * uVal - 0.4681f * vVal;
+ float b = yVal + 1.8556f * uVal;
+
+ // Clamp to [0, 1] and convert to byte
+ int rgbIndex = (y * width + x) * 3;
+ rgbData[rgbIndex] = (byte)(Math.Clamp(r, 0.0f, 1.0f) * 255); // R
+ rgbData[rgbIndex + 1] = (byte)(Math.Clamp(g, 0.0f, 1.0f) * 255); // G
+ rgbData[rgbIndex + 2] = (byte)(Math.Clamp(b, 0.0f, 1.0f) * 255); // B
+ }
+ }
+
+ GD.Print($"VavCorePlayer: YUV→RGB conversion completed: {rgbData.Length} bytes");
+ return rgbData;
+ }
+
+ private byte[] CombineUVPlanes(byte[] uData, byte[] vData, int uvWidth, int uvHeight)
+ {
+ // Combine separate U and V planes into interleaved UV (RG format)
+ byte[] uvData = new byte[uvWidth * uvHeight * 2]; // 2 channels (U, V)
+
+ for (int i = 0; i < uvWidth * uvHeight; i++)
+ {
+ uvData[i * 2] = uData[i]; // U component
+ uvData[i * 2 + 1] = vData[i]; // V component
+ }
+
+ GD.Print($"VavCorePlayer: Combined UV planes: {uvData.Length} bytes");
+ return uvData;
+ }
+
+ // ================================================
+ // Cleanup
+ // ================================================
+
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ Stop();
+ Core?.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+}
\ No newline at end of file
diff --git a/vav2/platforms/windows/godot-plugin/src/VavCore.Wrapper/VavCore.Wrapper.csproj b/vav2/platforms/windows/godot-plugin/src/VavCore.Wrapper/VavCore.Wrapper.csproj
new file mode 100644
index 0000000..0fd9ca0
--- /dev/null
+++ b/vav2/platforms/windows/godot-plugin/src/VavCore.Wrapper/VavCore.Wrapper.csproj
@@ -0,0 +1,47 @@
+
+
+
+ net8.0
+ 11
+ enable
+ enable
+ true
+
+
+ VavCore P/Invoke Wrapper
+ Low-level P/Invoke wrapper for VavCore AV1 decoder library
+ 1.0.0.0
+ 1.0.0.0
+ VavCore Team
+ VavCore Godot Extension
+ Copyright © 2024 VavCore Team
+
+
+
+ DEBUG;TRACE
+ full
+ true
+
+
+
+ TRACE
+ true
+ portable
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ bin\$(Configuration)\$(TargetFramework)\VavCore.Wrapper.xml
+
+
+
\ No newline at end of file
diff --git a/vav2/platforms/windows/godot-plugin/src/VavCore.Wrapper/VavCore.cs b/vav2/platforms/windows/godot-plugin/src/VavCore.Wrapper/VavCore.cs
new file mode 100644
index 0000000..8ed545c
--- /dev/null
+++ b/vav2/platforms/windows/godot-plugin/src/VavCore.Wrapper/VavCore.cs
@@ -0,0 +1,262 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace VavCore.Wrapper;
+
+///
+/// Simple VavCore video decoder - all-in-one class
+/// Direct P/Invoke wrapper for VavCore C API with minimal overhead
+///
+public class VavCore : IDisposable
+{
+ // ================================================
+ // Essential Data Types
+ // ================================================
+
+ public enum DecoderType : int
+ {
+ Auto = 0, DAV1D = 1, NVDEC = 2, MediaFoundation = 3,
+ VPL = 4, AMF = 5, MediaCodec = 6
+ }
+
+ public enum QualityMode : int
+ {
+ Conservative = 0, Fast = 1, UltraFast = 2
+ }
+
+ public enum SurfaceType : int
+ {
+ CPU = 0, D3D11Texture = 1, D3D12Resource = 2, VulkanImage = 7,
+ OpenGLTexture = 9, MetalTexture = 10, OpenGLESTexture = 6
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct VideoFrame
+ {
+ public IntPtr YPlane, UPlane, VPlane;
+ public int YStride, UStride, VStride;
+ public int Width, Height;
+ public ulong TimestampUs, FrameNumber;
+
+ // User-friendly properties
+ public ulong FrameIndex => FrameNumber;
+ public double TimestampSeconds => TimestampUs / 1_000_000.0;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct VideoMetadata
+ {
+ public int Width, Height;
+ public double FrameRate, DurationSeconds;
+ public ulong TotalFrames;
+ public IntPtr CodecName;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct PerformanceMetrics
+ {
+ public double AverageDecodeTimeMs, CurrentFps;
+ public ulong FramesDecoded, FramesDropped;
+ public int CurrentQualityLevel;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ public struct VideoFrameSurface
+ {
+ public SurfaceType SurfaceType;
+ public IntPtr YSurface, UVSurface; // GPU surface handles
+ public int Width, Height;
+ public ulong TimestampUs, FrameNumber;
+
+ // User-friendly properties
+ public ulong FrameIndex => FrameNumber;
+ public double TimestampSeconds => TimestampUs / 1_000_000.0;
+ }
+
+ // ================================================
+ // P/Invoke (Essential C API functions only)
+ // ================================================
+
+ private const string DllName = "VavCore-debug";
+
+ [DllImport(DllName)] private static extern int vavcore_initialize();
+ [DllImport(DllName)] private static extern void vavcore_cleanup();
+ [DllImport(DllName)] private static extern IntPtr vavcore_create_player();
+ [DllImport(DllName)] private static extern void vavcore_destroy_player(IntPtr player);
+ [DllImport(DllName)] private static extern int vavcore_open_file(IntPtr player, string filePath);
+ [DllImport(DllName)] private static extern int vavcore_close_file(IntPtr player);
+ [DllImport(DllName)] private static extern int vavcore_decode_next_frame(IntPtr player, ref VideoFrame frame);
+ [DllImport(DllName)] private static extern int vavcore_get_metadata(IntPtr player, ref VideoMetadata metadata);
+ [DllImport(DllName)] private static extern int vavcore_seek_to_time(IntPtr player, double timeSeconds);
+ [DllImport(DllName)] private static extern int vavcore_seek_to_frame(IntPtr player, ulong frameNumber);
+ [DllImport(DllName)] private static extern int vavcore_reset(IntPtr player);
+ [DllImport(DllName)] private static extern int vavcore_is_open(IntPtr player);
+ [DllImport(DllName)] private static extern int vavcore_is_end_of_file(IntPtr player);
+ [DllImport(DllName)] private static extern int vavcore_set_decoder_type(IntPtr player, DecoderType decoderType);
+ [DllImport(DllName)] private static extern int vavcore_set_quality_mode(IntPtr player, QualityMode qualityMode);
+ [DllImport(DllName)] private static extern int vavcore_get_performance_metrics(IntPtr player, ref PerformanceMetrics metrics);
+ [DllImport(DllName)] private static extern int vavcore_decode_to_surface(IntPtr player, SurfaceType targetType, IntPtr targetSurface, ref VideoFrameSurface frame);
+
+ // ================================================
+ // Simple Public API
+ // ================================================
+
+ private IntPtr _player = IntPtr.Zero;
+ private bool _disposed = false;
+ private static bool _initialized = false;
+
+ public bool IsOpen => _player != IntPtr.Zero && vavcore_is_open(_player) != 0;
+ public bool IsEndOfFile => _player != IntPtr.Zero && vavcore_is_end_of_file(_player) != 0;
+
+ public VavCore()
+ {
+ if (!_initialized)
+ {
+ if (vavcore_initialize() != 0)
+ throw new InvalidOperationException("Failed to initialize VavCore");
+ _initialized = true;
+ }
+
+ _player = vavcore_create_player();
+ if (_player == IntPtr.Zero)
+ throw new InvalidOperationException("Failed to create VavCore player");
+ }
+
+ public bool OpenFile(string filePath)
+ {
+ return vavcore_open_file(_player, filePath) == 0;
+ }
+
+ public void CloseFile()
+ {
+ if (IsOpen) vavcore_close_file(_player);
+ }
+
+ public bool DecodeNextFrame(out VideoFrame frame)
+ {
+ frame = new VideoFrame();
+ return vavcore_decode_next_frame(_player, ref frame) == 0;
+ }
+
+ public bool GetMetadata(out VideoMetadata metadata)
+ {
+ metadata = new VideoMetadata();
+ return vavcore_get_metadata(_player, ref metadata) == 0;
+ }
+
+ public bool SeekToTime(double timeSeconds)
+ {
+ return vavcore_seek_to_time(_player, timeSeconds) == 0;
+ }
+
+ public bool SeekToFrame(ulong frameNumber)
+ {
+ return vavcore_seek_to_frame(_player, frameNumber) == 0;
+ }
+
+ public bool Reset()
+ {
+ return vavcore_reset(_player) == 0;
+ }
+
+ public bool SetDecoderType(DecoderType decoderType)
+ {
+ return vavcore_set_decoder_type(_player, decoderType) == 0;
+ }
+
+ public bool SetQualityMode(QualityMode qualityMode)
+ {
+ return vavcore_set_quality_mode(_player, qualityMode) == 0;
+ }
+
+ public bool GetPerformanceMetrics(out PerformanceMetrics metrics)
+ {
+ metrics = new PerformanceMetrics();
+ return vavcore_get_performance_metrics(_player, ref metrics) == 0;
+ }
+
+ // ================================================
+ // GPU Surface Decoding (Primary method)
+ // ================================================
+
+ public bool DecodeToSurface(SurfaceType surfaceType, IntPtr targetSurface, out VideoFrameSurface frame)
+ {
+ frame = new VideoFrameSurface();
+ return vavcore_decode_to_surface(_player, surfaceType, targetSurface, ref frame) == 0;
+ }
+
+ // ================================================
+ // User-friendly helpers
+ // ================================================
+
+ public Dictionary GetVideoInfo()
+ {
+ var info = new Dictionary();
+ if (GetMetadata(out var meta))
+ {
+ info["width"] = meta.Width;
+ info["height"] = meta.Height;
+ info["duration"] = meta.DurationSeconds;
+ info["frames"] = (long)meta.TotalFrames;
+ info["fps"] = meta.FrameRate;
+ }
+ return info;
+ }
+
+ public Dictionary GetStats()
+ {
+ var stats = new Dictionary();
+ if (GetPerformanceMetrics(out var metrics))
+ {
+ stats["frames_decoded"] = (long)metrics.FramesDecoded;
+ stats["frames_dropped"] = (long)metrics.FramesDropped;
+ stats["avg_decode_time_ms"] = metrics.AverageDecodeTimeMs;
+ stats["current_fps"] = metrics.CurrentFps;
+ }
+ return stats;
+ }
+
+ // ================================================
+ // Static Utilities
+ // ================================================
+
+ public static bool Initialize()
+ {
+ if (!_initialized)
+ {
+ _initialized = vavcore_initialize() == 0;
+ }
+ return _initialized;
+ }
+
+ public static string GetVersion() => "1.0.0";
+
+ public static DecoderType GetOptimalDecoderType()
+ {
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
+ return DecoderType.Auto; // NVDEC/VPL/AMF
+ else
+ return DecoderType.DAV1D; // Fallback for Linux/macOS/Android
+ }
+
+ // ================================================
+ // Disposal
+ // ================================================
+
+ public void Dispose()
+ {
+ if (!_disposed)
+ {
+ CloseFile();
+ if (_player != IntPtr.Zero)
+ {
+ vavcore_destroy_player(_player);
+ _player = IntPtr.Zero;
+ }
+ _disposed = true;
+ }
+ }
+
+ ~VavCore() => Dispose();
+}
\ No newline at end of file
diff --git a/vav2/platforms/windows/tests/godot-extension/TestVavCoreDLL.cs b/vav2/platforms/windows/tests/godot-extension/TestVavCoreDLL.cs
new file mode 100644
index 0000000..077599c
--- /dev/null
+++ b/vav2/platforms/windows/tests/godot-extension/TestVavCoreDLL.cs
@@ -0,0 +1,84 @@
+using System;
+using VavCore.Wrapper;
+
+// Simple console test to verify VavCore DLL connection
+class TestVavCoreDLL
+{
+ static void Main(string[] args)
+ {
+ Console.WriteLine("VavCore DLL Connection Test");
+ Console.WriteLine("===========================");
+
+ try
+ {
+ // Test VavCore DLL connection
+ Console.WriteLine("Testing VavCore DLL connection...");
+
+ // Get version string
+ var version = VavCore.GetVersion();
+ Console.WriteLine($"VavCore version: {version}");
+
+ // Initialize VavCore
+ Console.WriteLine("Initializing VavCore...");
+ bool initSuccess = VavCore.Initialize();
+ Console.WriteLine($"VavCore initialization: {(initSuccess ? "SUCCESS" : "FAILED")}");
+
+ if (initSuccess)
+ {
+ // Test player creation
+ Console.WriteLine("Creating VavCore player...");
+ var player = VavCore.CreatePlayer();
+ Console.WriteLine($"Player creation: {(player != IntPtr.Zero ? "SUCCESS" : "FAILED")}");
+
+ if (player != IntPtr.Zero)
+ {
+ // Test decoder type setting
+ Console.WriteLine("Setting decoder type to AUTO...");
+ bool setDecoderSuccess = VavCore.SetDecoderType(player, DecoderType.AUTO);
+ Console.WriteLine($"Set decoder type: {(setDecoderSuccess ? "SUCCESS" : "FAILED")}");
+
+ // Test surface type support
+ Console.WriteLine("Checking Vulkan surface support...");
+ bool vulkanSupported = VavCore.SupportsSurfaceType(SurfaceType.Vulkan);
+ Console.WriteLine($"Vulkan surface support: {(vulkanSupported ? "SUPPORTED" : "NOT SUPPORTED")}");
+
+ Console.WriteLine("Checking D3D11 surface support...");
+ bool d3d11Supported = VavCore.SupportsSurfaceType(SurfaceType.D3D11);
+ Console.WriteLine($"D3D11 surface support: {(d3d11Supported ? "SUPPORTED" : "NOT SUPPORTED")}");
+
+ // Get optimal surface type
+ Console.WriteLine("Getting optimal surface type...");
+ var optimalSurface = VavCore.GetOptimalSurfaceType();
+ Console.WriteLine($"Optimal surface type: {optimalSurface}");
+
+ // Test performance metrics
+ Console.WriteLine("Getting performance metrics...");
+ var metrics = VavCore.GetPerformanceMetrics(player);
+ Console.WriteLine($"Performance metrics - FPS: {metrics.CurrentFPS:F2}, Dropped: {metrics.DroppedFrames}");
+
+ // Clean up player
+ Console.WriteLine("Destroying player...");
+ VavCore.DestroyPlayer(player);
+ Console.WriteLine("Player destroyed");
+ }
+
+ // Clean up VavCore
+ Console.WriteLine("Cleaning up VavCore...");
+ VavCore.Cleanup();
+ Console.WriteLine("VavCore cleanup completed");
+ }
+
+ Console.WriteLine("\n=== VavCore DLL Connection Test COMPLETED SUCCESSFULLY ===");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"\n=== VavCore DLL Connection Test FAILED ===");
+ Console.WriteLine($"Error: {ex.Message}");
+ Console.WriteLine($"Stack trace: {ex.StackTrace}");
+ return;
+ }
+
+ Console.WriteLine("\nPress any key to exit...");
+ Console.ReadKey();
+ }
+}
\ No newline at end of file
diff --git a/vav2/platforms/windows/tests/godot-extension/TestVavCoreDLL.csproj b/vav2/platforms/windows/tests/godot-extension/TestVavCoreDLL.csproj
new file mode 100644
index 0000000..7c2ae22
--- /dev/null
+++ b/vav2/platforms/windows/tests/godot-extension/TestVavCoreDLL.csproj
@@ -0,0 +1,15 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+ true
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/Vav2PlayerHeadless.vcxproj b/vav2/platforms/windows/tests/headless/Vav2PlayerHeadless.vcxproj
similarity index 85%
rename from vav2/Vav2Player/Vav2PlayerHeadless/Vav2PlayerHeadless.vcxproj
rename to vav2/platforms/windows/tests/headless/Vav2PlayerHeadless.vcxproj
index 9f375ad..eee19ad 100644
--- a/vav2/Vav2Player/Vav2PlayerHeadless/Vav2PlayerHeadless.vcxproj
+++ b/vav2/platforms/windows/tests/headless/Vav2PlayerHeadless.vcxproj
@@ -53,14 +53,14 @@
_DEBUG;_CONSOLE;HEADLESS_BUILD;%(PreprocessorDefinitions)
true
stdcpp20
- $(ProjectDir)src;$(ProjectDir)..\..\VavCore\include;$(ProjectDir)..\..\..\include\libwebm;$(ProjectDir)..\..\..\include\dav1d;$(ProjectDir)..\..\..\oss\nvidia-video-codec\Interface;$(CUDA_PATH_V13_0)\include
+ $(ProjectDir)src;$(ProjectDir)..\..\vavcore\include;$(ProjectDir)..\..\..\..\..\include\libwebm;$(ProjectDir)..\..\..\..\..\include\dav1d;$(ProjectDir)..\..\..\..\..\oss\nvidia-video-codec\Interface;$(CUDA_PATH_V13_0)\include
Use
pch.h
Console
true
- $(ProjectDir)..\..\VavCore\lib;$(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
+ $(ProjectDir)..\..\vavcore\lib;$(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
VavCore-debug.lib;webm-debug.lib;dav1d-debug.lib;amf-debug.lib;vpld.lib;nvcuvid.lib;cuda.lib;mfplat.lib;mf.lib;mfuuid.lib;d3d11.lib;d3d12.lib;dxgi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
@@ -73,7 +73,7 @@
NDEBUG;_CONSOLE;HEADLESS_BUILD;VAVCORE_STATIC_LIB;%(PreprocessorDefinitions)
true
stdcpp20
- $(ProjectDir)src;$(ProjectDir)..\..\VavCore\include;$(ProjectDir)..\..\..\include\libwebm;$(ProjectDir)..\..\..\include\dav1d;$(ProjectDir)..\..\..\oss\nvidia-video-codec\Interface;$(CUDA_PATH_V13_0)\include
+ $(ProjectDir)src;$(ProjectDir)..\..\vavcore\include;$(ProjectDir)..\..\..\..\..\include\libwebm;$(ProjectDir)..\..\..\..\..\include\dav1d;$(ProjectDir)..\..\..\..\..\oss\nvidia-video-codec\Interface;$(CUDA_PATH_V13_0)\include
Use
pch.h
@@ -82,7 +82,7 @@
true
true
true
- $(ProjectDir)..\..\VavCore\lib;$(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
+ $(ProjectDir)..\..\vavcore\lib;$(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
VavCore.lib;webm.lib;dav1d.lib;amf.lib;vpl.lib;nvcuvid.lib;cuda.lib;mfplat.lib;mf.lib;mfuuid.lib;d3d11.lib;d3d12.lib;dxgi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/D3D12VideoRenderer_Stub.h b/vav2/platforms/windows/tests/headless/src/D3D12VideoRenderer_Stub.h
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/D3D12VideoRenderer_Stub.h
rename to vav2/platforms/windows/tests/headless/src/D3D12VideoRenderer_Stub.h
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/DebugVavCoreTest.cpp b/vav2/platforms/windows/tests/headless/src/DebugVavCoreTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/DebugVavCoreTest.cpp
rename to vav2/platforms/windows/tests/headless/src/DebugVavCoreTest.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/GPUVideoTest.cpp b/vav2/platforms/windows/tests/headless/src/GPUVideoTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/GPUVideoTest.cpp
rename to vav2/platforms/windows/tests/headless/src/GPUVideoTest.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/HeadlessDecoder.cpp b/vav2/platforms/windows/tests/headless/src/HeadlessDecoder.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/HeadlessDecoder.cpp
rename to vav2/platforms/windows/tests/headless/src/HeadlessDecoder.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/HeadlessDecoder.h b/vav2/platforms/windows/tests/headless/src/HeadlessDecoder.h
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/HeadlessDecoder.h
rename to vav2/platforms/windows/tests/headless/src/HeadlessDecoder.h
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/HeadlessLauncher.cpp b/vav2/platforms/windows/tests/headless/src/HeadlessLauncher.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/HeadlessLauncher.cpp
rename to vav2/platforms/windows/tests/headless/src/HeadlessLauncher.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/HeadlessMain.cpp b/vav2/platforms/windows/tests/headless/src/HeadlessMain.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/HeadlessMain.cpp
rename to vav2/platforms/windows/tests/headless/src/HeadlessMain.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/NVDECAV1Decoder_Headless.cpp b/vav2/platforms/windows/tests/headless/src/NVDECAV1Decoder_Headless.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/NVDECAV1Decoder_Headless.cpp
rename to vav2/platforms/windows/tests/headless/src/NVDECAV1Decoder_Headless.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/NVDECAV1Decoder_Headless.h b/vav2/platforms/windows/tests/headless/src/NVDECAV1Decoder_Headless.h
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/NVDECAV1Decoder_Headless.h
rename to vav2/platforms/windows/tests/headless/src/NVDECAV1Decoder_Headless.h
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/NVDECDebugTest.cpp b/vav2/platforms/windows/tests/headless/src/NVDECDebugTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/NVDECDebugTest.cpp
rename to vav2/platforms/windows/tests/headless/src/NVDECDebugTest.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/NVDECTestMain.cpp b/vav2/platforms/windows/tests/headless/src/NVDECTestMain.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/NVDECTestMain.cpp
rename to vav2/platforms/windows/tests/headless/src/NVDECTestMain.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/SimpleGPUIntegrationTest.cpp b/vav2/platforms/windows/tests/headless/src/SimpleGPUIntegrationTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/SimpleGPUIntegrationTest.cpp
rename to vav2/platforms/windows/tests/headless/src/SimpleGPUIntegrationTest.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/SimpleGPURenderer_Headless.h b/vav2/platforms/windows/tests/headless/src/SimpleGPURenderer_Headless.h
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/SimpleGPURenderer_Headless.h
rename to vav2/platforms/windows/tests/headless/src/SimpleGPURenderer_Headless.h
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/SimpleHeadlessMain.cpp b/vav2/platforms/windows/tests/headless/src/SimpleHeadlessMain.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/SimpleHeadlessMain.cpp
rename to vav2/platforms/windows/tests/headless/src/SimpleHeadlessMain.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/SimpleVavCoreTest.cpp b/vav2/platforms/windows/tests/headless/src/SimpleVavCoreTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/SimpleVavCoreTest.cpp
rename to vav2/platforms/windows/tests/headless/src/SimpleVavCoreTest.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/VavCoreHeadlessMain.cpp b/vav2/platforms/windows/tests/headless/src/VavCoreHeadlessMain.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/VavCoreHeadlessMain.cpp
rename to vav2/platforms/windows/tests/headless/src/VavCoreHeadlessMain.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/pch.cpp b/vav2/platforms/windows/tests/headless/src/pch.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/pch.cpp
rename to vav2/platforms/windows/tests/headless/src/pch.cpp
diff --git a/vav2/Vav2Player/Vav2PlayerHeadless/src/pch.h b/vav2/platforms/windows/tests/headless/src/pch.h
similarity index 100%
rename from vav2/Vav2Player/Vav2PlayerHeadless/src/pch.h
rename to vav2/platforms/windows/tests/headless/src/pch.h
diff --git a/vav2/platforms/windows/tests/integration/Program.cs b/vav2/platforms/windows/tests/integration/Program.cs
new file mode 100644
index 0000000..4f2839a
--- /dev/null
+++ b/vav2/platforms/windows/tests/integration/Program.cs
@@ -0,0 +1,278 @@
+using System;
+using VavCore.Wrapper;
+using VavCoreClass = VavCore.Wrapper.VavCore;
+
+namespace VavCoreTest;
+
+class Program
+{
+ static void Main(string[] args)
+ {
+ Console.WriteLine("=== VavCore.Wrapper P/Invoke Test ===");
+ Console.WriteLine();
+
+ // Test 1: Library Initialization
+ Console.WriteLine("Test 1: Library Initialization");
+ try
+ {
+ bool initialized = VavCoreClass.Initialize();
+ Console.WriteLine($" VavCore.Initialize(): {(initialized ? "SUCCESS" : "FAILED")}");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($" ERROR: {ex.Message}");
+ Console.WriteLine($" Exception Type: {ex.GetType().Name}");
+ if (ex.InnerException != null)
+ {
+ Console.WriteLine($" Inner Exception: {ex.InnerException.Message}");
+ }
+ }
+ Console.WriteLine();
+
+ // Test 2: Version Information
+ Console.WriteLine("Test 2: Version Information");
+ try
+ {
+ string version = VavCoreClass.GetVersion();
+ Console.WriteLine($" VavCore Version: {version}");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($" ERROR getting version: {ex.Message}");
+ }
+ Console.WriteLine();
+
+ // Test 3: Platform Information
+ Console.WriteLine("Test 3: Platform Information");
+ try
+ {
+ var optimalDecoder = VavCoreClass.GetOptimalDecoderType();
+ Console.WriteLine($" Optimal Decoder: {optimalDecoder}");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($" ERROR getting platform info: {ex.Message}");
+ }
+ Console.WriteLine();
+
+ // Test 4: Player Creation and Basic Operations
+ Console.WriteLine("Test 4: Player Creation and Basic Operations");
+ VavCoreClass? player = null;
+ try
+ {
+ player = new VavCoreClass();
+ Console.WriteLine(" Player created successfully");
+
+ // Test basic properties
+ Console.WriteLine($" Player is open: {player.IsOpen}");
+ Console.WriteLine($" Player is end of file: {player.IsEndOfFile}");
+
+ // Test decoder configuration
+ bool decoderSet = player.SetDecoderType(VavCoreClass.DecoderType.Auto);
+ Console.WriteLine($" Set Auto decoder: {(decoderSet ? "SUCCESS" : "FAILED")}");
+
+ bool qualitySet = player.SetQualityMode(VavCoreClass.QualityMode.Fast);
+ Console.WriteLine($" Set Fast quality mode: {(qualitySet ? "SUCCESS" : "FAILED")}");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($" ERROR creating player: {ex.Message}");
+ if (ex.InnerException != null)
+ {
+ Console.WriteLine($" Inner Exception: {ex.InnerException.Message}");
+ }
+ }
+ Console.WriteLine();
+
+ // Test 5: File Operations (if test file exists)
+ Console.WriteLine("Test 5: File Operations");
+ if (player != null)
+ {
+ try
+ {
+ // Try common test file paths
+ string[] testFiles = {
+ @"D:\Project\video-av1\sample\simple_test.webm",
+ @"D:\Project\video-av1\sample\output.webm",
+ @"sample.webm",
+ @"test.webm"
+ };
+
+ bool fileOpened = false;
+ string usedFile = "";
+
+ foreach (string testFile in testFiles)
+ {
+ if (System.IO.File.Exists(testFile))
+ {
+ Console.WriteLine($" Attempting to open: {testFile}");
+ fileOpened = player.OpenFile(testFile);
+ if (fileOpened)
+ {
+ usedFile = testFile;
+ Console.WriteLine($" File opened successfully: {testFile}");
+ break;
+ }
+ else
+ {
+ Console.WriteLine($" Failed to open: {testFile}");
+ }
+ }
+ }
+
+ if (!fileOpened)
+ {
+ Console.WriteLine(" No test files found or could be opened");
+ }
+ else
+ {
+ // Test metadata
+ if (player.GetMetadata(out var metadata))
+ {
+ Console.WriteLine($" Video Resolution: {metadata.Width}x{metadata.Height}");
+ Console.WriteLine($" Frame Rate: {metadata.FrameRate:F2} fps");
+ Console.WriteLine($" Duration: {metadata.DurationSeconds:F2} seconds");
+ Console.WriteLine($" Total Frames: {metadata.TotalFrames}");
+ }
+ else
+ {
+ Console.WriteLine(" Failed to get metadata");
+ }
+
+ // Test frame decoding
+ Console.WriteLine(" Testing frame decoding:");
+ int frameCount = 0;
+ for (int i = 0; i < 5; i++)
+ {
+ if (player.DecodeNextFrame(out var frame))
+ {
+ frameCount++;
+ Console.WriteLine($" Frame {frameCount}: {frame.Width}x{frame.Height}, " +
+ $"Timestamp: {frame.TimestampSeconds:F3}s");
+ }
+ else
+ {
+ Console.WriteLine($" Failed to decode frame {i + 1}");
+ break;
+ }
+
+ if (player.IsEndOfFile)
+ {
+ Console.WriteLine(" Reached end of file");
+ break;
+ }
+ }
+
+ // Test seeking
+ Console.WriteLine(" Testing seek functionality:");
+ if (player.Reset())
+ {
+ Console.WriteLine(" Reset to beginning: SUCCESS");
+ }
+ else
+ {
+ Console.WriteLine(" Reset to beginning: FAILED");
+ }
+
+ if (player.SeekToTime(1.0))
+ {
+ Console.WriteLine(" Seek to 1.0 seconds: SUCCESS");
+ if (player.DecodeNextFrame(out var seekFrame))
+ {
+ Console.WriteLine($" Frame after seek: Timestamp {seekFrame.TimestampSeconds:F3}s");
+ }
+ }
+ else
+ {
+ Console.WriteLine(" Seek to 1.0 seconds: FAILED");
+ }
+
+ // Test performance metrics
+ if (player.GetPerformanceMetrics(out var metrics))
+ {
+ Console.WriteLine(" Performance Metrics:");
+ Console.WriteLine($" Frames Decoded: {metrics.FramesDecoded}");
+ Console.WriteLine($" Frames Dropped: {metrics.FramesDropped}");
+ Console.WriteLine($" Average Decode Time: {metrics.AverageDecodeTimeMs:F2}ms");
+ Console.WriteLine($" Current FPS: {metrics.CurrentFps:F2}");
+ Console.WriteLine($" Quality Level: {metrics.CurrentQualityLevel}");
+ }
+
+ // Test user-friendly helpers
+ Console.WriteLine(" Video Info Dictionary:");
+ var videoInfo = player.GetVideoInfo();
+ foreach (var kvp in videoInfo)
+ {
+ Console.WriteLine($" {kvp.Key}: {kvp.Value}");
+ }
+
+ Console.WriteLine(" Stats Dictionary:");
+ var stats = player.GetStats();
+ foreach (var kvp in stats)
+ {
+ Console.WriteLine($" {kvp.Key}: {kvp.Value}");
+ }
+
+ // Close file
+ player.CloseFile();
+ Console.WriteLine(" File closed successfully");
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($" ERROR in file operations: {ex.Message}");
+ if (ex.InnerException != null)
+ {
+ Console.WriteLine($" Inner Exception: {ex.InnerException.Message}");
+ }
+ }
+ }
+ Console.WriteLine();
+
+ // Test 6: Surface Types
+ Console.WriteLine("Test 6: Surface Types");
+ try
+ {
+ Console.WriteLine(" Available Surface Types:");
+ var surfaceTypes = Enum.GetValues();
+ foreach (var surfaceType in surfaceTypes)
+ {
+ Console.WriteLine($" {surfaceType} = {(int)surfaceType}");
+ }
+
+ Console.WriteLine(" Available Decoder Types:");
+ var decoderTypes = Enum.GetValues();
+ foreach (var decoderType in decoderTypes)
+ {
+ Console.WriteLine($" {decoderType} = {(int)decoderType}");
+ }
+
+ Console.WriteLine(" Available Quality Modes:");
+ var qualityModes = Enum.GetValues();
+ foreach (var qualityMode in qualityModes)
+ {
+ Console.WriteLine($" {qualityMode} = {(int)qualityMode}");
+ }
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($" ERROR listing enums: {ex.Message}");
+ }
+ Console.WriteLine();
+
+ // Test 7: Cleanup
+ Console.WriteLine("Test 7: Cleanup");
+ try
+ {
+ player?.Dispose();
+ Console.WriteLine(" Player disposed successfully");
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($" ERROR during disposal: {ex.Message}");
+ }
+ Console.WriteLine();
+
+ Console.WriteLine("=== VavCore.Wrapper Test Completed ===");
+ }
+}
\ No newline at end of file
diff --git a/vav2/VavCoreTest/VavCoreTest.csproj b/vav2/platforms/windows/tests/integration/VavCoreTest.csproj
similarity index 83%
rename from vav2/VavCoreTest/VavCoreTest.csproj
rename to vav2/platforms/windows/tests/integration/VavCoreTest.csproj
index db577e6..fa19066 100644
--- a/vav2/VavCoreTest/VavCoreTest.csproj
+++ b/vav2/platforms/windows/tests/integration/VavCoreTest.csproj
@@ -11,13 +11,13 @@
- ..\godot_extension\src\VavCore.Wrapper\bin\Debug\net8.0\VavCore.Wrapper.dll
+ ..\..\godot-plugin\src\VavCore.Wrapper\bin\Debug\net8.0\VavCore.Wrapper.dll
-
+
\ No newline at end of file
diff --git a/vav2/platforms/windows/tests/run-all-tests.bat b/vav2/platforms/windows/tests/run-all-tests.bat
new file mode 100644
index 0000000..f81d277
--- /dev/null
+++ b/vav2/platforms/windows/tests/run-all-tests.bat
@@ -0,0 +1,71 @@
+@echo off
+REM All Tests Execution Script
+
+echo [TEST] Running all Windows platform tests...
+
+set BUILD_CONFIG=%1
+if "%BUILD_CONFIG%"=="" set BUILD_CONFIG=Debug
+
+echo Configuration: %BUILD_CONFIG%
+
+echo.
+echo ============================================================
+echo RUNNING VAVCORE DLL TESTS
+echo ============================================================
+cd vavcore-dll\bin\%BUILD_CONFIG%\net8.0
+if exist TestVavCoreDLL.exe (
+ echo [TEST] Running VavCore DLL connection test...
+ TestVavCoreDLL.exe
+ echo.
+) else (
+ echo [WARNING] TestVavCoreDLL.exe not found, skipping...
+)
+
+echo.
+echo ============================================================
+echo RUNNING INTEGRATION TESTS
+echo ============================================================
+cd ..\..\..\integration\bin\%BUILD_CONFIG%\net8.0
+if exist VavCoreTest.exe (
+ echo [TEST] Running VavCore integration test...
+ VavCoreTest.exe
+ echo.
+) else (
+ echo [WARNING] VavCoreTest.exe not found, skipping...
+)
+
+echo.
+echo ============================================================
+echo RUNNING UNIT TESTS
+echo ============================================================
+cd ..\..\..\unit-tests\Vav2UnitTest\x64\%BUILD_CONFIG%\UnitTest
+if exist Vav2UnitTest.dll (
+ echo [TEST] Running Vav2 unit tests...
+ vstest.console.exe Vav2UnitTest.dll
+ echo.
+) else (
+ echo [WARNING] Vav2UnitTest.dll not found, skipping...
+)
+
+echo.
+echo ============================================================
+echo RUNNING HEADLESS TESTS
+echo ============================================================
+cd ..\..\..\..\..\headless\x64\%BUILD_CONFIG%\Headless
+if exist Vav2PlayerHeadless.exe (
+ echo [TEST] Running headless performance test...
+ if exist "D:\Project\video-av1\sample\simple_test.webm" (
+ Vav2PlayerHeadless.exe "D:\Project\video-av1\sample\simple_test.webm"
+ ) else (
+ echo [WARNING] Test video file not found, running without file...
+ Vav2PlayerHeadless.exe
+ )
+ echo.
+) else (
+ echo [WARNING] Vav2PlayerHeadless.exe not found, skipping...
+)
+
+echo.
+echo ============================================================
+echo ALL TESTS COMPLETED
+echo ============================================================
\ No newline at end of file
diff --git a/vav2/Vav2Player/Vav2UnitTest/Vav2UnitTest.vcxproj b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/Vav2UnitTest.vcxproj
similarity index 82%
rename from vav2/Vav2Player/Vav2UnitTest/Vav2UnitTest.vcxproj
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/Vav2UnitTest.vcxproj
index ccbcf53..2ead892 100644
--- a/vav2/Vav2Player/Vav2UnitTest/Vav2UnitTest.vcxproj
+++ b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/Vav2UnitTest.vcxproj
@@ -62,7 +62,7 @@
pch.h
Level3
true
- $(ProjectDir)unit-test;$(ProjectDir)..\..\VavCore\include;$(ProjectDir)..\..\VavCore\src;$(ProjectDir)..\..\..\include\libwebm;$(ProjectDir)..\..\..\include\dav1d;$(ProjectDir)..\..\..\oss\nvidia-video-codec\Interface;$(CUDA_PATH_V13_0)\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)
+ $(ProjectDir)tests;$(ProjectDir)..\..\..\vavcore\include;$(ProjectDir)..\..\..\vavcore\src;$(ProjectDir)..\..\..\applications\vav2player\Vav2Player\src;$(ProjectDir)..\..\..\..\..\include\libwebm;$(ProjectDir)..\..\..\..\..\include\dav1d;$(ProjectDir)..\..\..\..\..\oss\nvidia-video-codec\Interface;$(CUDA_PATH_V13_0)\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)
WIN32;_DEBUG;UNIT_TEST_BUILD;VAVCORE_STATIC_LIB;%(PreprocessorDefinitions)
true
$(IntDir)pch.pch
@@ -70,7 +70,7 @@
Windows
- $(ProjectDir)..\..\VavCore\lib;%(AdditionalLibraryDirectories)
+ $(ProjectDir)..\..\..\vavcore\lib;%(AdditionalLibraryDirectories)
VavCore-debug.lib;mfplat.lib;mfuuid.lib;d3d12.lib;d3d11.lib;dxgi.lib;%(AdditionalDependencies)
@@ -82,7 +82,7 @@
true
true
true
- $(ProjectDir)unit-test;$(ProjectDir)..\..\VavCore\include;$(ProjectDir)..\..\VavCore\src;$(ProjectDir)..\..\..\include\libwebm;$(ProjectDir)..\..\..\include\dav1d;$(ProjectDir)..\..\..\oss\nvidia-video-codec\Interface;$(CUDA_PATH_V13_0)\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)
+ $(ProjectDir)tests;$(ProjectDir)..\..\..\vavcore\include;$(ProjectDir)..\..\..\vavcore\src;$(ProjectDir)..\..\..\applications\vav2player\Vav2Player\src;$(ProjectDir)..\..\..\..\..\include\libwebm;$(ProjectDir)..\..\..\..\..\include\dav1d;$(ProjectDir)..\..\..\..\..\oss\nvidia-video-codec\Interface;$(CUDA_PATH_V13_0)\include;$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories)
WIN32;NDEBUG;UNIT_TEST_BUILD;%(PreprocessorDefinitions)
true
$(IntDir)pch.pch
@@ -92,7 +92,7 @@
Windows
true
true
- $(ProjectDir)..\..\VavCore\lib;%(AdditionalLibraryDirectories)
+ $(ProjectDir)..\..\..\vavcore\lib;%(AdditionalLibraryDirectories)
VavCore.lib;mfplat.lib;mfuuid.lib;d3d12.lib;d3d11.lib;dxgi.lib;%(AdditionalDependencies)
@@ -113,8 +113,8 @@
-
-
+
+
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/AV1DecoderTest.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/AV1DecoderTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/AV1DecoderTest.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/AV1DecoderTest.cpp
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/LogManagerTest.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/LogManagerTest.cpp
similarity index 98%
rename from vav2/Vav2Player/Vav2UnitTest/tests/LogManagerTest.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/LogManagerTest.cpp
index e7535dd..2102cd8 100644
--- a/vav2/Vav2Player/Vav2UnitTest/tests/LogManagerTest.cpp
+++ b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/LogManagerTest.cpp
@@ -1,6 +1,6 @@
#include "pch.h"
-#include "../../Vav2Player/src/Logger/ILogManager.h"
-#include "../../Vav2Player/src/Logger/LogManager.h"
+#include "Logger/ILogManager.h"
+#include "Logger/LogManager.h"
#include "MockLogManager.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/MockLogManager.h b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockLogManager.h
similarity index 98%
rename from vav2/Vav2Player/Vav2UnitTest/tests/MockLogManager.h
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockLogManager.h
index 0a31402..ceb62c9 100644
--- a/vav2/Vav2Player/Vav2UnitTest/tests/MockLogManager.h
+++ b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockLogManager.h
@@ -1,6 +1,6 @@
#pragma once
-#include "../../Vav2Player/src/Logger/ILogManager.h"
-#include "../../Vav2Player/src/Logger/LogManager.h"
+#include "Logger/ILogManager.h"
+#include "Logger/LogManager.h"
#include
#include
#include
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/MockVideoRenderer.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockVideoRenderer.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/MockVideoRenderer.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockVideoRenderer.cpp
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/MockVideoRenderer.h b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockVideoRenderer.h
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/MockVideoRenderer.h
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockVideoRenderer.h
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/MockWebMFileReader.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockWebMFileReader.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/MockWebMFileReader.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockWebMFileReader.cpp
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/MockWebMFileReader.h b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockWebMFileReader.h
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/MockWebMFileReader.h
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/MockWebMFileReader.h
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/VavCoreTest.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/VavCoreTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/VavCoreTest.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/VavCoreTest.cpp
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/VideoPlayerControlTest.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/VideoPlayerControlTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/VideoPlayerControlTest.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/VideoPlayerControlTest.cpp
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/VideoRendererTest.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/VideoRendererTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/VideoRendererTest.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/VideoRendererTest.cpp
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/VideoTypesTest.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/VideoTypesTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/VideoTypesTest.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/VideoTypesTest.cpp
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/WebMFileReaderTest.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/WebMFileReaderTest.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/WebMFileReaderTest.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/WebMFileReaderTest.cpp
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/pch.cpp b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/pch.cpp
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/pch.cpp
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/pch.cpp
diff --git a/vav2/Vav2Player/Vav2UnitTest/tests/pch.h b/vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/pch.h
similarity index 100%
rename from vav2/Vav2Player/Vav2UnitTest/tests/pch.h
rename to vav2/platforms/windows/tests/unit-tests/Vav2UnitTest/tests/pch.h
diff --git a/test_vavcore/TestVavCoreDLL.cs b/vav2/platforms/windows/tests/vavcore-dll/TestVavCoreDLL.cs
similarity index 100%
rename from test_vavcore/TestVavCoreDLL.cs
rename to vav2/platforms/windows/tests/vavcore-dll/TestVavCoreDLL.cs
diff --git a/test_vavcore/TestVavCoreDLL.csproj b/vav2/platforms/windows/tests/vavcore-dll/TestVavCoreDLL.csproj
similarity index 100%
rename from test_vavcore/TestVavCoreDLL.csproj
rename to vav2/platforms/windows/tests/vavcore-dll/TestVavCoreDLL.csproj
diff --git a/vav2/VavCore/Android.mk b/vav2/platforms/windows/vavcore/Android.mk
similarity index 100%
rename from vav2/VavCore/Android.mk
rename to vav2/platforms/windows/vavcore/Android.mk
diff --git a/vav2/VavCore/Application.mk b/vav2/platforms/windows/vavcore/Application.mk
similarity index 100%
rename from vav2/VavCore/Application.mk
rename to vav2/platforms/windows/vavcore/Application.mk
diff --git a/vav2/VavCore/CMakeLists.txt b/vav2/platforms/windows/vavcore/CMakeLists.txt
similarity index 100%
rename from vav2/VavCore/CMakeLists.txt
rename to vav2/platforms/windows/vavcore/CMakeLists.txt
diff --git a/vav2/VavCore/README-Android.md b/vav2/platforms/windows/vavcore/README-Android.md
similarity index 100%
rename from vav2/VavCore/README-Android.md
rename to vav2/platforms/windows/vavcore/README-Android.md
diff --git a/vav2/VavCore/VavCore.vcxproj b/vav2/platforms/windows/vavcore/VavCore.vcxproj
similarity index 76%
rename from vav2/VavCore/VavCore.vcxproj
rename to vav2/platforms/windows/vavcore/VavCore.vcxproj
index 8c899af..c15272d 100644
--- a/vav2/VavCore/VavCore.vcxproj
+++ b/vav2/platforms/windows/vavcore/VavCore.vcxproj
@@ -63,7 +63,7 @@
true
Use
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)
+ $(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
@@ -71,11 +71,11 @@
true
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)
+ $(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)
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)
+ $(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)
@@ -88,7 +88,7 @@
true
Use
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)
+ $(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
@@ -98,17 +98,17 @@
true
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)
+ $(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)
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)
+ $(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 DLL to Godot extension directory..."
- if not exist "$(ProjectDir)..\godot_extension\libs\windows-x86_64\" mkdir "$(ProjectDir)..\godot_extension\libs\windows-x86_64\"
- copy "$(TargetPath)" "$(ProjectDir)..\godot_extension\libs\windows-x86_64\"
+ 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"
Installing VavCore DLL to Godot extension
diff --git a/vav2/VavCore/build-android.sh b/vav2/platforms/windows/vavcore/build-android.sh
similarity index 100%
rename from vav2/VavCore/build-android.sh
rename to vav2/platforms/windows/vavcore/build-android.sh
diff --git a/vav2/VavCore/build-windows.bat b/vav2/platforms/windows/vavcore/build-windows.bat
similarity index 100%
rename from vav2/VavCore/build-windows.bat
rename to vav2/platforms/windows/vavcore/build-windows.bat
diff --git a/vav2/platforms/windows/vavcore/build.bat b/vav2/platforms/windows/vavcore/build.bat
new file mode 100644
index 0000000..868f582
--- /dev/null
+++ b/vav2/platforms/windows/vavcore/build.bat
@@ -0,0 +1,23 @@
+@echo off
+REM VavCore Library Build Script
+
+echo [BUILD] Building VavCore library...
+
+set BUILD_CONFIG=%1
+if "%BUILD_CONFIG%"=="" set BUILD_CONFIG=Debug
+
+set PLATFORM=%2
+if "%PLATFORM%"=="" set PLATFORM=x64
+
+echo Configuration: %BUILD_CONFIG%
+echo Platform: %PLATFORM%
+
+"C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe" VavCore.vcxproj /p:Configuration=%BUILD_CONFIG% /p:Platform=%PLATFORM% /v:minimal
+
+if errorlevel 1 (
+ echo [ERROR] VavCore build failed!
+ exit /b 1
+)
+
+echo [SUCCESS] VavCore library built successfully
+echo Output: x64\%BUILD_CONFIG%\VavCore\
\ No newline at end of file
diff --git a/vav2/VavCore/include/VavCore/VavCore.h b/vav2/platforms/windows/vavcore/include/VavCore/VavCore.h
similarity index 100%
rename from vav2/VavCore/include/VavCore/VavCore.h
rename to vav2/platforms/windows/vavcore/include/VavCore/VavCore.h
diff --git a/vav2/VavCore/src/Common/AdaptiveTypes.h b/vav2/platforms/windows/vavcore/src/Common/AdaptiveTypes.h
similarity index 100%
rename from vav2/VavCore/src/Common/AdaptiveTypes.h
rename to vav2/platforms/windows/vavcore/src/Common/AdaptiveTypes.h
diff --git a/vav2/VavCore/src/Common/D3D12Helpers.h b/vav2/platforms/windows/vavcore/src/Common/D3D12Helpers.h
similarity index 100%
rename from vav2/VavCore/src/Common/D3D12Helpers.h
rename to vav2/platforms/windows/vavcore/src/Common/D3D12Helpers.h
diff --git a/vav2/VavCore/src/Common/VideoTypes.h b/vav2/platforms/windows/vavcore/src/Common/VideoTypes.h
similarity index 100%
rename from vav2/VavCore/src/Common/VideoTypes.h
rename to vav2/platforms/windows/vavcore/src/Common/VideoTypes.h
diff --git a/vav2/VavCore/src/Decoder/AMFAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/AMFAV1Decoder.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/AMFAV1Decoder.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/AMFAV1Decoder.cpp
diff --git a/vav2/VavCore/src/Decoder/AMFAV1Decoder.h b/vav2/platforms/windows/vavcore/src/Decoder/AMFAV1Decoder.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/AMFAV1Decoder.h
rename to vav2/platforms/windows/vavcore/src/Decoder/AMFAV1Decoder.h
diff --git a/vav2/VavCore/src/Decoder/AV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/AV1Decoder.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/AV1Decoder.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/AV1Decoder.cpp
diff --git a/vav2/VavCore/src/Decoder/AV1Decoder.h b/vav2/platforms/windows/vavcore/src/Decoder/AV1Decoder.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/AV1Decoder.h
rename to vav2/platforms/windows/vavcore/src/Decoder/AV1Decoder.h
diff --git a/vav2/VavCore/src/Decoder/AdaptiveAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/AdaptiveAV1Decoder.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/AdaptiveAV1Decoder.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/AdaptiveAV1Decoder.cpp
diff --git a/vav2/VavCore/src/Decoder/AdaptiveAV1Decoder.h b/vav2/platforms/windows/vavcore/src/Decoder/AdaptiveAV1Decoder.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/AdaptiveAV1Decoder.h
rename to vav2/platforms/windows/vavcore/src/Decoder/AdaptiveAV1Decoder.h
diff --git a/vav2/VavCore/src/Decoder/AdaptiveDecodingExample.cpp b/vav2/platforms/windows/vavcore/src/Decoder/AdaptiveDecodingExample.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/AdaptiveDecodingExample.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/AdaptiveDecodingExample.cpp
diff --git a/vav2/VavCore/src/Decoder/AdaptiveNVDECDecoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/AdaptiveNVDECDecoder.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/AdaptiveNVDECDecoder.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/AdaptiveNVDECDecoder.cpp
diff --git a/vav2/VavCore/src/Decoder/AdaptiveNVDECDecoder.h b/vav2/platforms/windows/vavcore/src/Decoder/AdaptiveNVDECDecoder.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/AdaptiveNVDECDecoder.h
rename to vav2/platforms/windows/vavcore/src/Decoder/AdaptiveNVDECDecoder.h
diff --git a/vav2/VavCore/src/Decoder/AndroidMediaCodecAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/AndroidMediaCodecAV1Decoder.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/AndroidMediaCodecAV1Decoder.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/AndroidMediaCodecAV1Decoder.cpp
diff --git a/vav2/VavCore/src/Decoder/AndroidMediaCodecAV1Decoder.h b/vav2/platforms/windows/vavcore/src/Decoder/AndroidMediaCodecAV1Decoder.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/AndroidMediaCodecAV1Decoder.h
rename to vav2/platforms/windows/vavcore/src/Decoder/AndroidMediaCodecAV1Decoder.h
diff --git a/vav2/VavCore/src/Decoder/IVideoDecoder.h b/vav2/platforms/windows/vavcore/src/Decoder/IVideoDecoder.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/IVideoDecoder.h
rename to vav2/platforms/windows/vavcore/src/Decoder/IVideoDecoder.h
diff --git a/vav2/VavCore/src/Decoder/MediaFoundationAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/MediaFoundationAV1Decoder.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/MediaFoundationAV1Decoder.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/MediaFoundationAV1Decoder.cpp
diff --git a/vav2/VavCore/src/Decoder/MediaFoundationAV1Decoder.h b/vav2/platforms/windows/vavcore/src/Decoder/MediaFoundationAV1Decoder.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/MediaFoundationAV1Decoder.h
rename to vav2/platforms/windows/vavcore/src/Decoder/MediaFoundationAV1Decoder.h
diff --git a/vav2/VavCore/src/Decoder/NVDECAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/NVDECAV1Decoder.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/NVDECAV1Decoder.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/NVDECAV1Decoder.cpp
diff --git a/vav2/VavCore/src/Decoder/NVDECAV1Decoder.h b/vav2/platforms/windows/vavcore/src/Decoder/NVDECAV1Decoder.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/NVDECAV1Decoder.h
rename to vav2/platforms/windows/vavcore/src/Decoder/NVDECAV1Decoder.h
diff --git a/vav2/VavCore/src/Decoder/VPLAV1Decoder.cpp b/vav2/platforms/windows/vavcore/src/Decoder/VPLAV1Decoder.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/VPLAV1Decoder.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/VPLAV1Decoder.cpp
diff --git a/vav2/VavCore/src/Decoder/VPLAV1Decoder.h b/vav2/platforms/windows/vavcore/src/Decoder/VPLAV1Decoder.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/VPLAV1Decoder.h
rename to vav2/platforms/windows/vavcore/src/Decoder/VPLAV1Decoder.h
diff --git a/vav2/VavCore/src/Decoder/VideoDecoderFactory.cpp b/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.cpp
similarity index 100%
rename from vav2/VavCore/src/Decoder/VideoDecoderFactory.cpp
rename to vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.cpp
diff --git a/vav2/VavCore/src/Decoder/VideoDecoderFactory.h b/vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.h
similarity index 100%
rename from vav2/VavCore/src/Decoder/VideoDecoderFactory.h
rename to vav2/platforms/windows/vavcore/src/Decoder/VideoDecoderFactory.h
diff --git a/vav2/VavCore/src/FileIO/IWebMFileReader.h b/vav2/platforms/windows/vavcore/src/FileIO/IWebMFileReader.h
similarity index 100%
rename from vav2/VavCore/src/FileIO/IWebMFileReader.h
rename to vav2/platforms/windows/vavcore/src/FileIO/IWebMFileReader.h
diff --git a/vav2/VavCore/src/FileIO/WebMFileReader.cpp b/vav2/platforms/windows/vavcore/src/FileIO/WebMFileReader.cpp
similarity index 100%
rename from vav2/VavCore/src/FileIO/WebMFileReader.cpp
rename to vav2/platforms/windows/vavcore/src/FileIO/WebMFileReader.cpp
diff --git a/vav2/VavCore/src/FileIO/WebMFileReader.h b/vav2/platforms/windows/vavcore/src/FileIO/WebMFileReader.h
similarity index 100%
rename from vav2/VavCore/src/FileIO/WebMFileReader.h
rename to vav2/platforms/windows/vavcore/src/FileIO/WebMFileReader.h
diff --git a/vav2/VavCore/src/VavCore.cpp b/vav2/platforms/windows/vavcore/src/VavCore.cpp
similarity index 100%
rename from vav2/VavCore/src/VavCore.cpp
rename to vav2/platforms/windows/vavcore/src/VavCore.cpp
diff --git a/vav2/VavCore/src/pch.cpp b/vav2/platforms/windows/vavcore/src/pch.cpp
similarity index 100%
rename from vav2/VavCore/src/pch.cpp
rename to vav2/platforms/windows/vavcore/src/pch.cpp
diff --git a/vav2/VavCore/src/pch.h b/vav2/platforms/windows/vavcore/src/pch.h
similarity index 100%
rename from vav2/VavCore/src/pch.h
rename to vav2/platforms/windows/vavcore/src/pch.h
diff --git a/vav2/todo9.txt b/vav2/todo9.txt
index fc34676..acc7dd9 100644
--- a/vav2/todo9.txt
+++ b/vav2/todo9.txt
@@ -1,3 +1,58 @@
+ 🎯 권장 재배치 구조:
+
+ vav2/platforms/windows/
+ ├── vavcore/ # VavCore Windows 빌드
+ │ ├── VavCore.vcxproj
+ │ ├── src/ → 심볼릭링크 to ../../VavCore/src/
+ │ ├── include/ → 심볼릭링크 to ../../VavCore/include/
+ │ └── build_windows.bat
+ ├── godot-plugin/ # Godot Windows 확장
+ │ ├── VavCore.Wrapper/
+ │ ├── VavCore.Godot/
+ │ ├── libs/windows-x86_64/
+ │ └── build_godot.bat
+ ├── applications/ # Windows 애플리케이션들
+ │ └── vav2player/ # Vav2Player GUI 앱
+ │ ├── Vav2Player/
+ │ ├── Vav2PlayerHeadless/
+ │ └── build_app.bat
+ └── tests/ # 모든 Windows 테스트
+ ├── vavcore-dll/ # VavCore DLL 테스트
+ ├── godot-extension/ # Godot 확장 테스트
+ ├── integration/ # 통합 테스트
+ └── unit-tests/ # 유닛 테스트
+
+ 🚀 재배치의 장점:
+
+ 1. 플랫폼별 관리 일원화
+
+ - Windows 관련 모든 프로젝트가 한 곳에 집중
+ - 플랫폼별 빌드 스크립트 통합 관리
+ - 의존성 관리 단순화
+
+ 2. 크로스 플랫폼 확장성
+
+ - Android, iOS 등 다른 플랫폼 추가 시 동일한 구조 적용
+ - 플랫폼별 차이점 명확한 분리
+ - README.md 설계 철학에 부합
+
+ 3. CI/CD 최적화
+
+ - 플랫폼별 빌드 파이프라인 구성 용이
+ - 테스트 자동화 경로 일관성
+ - 배포 아티팩트 관리 체계화
+
+ 💡 실행 제안:
+
+ 어떤 방식으로 진행하시겠습니까?
+
+ 1. 전체 재배치: 모든 Windows 프로젝트를 platforms/windows/로 이동
+ 2. 단계적 재배치: 테스트 프로젝트부터 우선 이동
+ 3. 심볼릭 링크 활용: 기존 위치 유지하면서 platforms/windows/에서 참조
+ 4. 현재 구조 유지: platforms/windows/는 미래 확장용으로 보존
+
+-----------------------------------------------------------------
+
● 현재 VavCore DLL 통합 테스트가 완전히 완료되었으므로, 다음 단계를 제안합니다:
🎯 다음 작업 옵션들