diff --git a/vav2/VavCore_Godot_Integration_Design.md b/vav2/VavCore_Godot_Integration_Design.md index d887c2c..2440ec3 100644 --- a/vav2/VavCore_Godot_Integration_Design.md +++ b/vav2/VavCore_Godot_Integration_Design.md @@ -72,11 +72,17 @@ D:\Project\video-av1\ │ └── ios/ │ └── VavCore.xcodeproj # iOS용 .a 빌드용 Xcode 프로젝트 │ - ├── godot_extension/ # (예정) Godot 익스텐션 및 C# 래퍼 개발 - │ ├── VavCoreGodot.sln # C# 래퍼 및 Godot 노드용 솔루션 - │ ├── src/ - │ │ ├── VavCore.Wrapper/ # C# P/Invoke 래퍼 클래스 - │ │ └── VavCore.Godot/ # Godot 커스텀 노드 구현 + ├── platforms/ # ✅ 플랫폼별 구조로 개편 완료 + │ └── windows/ + │ ├── vavcore/ # VavCore Windows 라이브러리 + │ ├── godot-plugin/ # ✅ Godot Extension (완전 구현) + │ │ ├── VavCoreGodot.sln # C# 래퍼 및 Godot 노드용 솔루션 + │ │ ├── src/ + │ │ │ ├── VavCore.Wrapper/ # C# P/Invoke 래퍼 클래스 + │ │ │ └── VavCore.Godot/ # Godot 커스텀 노드 구현 + │ │ └── libs/windows-x86_64/ # Windows DLL들 + │ ├── applications/ # Windows 애플리케이션들 + │ └── tests/ # 테스트 프로젝트들 │ ├── project.godot # 익스텐션 테스트/개발용 Godot 프로젝트 │ └── shaders/ │ └── yuv_to_rgb.gdshader @@ -108,10 +114,11 @@ D:\Project\video-av1\ - **Android 플랫폼**: MediaCodec 통합, dav1d 크로스 컴파일, CMake 빌드 시스템 완료 - 각 프로젝트는 `vav2/VavCore/src`의 공용 소스를 참조한다. -- **`vav2/godot_extension/`** ✅ (완료) - - Godot 엔진용 플러그인을 개발하고 테스트하는 전용 공간이다. - - `VavCore.Wrapper`: 네이티브 라이브러리의 C 함수를 호출하는 저수준 C# P/Invoke 코드를 포함한다. **실제 VavCore C API에 맞춰 28개 함수로 단순화 완료** - - `VavCore.Godot`: `VavCore.Wrapper`를 사용하여 Godot 에디터에서 사용할 수 있는 커스텀 노드(예: `VavCorePlayerNode`)를 구현한다. +- **`vav2/platforms/windows/godot-plugin/`** ✅ (완료) + - Windows 전용 Godot 엔진 플러그인 개발 및 테스트 공간 + - `VavCore.Wrapper`: Windows VavCore DLL의 C 함수를 호출하는 저수준 C# P/Invoke 코드 포함. **실제 VavCore C API에 맞춰 28개 함수로 단순화 완료** + - `VavCore.Godot`: `VavCore.Wrapper`를 사용하여 Godot 에디터에서 사용할 수 있는 커스텀 노드(예: `VavCorePlayerNode`) 구현 + - **플랫폼별 구조**: Windows 특화 최적화 및 NVDEC/VPL/AMF 하드웨어 가속 지원 - **API 설계 철학**: 작고 간편한 player-centric 디자인으로 기술부채 최소화 - **`vav2/libs_output/`** (예정) @@ -119,7 +126,7 @@ D:\Project\video-av1\ ## 4. Godot 애드온 배포 및 사용 -`vav2/godot_extension`에서 개발된 결과물은 다른 Godot 프로젝트에서 쉽게 사용할 수 있는 '애드온' 형태로 배포된다. +`vav2/platforms/windows/godot-plugin`에서 개발된 결과물은 다른 Godot 프로젝트에서 쉽게 사용할 수 있는 '애드온' 형태로 배포된다. ### 4.1. 소비자 프로젝트 예시 (`GodotPlayer`) @@ -159,7 +166,7 @@ D:\MyGames\GodotPlayer\ - **dav1d Android 빌드**: ARM64/ARM32 크로스 컴파일 완료 - **CMake 빌드 시스템**: Android NDK 통합 및 라이브러리 빌드 - **platforms/android/godot-plugin**: Godot 4.4.1 Android 네이티브 플러그인 완료 -- **godot_extension C# wrapper**: VavCore C API 기반 P/Invoke 레이어 완료 +- **platforms/windows/godot-plugin C# wrapper**: VavCore C API 기반 P/Invoke 레이어 완료 - **API 설계 단순화**: 70+ 함수에서 28개 vavcore_* 함수로 축소 ### 5.2. 현재 진행 중 🔄 diff --git a/vav2/godot_extension/Program.cs b/vav2/godot_extension/Program.cs deleted file mode 100644 index 2fdbb93..0000000 --- a/vav2/godot_extension/Program.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System; -using VavCore.Wrapper; - -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 = VavCoreWrapper.Initialize(); - Console.WriteLine($" VavCore.Initialize(): {(initialized ? "SUCCESS" : "FAILED")}"); - - if (initialized) - { - Console.WriteLine($" Library is initialized: {VavCoreWrapper.IsInitialized}"); - } - } - catch (Exception ex) - { - Console.WriteLine($" ERROR: {ex.Message}"); - Console.WriteLine($" Exception Type: {ex.GetType().Name}"); - Console.WriteLine($" Stack Trace: {ex.StackTrace}"); - } - Console.WriteLine(); - - // Test 2: Version Information - Console.WriteLine("Test 2: Version Information"); - try - { - string version = VavCoreWrapper.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 - { - string libraryName = VavCoreTypes.GetLibraryName(); - Console.WriteLine($" Library Name: {libraryName}"); - - var optimalDecoder = VavCoreTypes.GetOptimalDecoderType(); - Console.WriteLine($" Optimal Decoder: {optimalDecoder}"); - - var optimalSurface = VavCoreTypes.GetOptimalSurfaceType(); - Console.WriteLine($" Optimal Surface: {optimalSurface}"); - } - 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"); - VavCoreWrapper? player = null; - try - { - player = new VavCoreWrapper(); - Console.WriteLine(" Player created successfully"); - - // Test basic properties - Console.WriteLine($" Player handle: 0x{player.NativeHandle:X}"); - - // Test decoder capabilities - bool supportsAuto = player.SupportsSurfaceType(VavCoreTypes.SurfaceType.Auto); - bool supportsCPU = player.SupportsSurfaceType(VavCoreTypes.SurfaceType.CPU); - bool supportsD3D11 = player.SupportsSurfaceType(VavCoreTypes.SurfaceType.D3D11Texture); - - Console.WriteLine($" Supports Auto Surface: {supportsAuto}"); - Console.WriteLine($" Supports CPU Surface: {supportsCPU}"); - Console.WriteLine($" Supports D3D11 Surface: {supportsD3D11}"); - - // Get optimal surface type for this player - var playerOptimalSurface = player.GetOptimalSurfaceType(); - Console.WriteLine($" Player Optimal Surface: {playerOptimalSurface}"); - } - catch (Exception ex) - { - Console.WriteLine($" ERROR creating player: {ex.Message}"); - } - finally - { - player?.Dispose(); - Console.WriteLine(" Player disposed"); - } - Console.WriteLine(); - - // Test 5: Static Utility Methods - Console.WriteLine("Test 5: Static Utility Methods"); - try - { - string availableDecoders = VavCoreWrapper.GetAvailableDecoders(); - Console.WriteLine($" Available Decoders: {availableDecoders}"); - - var optimalDecoderType = VavCoreWrapper.GetOptimalDecoderType(); - Console.WriteLine($" Static Optimal Decoder: {optimalDecoderType}"); - - var optimalSurfaceType = VavCoreWrapper.GetOptimalSurfaceType("vulkan"); - Console.WriteLine($" Static Optimal Surface (Vulkan): {optimalSurfaceType}"); - - bool av1Supported = VavCoreWrapper.IsCodecSupported(VavCoreTypes.VideoCodecType.AV1); - bool vp9Supported = VavCoreWrapper.IsCodecSupported(VavCoreTypes.VideoCodecType.VP9); - - Console.WriteLine($" AV1 Codec Supported: {av1Supported}"); - Console.WriteLine($" VP9 Codec Supported: {vp9Supported}"); - } - catch (Exception ex) - { - Console.WriteLine($" ERROR in utility methods: {ex.Message}"); - } - Console.WriteLine(); - - // Test 6: Error Handling - Console.WriteLine("Test 6: Error Handling"); - try - { - string successMsg = VavCoreWrapper.GetErrorMessage(VavCoreTypes.VavCoreResult.Success); - string errorMsg = VavCoreWrapper.GetErrorMessage(VavCoreTypes.VavCoreResult.ErrorFileNotFound); - - Console.WriteLine($" Success Message: {successMsg}"); - Console.WriteLine($" Error Message: {errorMsg}"); - } - catch (Exception ex) - { - Console.WriteLine($" ERROR in error handling: {ex.Message}"); - } - Console.WriteLine(); - - // Test 7: Library Cleanup - Console.WriteLine("Test 7: Library Cleanup"); - try - { - VavCoreWrapper.Cleanup(); - Console.WriteLine(" VavCore.Cleanup(): SUCCESS"); - Console.WriteLine($" Library is initialized: {VavCoreWrapper.IsInitialized}"); - } - catch (Exception ex) - { - Console.WriteLine($" ERROR during cleanup: {ex.Message}"); - } - 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/godot_extension/README.md b/vav2/godot_extension/README.md deleted file mode 100644 index c11b80d..0000000 --- a/vav2/godot_extension/README.md +++ /dev/null @@ -1,702 +0,0 @@ -# VavCore Godot 4.4.1 Extension - 완전 구현 완료 - -크로스 플랫폼 C# Extension으로 Godot 4.4.1에서 하드웨어 가속 AV1 비디오 디코딩을 제공하는 완전 구현된 라이브러리입니다. - -## ✅ **완전 구현된 주요 기능** - -### **🚀 하드웨어 가속 AV1 디코딩 (완료)** -- **Windows**: ✅ NVIDIA NVDEC, Intel VPL, AMD AMF, Media Foundation 모든 디코더 구현 완료 -- **크로스 플랫폼**: ✅ Linux, macOS, Android, iOS 모든 플랫폼 지원 구조 완성 -- **자동 감지**: ✅ 최적 하드웨어 디코더 자동 선택 (nvdec → vpl → amf → dav1d) -- **소프트웨어 fallback**: ✅ 하드웨어 미지원 시 dav1d 자동 전환 - -### **🎮 Godot 4.4.1 통합 (완료)** -- **VavCore C API**: ✅ 28개 vavcore_* 함수 완전 구현 및 DLL 빌드 성공 -- **VavCore.Wrapper**: ✅ P/Invoke C# 래퍼 완전 구현 (빌드 성공) -- **Zero-Copy GPU Pipeline**: ✅ 플랫폼별 GPU Surface 직접 바인딩 구현 -- **CPU Fallback 시스템**: ✅ 저사양 디바이스용 완전한 소프트웨어 렌더링 -- **이중 렌더링 모드**: ✅ GPU Surface + CPU ImageTexture 양방향 지원 - -### **🔧 크로스 플랫폼 아키텍처 (완료)** -- **VavCore.Wrapper**: ✅ 28개 C API 함수의 완전한 P/Invoke 래퍼 -- **VavCore.Godot**: ✅ Godot 전용 노드 및 유틸리티 완성 -- **플랫폼별 Surface 지원**: ✅ Vulkan, OpenGL, D3D11, Metal 모든 GPU API 지원 -- **RenderingDevice 통합**: ✅ Godot 4.4.1 RenderingDevice API 완전 활용 - -## 📁 **완성된 프로젝트 구조** - -``` -vav2/platforms/windows/godot-plugin/ # 플랫폼별 구조로 재편성 완료 -├── VavCoreGodot.sln # Visual Studio 솔루션 (빌드 성공) -├── src/ -│ ├── VavCore.Wrapper/ # ✅ P/Invoke 래퍼 (완전 구현) -│ │ ├── VavCore.Wrapper.csproj # .NET 6.0 라이브러리 (빌드 성공) -│ │ ├── VavCoreTypes.cs # ✅ C API 매칭 C# 데이터 타입 -│ │ ├── VavCoreNative.cs # ✅ 28개 P/Invoke 선언 완료 -│ │ └── VavCoreWrapper.cs # ✅ 고수준 C# 래퍼 완료 -│ └── VavCore.Godot/ # ✅ Godot Extension (완전 구현) -│ ├── VavCore.Godot.csproj # Godot 4.4.1 프로젝트 (빌드 성공) -│ ├── Nodes/ # ✅ Godot 노드들 -│ │ ├── VavCoreVideoPlayer.cs # ✅ 완전한 비디오 플레이어 -│ │ ├── VavCoreVideoTexture.cs # ✅ YUV→RGB 변환 텍스처 -│ │ └── VavCoreVideoStream.cs # ✅ 저수준 스트림 제어 -│ ├── Resources/ # ✅ Godot 리소스 -│ │ ├── VavCoreVideoFile.cs # ✅ 비디오 파일 메타데이터 -│ │ └── VavCoreDecoderSettings.cs # ✅ 디코더 설정 -│ ├── Utilities/ # ✅ 헬퍼 유틸리티 -│ │ ├── VavCoreGodotUtils.cs # ✅ 플랫폼 감지 및 최적화 -│ │ └── VavCoreImageConverter.cs # ✅ YUV→RGB 변환 최적화 -│ └── Plugin/ # ✅ 에디터 통합 -│ └── VavCorePlugin.cs # ✅ 에디터 플러그인 -├── libs/windows-x86_64/ # ✅ 네이티브 라이브러리 -│ ├── VavCore.dll # ✅ 빌드된 VavCore DLL -│ ├── dav1d.dll # ✅ dav1d 라이브러리 -│ └── [GPU 라이브러리들] # ✅ NVDEC/VPL/AMF 지원 -└── demo/ # ✅ 데모 프로젝트 - └── vavcore-demo/ # ✅ 완전 구현된 Godot 데모 -``` - -## 🚀 **설치 및 사용법** - -### **1. 필요 조건 (모두 구현 완료)** - -- **Godot 4.4.1** with C# support ✅ -- **.NET 8.0 SDK** ✅ (현재 프로젝트에서 사용 중) -- **Visual Studio 2022** ✅ (빌드 환경 구성 완료) -- **VavCore 라이브러리**: ✅ 완전 구현 및 빌드 완료 -- **VavCore C API**: ✅ 28개 vavcore_* 함수 모두 구현 - -### **2. Extension 빌드 (검증 완료)** - -```bash -# 플랫폼별 디렉토리로 이동 -cd vav2/platforms/windows/godot-plugin/ - -# NuGet 패키지 복원 (성공 확인) -dotnet restore - -# 전체 솔루션 빌드 (성공 확인) -dotnet build --configuration Debug -dotnet build --configuration Release - -# 개별 프로젝트 빌드 -dotnet build src/VavCore.Wrapper/VavCore.Wrapper.csproj --configuration Debug -dotnet build src/VavCore.Godot/VavCore.Godot.csproj --configuration Debug - -# 빌드 결과 확인 -# → VavCore.Wrapper.dll 생성 완료 -# → VavCore.Godot.dll 생성 완료 -# → 일부 경고만 있음 (기능에 영향 없음) -``` - -### **3. Godot 프로젝트에 설치 (실제 구현됨)** - -#### **Option A: 데모 프로젝트 사용 (추천)** -```bash -# 완전 구현된 데모 프로젝트 실행 -cd godot-projects/vavcore-demo/ -# Godot 4.4.1에서 project.godot 열기 -# → VavCorePlayer 노드가 씬에 이미 설정됨 -# → Load Video, Play, Pause, Stop 버튼 모두 작동 -# → 실제 AV1 프레임 디코딩 및 렌더링 완료 -``` - -#### **Option B: 기존 프로젝트에 통합** -```xml - - - - -``` - -#### **Option C: 빌드된 DLL 직접 복사** -```bash -# 빌드된 DLL들을 Godot 프로젝트로 복사 -cp bin/Debug/VavCore.Wrapper.dll /path/to/godot/project/ -cp bin/Debug/VavCore.Godot.dll /path/to/godot/project/ - -# 네이티브 라이브러리 복사 (Windows) -cp libs/windows-x86_64/VavCore.dll /path/to/godot/project/ -cp libs/windows-x86_64/dav1d.dll /path/to/godot/project/ -``` - -## 🎮 **실제 구현된 사용 예제** - -### **완전 구현된 VavCorePlayer (실제 동작)** - -```csharp -// godot-projects/vavcore-demo/scripts/VavCorePlayer.cs - 실제 구현 파일 -using Godot; -using System; -using System.Runtime.InteropServices; - -public partial class VavCorePlayer : Control -{ - // ✅ 실제 구현된 핵심 기능들 - private IntPtr decoderHandle = IntPtr.Zero; - private Image yuvImage; - private ImageTexture yuvTexture; - private ShaderMaterial yuvMaterial; - - // ✅ 텍스처 캐싱 최적화 (실제 구현됨) - private bool isTextureInitialized = false; - - public override void _Ready() - { - GD.Print("VavCore Demo: Initializing..."); - GD.Print("Checking for VavCore Extension..."); - - // ✅ VavCore DLL 로드 확인 (실제 P/Invoke) - if (!CheckVavCoreAvailability()) - { - GD.PrintErr("VavCore Extension not available"); - return; - } - - // ✅ YUV to RGB 셰이더 로드 (실제 구현됨) - SetupYUVShader(); - - GD.Print("VavCore Player initialized successfully"); - } - - // ✅ 실제 비디오 로드 기능 (VavCore DLL 연동) - public bool LoadVideo(string filePath) - { - GD.Print($"Loading video: {filePath}"); - - // VavCore C API 호출 (실제 P/Invoke) - decoderHandle = vavcore_create_decoder(); - if (decoderHandle == IntPtr.Zero) - { - GD.PrintErr("Failed to create VavCore decoder"); - return false; - } - - // 비디오 파일 열기 - int result = vavcore_open_file(decoderHandle, filePath); - if (result != 0) - { - GD.PrintErr($"Failed to open video file: {result}"); - return false; - } - - GD.Print("Video loaded successfully"); - return true; - } - - // ✅ 실제 프레임 디코딩 및 렌더링 (GPU/CPU 하이브리드) - private void DecodeAndRenderFrame() - { - // VavCore에서 프레임 디코딩 - var frame = new VavCoreVideoFrame(); - int result = vavcore_decode_frame(decoderHandle, ref frame); - - if (result == 0) // 성공 - { - // ✅ GPU Pipeline 시도 - if (!TryGPUSurfaceRendering(frame)) - { - // ✅ CPU Fallback (완전 구현됨) - CreateYUVTextures(frame); - } - } - } - - // ✅ 실제 P/Invoke 함수들 (28개 vavcore_* 함수) - [DllImport("VavCore.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern IntPtr vavcore_create_decoder(); - - [DllImport("VavCore.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern int vavcore_open_file(IntPtr handle, string filePath); - - [DllImport("VavCore.dll", CallingConvention = CallingConvention.Cdecl)] - private static extern int vavcore_decode_frame(IntPtr handle, ref VavCoreVideoFrame frame); - - // ... 25개 추가 vavcore_* 함수들 -} -``` - -### **GPU/CPU 하이브리드 렌더링 시스템 (실제 구현됨)** - -```csharp -// ✅ Zero-Copy GPU Pipeline 구현 -private bool TryGPUSurfaceRendering(VavCoreVideoFrame frame) -{ - // 플랫폼별 GPU Surface 바인딩 시도 - var renderingServer = RenderingServer.Singleton; - var device = renderingServer.GetRenderingDevice(); - - if (device != null) - { - // Vulkan/D3D11/Metal Surface 직접 바인딩 - return UpdateGPUSurfaceTextures(frame, device); - } - - return false; // GPU 실패 시 CPU Fallback -} - -// ✅ CPU Fallback 렌더링 (완전 구현됨) -private void CreateYUVTextures(VavCoreVideoFrame frame) -{ - // 텍스처 캐싱 최적화 - if (!isTextureInitialized) - { - CreateSingleBlockYUVTexture(frame); // 단일 블록 복사 최적화 - isTextureInitialized = true; - } - else - { - UpdateYUVTexture(frame); // ImageTexture.Update() 사용 - } -} - -// ✅ 단일 블록 YUV 복사 최적화 (실제 구현됨) -private void CreateSingleBlockYUVTexture(VavCoreVideoFrame frame) -{ - // 진정한 단일 블록 복사: 1회 Buffer.MemoryCopy - uint totalSize = frame.y_size + frame.u_size + frame.v_size; - var yuvData = new byte[totalSize]; - - unsafe - { - byte* srcPtr = (byte*)frame.y_plane.ToPointer(); - fixed (byte* dstPtr = yuvData) - { - Buffer.MemoryCopy(srcPtr, dstPtr, totalSize, totalSize); - } - } - - // 전체 YUV 데이터를 하나의 1D 텍스처로 생성 - var yuvImage = Image.CreateFromData((int)totalSize, 1, false, Image.Format.R8, yuvData); - yuvTexture = ImageTexture.CreateFromImage(yuvImage); - - // 셰이더에 오프셋 정보 전달 - yuvMaterial.SetShaderParameter("yuv_texture", yuvTexture); - yuvMaterial.SetShaderParameter("y_offset", 0); - yuvMaterial.SetShaderParameter("u_offset", (int)frame.y_size); - yuvMaterial.SetShaderParameter("v_offset", (int)(frame.y_size + frame.u_size)); - yuvMaterial.SetShaderParameter("frame_width", (int)frame.width); - yuvMaterial.SetShaderParameter("frame_height", (int)frame.height); -} - -// ✅ BT.709 YUV→RGB 변환 셰이더 (실제 파일) -private void SetupYUVShader() -{ - var shader = GD.Load("res://shaders/yuv_to_rgb.gdshader"); - yuvMaterial = new ShaderMaterial(); - yuvMaterial.Shader = shader; - - // 단일 블록 + 3개 텍스처 양방향 지원 - GetNode("VideoRect").Material = yuvMaterial; -} -``` - -### **실제 하드웨어 디코더 선택 시스템 (구현 완료)** - -```csharp -// ✅ 자동 최적 디코더 선택 (실제 VavCore C API) -public bool InitializeWithOptimalDecoder() -{ - // VavCore에서 지원하는 디코더 목록 확인 - IntPtr decoders = vavcore_get_available_decoders(); - - // 우선순위: NVDEC → VPL → AMF → Media Foundation → dav1d - string[] priority = { "nvdec", "vpl", "amf", "media_foundation", "dav1d" }; - - foreach (string decoderName in priority) - { - if (vavcore_is_decoder_available(decoders, decoderName)) - { - GD.Print($"Using optimal decoder: {decoderName}"); - decoderHandle = vavcore_create_decoder_by_name(decoderName); - return decoderHandle != IntPtr.Zero; - } - } - - GD.PrintErr("No suitable decoder found"); - return false; -} - -// ✅ 플랫폼별 GPU API 지원 확인 -private bool CheckGPUAccelerationSupport() -{ - var renderingServer = RenderingServer.Singleton; - string apiName = renderingServer.GetRenderingDriverName(); - - switch (apiName) - { - case "Vulkan": - return CheckVulkanSupport(); - case "D3D11": - return CheckD3D11Support(); - case "OpenGL3": - return CheckOpenGLSupport(); - case "Metal": - return CheckMetalSupport(); - default: - GD.Print($"Unsupported GPU API: {apiName}, using CPU fallback"); - return false; - } -} - -// ✅ VavCore DLL 가용성 확인 (실제 P/Invoke) -private bool CheckVavCoreAvailability() -{ - try - { - int version = vavcore_get_version(); - GD.Print($"VavCore version: {version}"); - return version > 0; - } - catch (DllNotFoundException) - { - GD.PrintErr("VavCore.dll not found"); - return false; - } - catch (Exception ex) - { - GD.PrintErr($"VavCore initialization failed: {ex.Message}"); - return false; - } -} -``` - -### **실제 비디오 메타데이터 추출 (VavCore C API)** - -```csharp -// ✅ 실제 구현된 메타데이터 추출 함수들 -public void DisplayVideoMetadata(string filePath) -{ - IntPtr decoder = vavcore_create_decoder(); - int result = vavcore_open_file(decoder, filePath); - - if (result == 0) - { - // VavCore C API로 메타데이터 추출 - var metadata = new VavCoreVideoMetadata(); - vavcore_get_metadata(decoder, ref metadata); - - // 실제 출력되는 정보들 - GD.Print($"Resolution: {metadata.width}x{metadata.height}"); - GD.Print($"Duration: {metadata.duration_seconds:F2} seconds"); - GD.Print($"Frame rate: {metadata.frame_rate:F2} FPS"); - GD.Print($"Total frames: {metadata.total_frames}"); - GD.Print($"Codec: {Marshal.PtrToStringAnsi(metadata.codec_name)}"); - - // 지원되는 디코더 목록 - IntPtr availableDecoders = vavcore_get_available_decoders(); - PrintAvailableDecoders(availableDecoders); - - vavcore_destroy_decoder(decoder); - } - else - { - GD.PrintErr($"Failed to open video file: {result}"); - } -} - -// ✅ 실제 데이터 구조체 (VavCore C API 매칭) -[StructLayout(LayoutKind.Sequential)] -public struct VavCoreVideoMetadata -{ - public uint width; - public uint height; - public double frame_rate; - public double duration_seconds; - public ulong total_frames; - public IntPtr codec_name; // char* - public uint format; // YUV format -} - -// ✅ Main.cs - 실제 UI 연동 (완전 구현됨) -public partial class Main : Control -{ - private VavCorePlayer player; - - private void OnLoadButtonPressed() - { - // 실제 파일 다이얼로그는 현재 하드코딩 - string testVideoPath = "D:/Project/video-av1/sample/simple_test.webm"; - - if (player.LoadVideo(testVideoPath)) - { - GetNode