diff --git a/src/Video/Video.cs b/src/Video/Video.cs index 4ca357d..34c9cfe 100644 --- a/src/Video/Video.cs +++ b/src/Video/Video.cs @@ -17,6 +17,8 @@ namespace MoonWorks.Video public unsafe class Video : IDisposable { internal IntPtr Handle; + private IntPtr rwData; + private void* videoData; public bool Loop { get; private set; } public float Volume { @@ -71,7 +73,12 @@ namespace MoonWorks.Video throw new ArgumentException("Video file not found!"); } - if (Theorafile.tf_fopen(filename, out Handle) < 0) + var bytes = System.IO.File.ReadAllBytes(filename); + videoData = NativeMemory.Alloc((nuint) bytes.Length); + Marshal.Copy(bytes, 0, (IntPtr) videoData, bytes.Length); + rwData = SDL2.SDL.SDL_RWFromMem((IntPtr) videoData, bytes.Length); + + if (Theorafile.tf_open_callbacks(rwData, out Handle, callbacks) < 0) { throw new ArgumentException("Invalid video file!"); } @@ -317,6 +324,17 @@ namespace MoonWorks.Video currentFrame = -1; } + private static IntPtr Read(IntPtr ptr, IntPtr size, IntPtr nmemb, IntPtr datasource) => (IntPtr) SDL2.SDL.SDL_RWread(datasource, ptr, size, nmemb); + private static int Seek(IntPtr datasource, long offset, Theorafile.SeekWhence whence) => (int) SDL2.SDL.SDL_RWseek(datasource, offset, (int) whence); + private static int Close(IntPtr datasource) => (int) SDL2.SDL.SDL_RWclose(datasource); + + private static Theorafile.tf_callbacks callbacks = new Theorafile.tf_callbacks + { + read_func = Read, + seek_func = Seek, + close_func = Close + }; + protected virtual void Dispose(bool disposing) { if (!disposed) @@ -332,6 +350,7 @@ namespace MoonWorks.Video // free unmanaged resources (unmanaged objects) Theorafile.tf_close(ref Handle); NativeMemory.Free(yuvData); + NativeMemory.Free(videoData); disposed = true; } diff --git a/src/Video/VideoData.cs b/src/Video/VideoData.cs new file mode 100644 index 0000000..e69de29