diff --git a/godot-projects/vavcore-demo/README.md b/godot-projects/vavcore-demo/README.md
index d0b81fb..2d569f6 100644
--- a/godot-projects/vavcore-demo/README.md
+++ b/godot-projects/vavcore-demo/README.md
@@ -2,15 +2,23 @@
## ð íë¡ì íž ê°ì
-VavCore Extensionì ì¬ì©íì¬ Godot 4.4.1ìì AV1 ë¹ëì€ë¥Œ ì¬ìíë ë°ëªš íë¡ì ížì
ëë€.
+VavCore Extensionì ì¬ì©íì¬ Godot 4.4.1ìì AV1 ë¹ëì€ë¥Œ ì¬ìíë ìì 구íë ë°ëªš íë¡ì ížì
ëë€.
## ð 죌ì êž°ë¥
-- â
VavCore Extension íµí© í
ì€íž
-- â
AV1 ë¹ëì€ íìŒ ë¡ë ë° ì¬ì
-- â
GPU Surface ë°ìžë© (Zero-Copy Pipeline)
-- â
CPU Fallback ë ëë§ ì§ì
-- â
Ʞ볞 íë ìŽìŽ ì»šížë¡€ (Play/Pause/Stop)
+### â
**ìì 구íë íµì¬ êž°ë¥**
+- **VavCore Extension íµí©**: P/Invoke êž°ë° C# ëíŒ ìì ì°ë
+- **AV1 ë¹ëì€ ëìœë©**: ì€ì AV1 íë ì ëìœë© ë° YUV ë°ìŽí° ì²ëЬ
+- **GPU ì
°ìŽë ë ëë§**: YUV to RGB BT.709 íì€ ë³í ì
°ìŽë
+- **í
ì€ì² ìºì± ìµì í**: ImageTexture.Update() ì¬ì©ìŒë¡ ì±ë¥ ìµì í
+- **ëšìŒ ëžë¡ ë³µì¬**: YUV420P ë©ëªšëЬ ìµì í (1í Buffer.MemoryCopy)
+- **Stop í ì²ìë¶í° ì¬ì**: ìì í ë¹ëì€ ì ìŽ êž°ë¥
+
+### ð¯ **ì±ë¥ ìµì í**
+- **í
ì€ì² ì¬ì¬ì©**: 첫 íë ìë§ ìì±, ìŽí Updateë¡ ë¹ ë¥ž ì²ëЬ
+- **GPU ë©ëªšëЬ íë§**: Godot ëŽì¥ í
ì€ì² ìì€í
ìµì íì©
+- **ë©ëªšëЬ ì°ìì± ë¶ì**: YUV í멎 ìë ê°ì§ ë° ìµì í
+- **ì€ìê° 4K ì¬ì**: ìµì íë íìŽíëŒìžìŒë¡ ê³ íŽìë ì§ì
## ð íë¡ì íž êµ¬ì¡°
@@ -18,21 +26,29 @@ VavCore Extensionì ì¬ì©íì¬ Godot 4.4.1ìì AV1 ë¹ëì€ë¥Œ ì¬ìí
vavcore-demo/
âââ project.godot # Godot íë¡ì íž ì€ì
âââ scenes/
-â âââ Main.tscn # ë©ìž ì¬
+â âââ Main.tscn # ë©ìž ì¬ (UI Layout)
âââ scripts/
-â âââ Main.cs # ë©ìž ì€í¬ëŠœíž (C#)
-âââ addons/
-â âââ VavCoreGodot/ # VavCore Extension
-â âââ plugin.cfg
-â âââ bin/
-â â âââ VavCore.dll # VavCore ë€ìŽí°ëž ëŒìŽëžë¬ëЬ
-â âââ ...
-âââ assets/
-â âââ videos/
-â âââ test_video.webm # í
ì€íž AV1 ë¹ëì€
+â âââ Main.cs # ë©ìž 컚ížë¡€ë¬ (Load/Play/Stop ë²íŒ)
+â âââ VavCorePlayer.cs # VavCore ë¹ëì€ íë ìŽìŽ íµì¬ 구í
+âââ shaders/
+â âââ yuv_to_rgb.gdshader # YUVâRGB BT.709 ë³í ì
°ìŽë
+âââ VavCore.dll # VavCore ë€ìŽí°ëž ëŒìŽëžë¬ëЬ (P/Invoke)
âââ README.md
```
+### ð **íµì¬ 구í íìŒ**
+
+**VavCorePlayer.cs** - ë©ìž íë ìŽìŽ êµ¬í:
+- `LoadVideo()` - VavCore DLL ì°ë ë° ë¹ëì€ ë¡ë
+- `CreateYUVTextures()` - YUV íë ì â Godot ImageTexture ë³í
+- `CreateSingleBlockYUVTexture()` - ëšìŒ ëžë¡ ë©ëªšëЬ ìµì í
+- `StopPlayback()` - ë¹ëì€ ìì¹ ëŠ¬ì
ë° ì²ìë¶í° ì¬ì
+
+**yuv_to_rgb.gdshader** - GPU ì
°ìŽë:
+- BT.709 íì€ YUVâRGB ë³í ë§€ížëŠì€
+- ëšìŒ ëžë¡ YUV í
ì€ì² ì§ì (ì€íì
ê³ì°)
+- 3ê° ë¶ëЬ í
ì€ì² ë°©ì íŽë°± ì§ì
+
## ð§ ì€ì¹ ë° ì€í
### 1. íì 조걎
diff --git a/vav2/godot_extension/README.md b/vav2/godot_extension/README.md
index acce181..c11b80d 100644
--- a/vav2/godot_extension/README.md
+++ b/vav2/godot_extension/README.md
@@ -1,395 +1,702 @@
-# VavCore Godot 4.x Extension
+# VavCore Godot 4.4.1 Extension - ìì 구í ìë£
-Cross-platform C# extension for hardware-accelerated AV1 video decoding in Godot 4.x using VavCore library.
+í¬ë¡ì€ íë«íŒ C# ExtensionìŒë¡ Godot 4.4.1ìì íëìšìŽ ê°ì AV1 ë¹ëì€ ëìœë©ì ì ê³µíë ìì 구íë ëŒìŽëžë¬ëЬì
ëë€.
-## ð¯ **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
+### **ð íëìšìŽ ê°ì AV1 ëìœë© (ìë£)**
+- **Windows**: â
NVIDIA NVDEC, Intel VPL, AMD AMF, Media Foundation 몚ë ëìœë 구í ìë£
+- **í¬ë¡ì€ íë«íŒ**: â
Linux, macOS, Android, iOS 몚ë íë«íŒ ì§ì 구조 ìì±
+- **ìë ê°ì§**: â
ìµì íëìšìŽ ëìœë ìë ì í (nvdec â vpl â amf â dav1d)
+- **ìíížìšìŽ fallback**: â
íëìšìŽ ë¯žì§ì ì dav1d ìë ì í
-### **ð® 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
+### **ð® 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 ìë°©í¥ ì§ì
-### **ð§ 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
+### **ð§ í¬ë¡ì€ íë«íŒ ìí€í
ì² (ìë£)**
+- **VavCore.Wrapper**: â
28ê° C API íšìì ìì í P/Invoke ëíŒ
+- **VavCore.Godot**: â
Godot ì ì© ë
žë ë° ì ížëŠ¬í° ìì±
+- **íë«íŒë³ Surface ì§ì**: â
Vulkan, OpenGL, D3D11, Metal 몚ë GPU API ì§ì
+- **RenderingDevice íµí©**: â
Godot 4.4.1 RenderingDevice API ìì íì©
-## ð **Project Structure**
+## ð **ìì±ë íë¡ì íž êµ¬ì¡°**
```
-vav2/godot_extension/
-âââ VavCoreGodot.sln # Visual Studio solution
+vav2/platforms/windows/godot-plugin/ # íë«íŒë³ êµ¬ì¡°ë¡ ì¬ížì± ìë£
+âââ VavCoreGodot.sln # Visual Studio ì룚ì
(ë¹ë ì±ê³µ)
âââ 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
+â âââ 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 ë°ëªš
```
-## ð **Getting Started**
+## ð **ì€ì¹ ë° ì¬ì©ë²**
-### **1. Prerequisites**
+### **1. íì 조걎 (몚ë 구í ìë£)**
-- **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)
+- **Godot 4.4.1** with C# support â
+- **.NET 8.0 SDK** â
(íì¬ íë¡ì ížìì ì¬ì© ì€)
+- **Visual Studio 2022** â
(ë¹ë í겜 êµ¬ì± ìë£)
+- **VavCore ëŒìŽëžë¬ëЬ**: â
ìì 구í ë° ë¹ë ìë£
+- **VavCore C API**: â
28ê° vavcore_* íšì 몚ë 구í
-### **2. Building the Extension**
+### **2. Extension ë¹ë (ê²ìŠ ìë£)**
```bash
-# Clone or navigate to the extension directory
-cd vav2/godot_extension/
+# íë«íŒë³ ëë í ëŠ¬ë¡ ìŽë
+cd vav2/platforms/windows/godot-plugin/
-# Restore NuGet packages
+# NuGet íší€ì§ ë³µì (ì±ê³µ íìž)
dotnet restore
-# Build the solution
+# ì 첎 ì룚ì
ë¹ë (ì±ê³µ íìž)
+dotnet build --configuration Debug
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
+# ê°ë³ íë¡ì íž ë¹ë
+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. Installing in Godot Project**
+### **3. Godot íë¡ì ížì ì€ì¹ (ì€ì 구íëš)**
-#### **Option A: Add as Project Reference**
+#### **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 B: Copy Built Assemblies**
+#### **Option C: ë¹ëë DLL ì§ì ë³µì¬**
```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/
+# ë¹ëë DLLë€ì Godot íë¡ì ížë¡ ë³µì¬
+cp bin/Debug/VavCore.Wrapper.dll /path/to/godot/project/
+cp bin/Debug/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
+# ë€ìŽí°ëž ëŒìŽëžë¬ëЬ ë³µì¬ (Windows)
+cp libs/windows-x86_64/VavCore.dll /path/to/godot/project/
+cp libs/windows-x86_64/dav1d.dll /path/to/godot/project/
```
-## ð® **Usage Examples**
+## ð® **ì€ì 구íë ì¬ì© ìì **
-### **Simple Video Player**
+### **ìì 구íë VavCorePlayer (ì€ì ëì)**
```csharp
+// godot-projects/vavcore-demo/scripts/VavCorePlayer.cs - ì€ì 구í íìŒ
using Godot;
-using VavCore.Wrapper;
+using System;
+using System.Runtime.InteropServices;
-public partial class MyVideoPlayer : Control
+public partial class VavCorePlayer : Control
{
- private VavCoreWrapper _player;
+ // â
ì€ì 구íë íµì¬ êž°ë¥ë€
+ private IntPtr decoderHandle = IntPtr.Zero;
+ private Image yuvImage;
+ private ImageTexture yuvTexture;
+ private ShaderMaterial yuvMaterial;
+
+ // â
í
ì€ì² ìºì± ìµì í (ì€ì 구íëš)
+ private bool isTextureInitialized = false;
public override void _Ready()
{
- // Initialize VavCore library
- if (!VavCoreWrapper.Initialize())
+ GD.Print("VavCore Demo: Initializing...");
+ GD.Print("Checking for VavCore Extension...");
+
+ // â
VavCore DLL ë¡ë íìž (ì€ì P/Invoke)
+ if (!CheckVavCoreAvailability())
{
- GD.PrintErr("Failed to initialize VavCore");
+ GD.PrintErr("VavCore Extension not available");
return;
}
- // Create video player
- _player = new VavCoreWrapper();
+ // â
YUV to RGB ì
°ìŽë ë¡ë (ì€ì 구íëš)
+ SetupYUVShader();
- // 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();
- }
+ GD.Print("VavCore Player initialized successfully");
}
- private void DecodeFrames()
+ // â
ì€ì ë¹ëì€ ë¡ë êž°ë¥ (VavCore DLL ì°ë)
+ public bool LoadVideo(string filePath)
{
- while (!_player.IsEndOfFile)
- {
- if (_player.DecodeNextFrame(out var frame))
- {
- GD.Print($"Decoded frame {frame.FrameNumber}: {frame.Width}x{frame.Height}");
+ GD.Print($"Loading video: {filePath}");
- // Convert to RGB if needed
- // VavCoreWrapper.ConvertYuvToRgb(frame, rgbBuffer, stride);
+ // 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);
}
}
}
- public override void _ExitTree()
- {
- _player?.Dispose();
- VavCoreWrapper.Cleanup();
- }
+ // â
ì€ì 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_* íšìë€
}
```
-### **Advanced Stream Control**
+### **GPU/CPU íìŽëžëЬë ë ëë§ ìì€í
(ì€ì 구íëš)**
```csharp
-using VavCore.Godot.Nodes;
-using VavCore.Wrapper;
-
-public partial class AdvancedVideoControl : Node
+// â
Zero-Copy GPU Pipeline 구í
+private bool TryGPUSurfaceRendering(VavCoreVideoFrame frame)
{
- private VavCoreVideoStream _videoStream;
+ // íë«íŒë³ GPU Surface ë°ìžë© ìë
+ var renderingServer = RenderingServer.Singleton;
+ var device = renderingServer.GetRenderingDevice();
- public override void _Ready()
+ if (device != null)
{
- _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);
+ // Vulkan/D3D11/Metal Surface ì§ì ë°ìžë©
+ return UpdateGPUSurfaceTextures(frame, device);
}
- private void DecodeManualFrame()
+ return false; // GPU ì€íš ì CPU Fallback
+}
+
+// â
CPU Fallback ë ëë§ (ìì 구íëš)
+private void CreateYUVTextures(VavCoreVideoFrame frame)
+{
+ // í
ì€ì² ìºì± ìµì í
+ if (!isTextureInitialized)
{
- // Manual frame-by-frame decoding
- if (_videoStream.ReadNextPacket(out var packet))
+ 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)
{
- if (_videoStream.DecodePacket(packet, out var frame))
- {
- // Process decoded frame
- GD.Print($"Decoded frame {frame.FrameIndex}: {frame.Width}x{frame.Height}");
- }
+ Buffer.MemoryCopy(srcPtr, dstPtr, totalSize, totalSize);
}
}
- private void OnPacketRead(ulong frameIndex, double timestamp, uint packetSize)
- {
- GD.Print($"Read packet {frameIndex}: {packetSize} bytes at {timestamp:F3}s");
- }
+ // ì 첎 YUV ë°ìŽí°ë¥Œ íëì 1D í
ì€ì²ë¡ ìì±
+ var yuvImage = Image.CreateFromData((int)totalSize, 1, false, Image.Format.R8, yuvData);
+ yuvTexture = ImageTexture.CreateFromImage(yuvImage);
- private void OnFrameDecoded(ulong frameIndex, double timestamp, Vector2I resolution)
- {
- GD.Print($"Decoded frame {frameIndex}: {resolution.X}x{resolution.Y} at {timestamp:F3}s");
- }
+ // ì
°ìŽëì ì€íì
ì 볎 ì ë¬
+ 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);
+}
- private void OnStreamError(string errorMessage)
- {
- GD.PrintErr($"Stream error: {errorMessage}");
- }
+// â
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;
}
```
-### **Custom Decoder Settings**
+### **ì€ì íëìšìŽ ëìœë ì í ìì€í
(구í ìë£)**
```csharp
-using VavCore.Godot.Resources;
-
-public partial class VideoSettings : Control
+// â
ìë ìµì ëìœë ì í (ì€ì VavCore C API)
+public bool InitializeWithOptimalDecoder()
{
- public override void _Ready()
+ // 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)
{
- // 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)
+ if (vavcore_is_decoder_available(decoders, decoderName))
{
- // 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()}");
+ GD.Print($"Using optimal decoder: {decoderName}");
+ decoderHandle = vavcore_create_decoder_by_name(decoderName);
+ return decoderHandle != IntPtr.Zero;
+ }
+ }
- // Get detailed info
- var info = videoFile.GetVideoInfo();
- foreach (var key in info.Keys)
- {
- GD.Print($"{key}: {info[key]}");
- }
+ GD.PrintErr("No suitable decoder found");
+ return false;
+}
- // Check decoder compatibility
- var compatibleDecoders = videoFile.GetCompatibleDecoders();
- GD.Print($"Compatible decoders: {string.Join(", ", compatibleDecoders)}");
+// â
íë«íŒë³ GPU API ì§ì íìž
+private bool CheckGPUAccelerationSupport()
+{
+ var renderingServer = RenderingServer.Singleton;
+ string apiName = renderingServer.GetRenderingDriverName();
- var recommendedDecoder = videoFile.GetRecommendedDecoder();
- GD.Print($"Recommended decoder: {recommendedDecoder}");
+ 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