drop Theorafile
parent
c70560025d
commit
e1f934d445
|
@ -10,9 +10,6 @@
|
||||||
[submodule "lib/WellspringCS"]
|
[submodule "lib/WellspringCS"]
|
||||||
path = lib/WellspringCS
|
path = lib/WellspringCS
|
||||||
url = https://gitea.moonside.games/MoonsideGames/WellspringCS.git
|
url = https://gitea.moonside.games/MoonsideGames/WellspringCS.git
|
||||||
[submodule "lib/Theorafile"]
|
|
||||||
path = lib/Theorafile
|
|
||||||
url = https://github.com/FNA-XNA/Theorafile.git
|
|
||||||
[submodule "lib/dav1dfile"]
|
[submodule "lib/dav1dfile"]
|
||||||
path = lib/dav1dfile
|
path = lib/dav1dfile
|
||||||
url = git@github.com:MoonsideGames/dav1dfile.git
|
url = git@github.com:MoonsideGames/dav1dfile.git
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
<Compile Include="lib\FAudio\csharp\FAudio.cs" />
|
<Compile Include="lib\FAudio\csharp\FAudio.cs" />
|
||||||
<Compile Include="lib\RefreshCS\src\Refresh.cs" />
|
<Compile Include="lib\RefreshCS\src\Refresh.cs" />
|
||||||
<Compile Include="lib\SDL2-CS\src\SDL2.cs" />
|
<Compile Include="lib\SDL2-CS\src\SDL2.cs" />
|
||||||
<Compile Include="lib\Theorafile\csharp\Theorafile.cs" />
|
|
||||||
<Compile Include="lib\WellspringCS\WellspringCS.cs" />
|
<Compile Include="lib\WellspringCS\WellspringCS.cs" />
|
||||||
<Compile Include="lib\dav1dfile\csharp\dav1dfile.cs" />
|
<Compile Include="lib\dav1dfile\csharp\dav1dfile.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 8f9419ea856480e08294698e1d6be8752df3710b
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 8ba817ff9bf65ed2fa7b9c12d70112b29c450cf4
|
Subproject commit 859f47f6fa0dfa0f7f941dcced6664fa83736202
|
|
@ -1,67 +0,0 @@
|
||||||
using System;
|
|
||||||
using MoonWorks.Audio;
|
|
||||||
|
|
||||||
namespace MoonWorks.Video
|
|
||||||
{
|
|
||||||
// TODO: should we just not handle theora sound? it sucks!
|
|
||||||
internal unsafe class StreamingSoundTheora : StreamingSound
|
|
||||||
{
|
|
||||||
private IntPtr VideoHandle;
|
|
||||||
public override bool Loaded => true;
|
|
||||||
|
|
||||||
internal StreamingSoundTheora(
|
|
||||||
AudioDevice device,
|
|
||||||
IntPtr videoHandle,
|
|
||||||
int channels,
|
|
||||||
uint sampleRate,
|
|
||||||
uint bufferSize = 8192
|
|
||||||
) : base(
|
|
||||||
device,
|
|
||||||
3, /* float type */
|
|
||||||
32, /* size of float */
|
|
||||||
(ushort) (4 * channels),
|
|
||||||
(ushort) channels,
|
|
||||||
sampleRate,
|
|
||||||
bufferSize,
|
|
||||||
false // Theorafile is not thread safe, so let's update on the main thread
|
|
||||||
) {
|
|
||||||
VideoHandle = videoHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override unsafe void Load()
|
|
||||||
{
|
|
||||||
// no-op
|
|
||||||
}
|
|
||||||
|
|
||||||
public override unsafe void Unload()
|
|
||||||
{
|
|
||||||
// no-op
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override unsafe void FillBuffer(
|
|
||||||
void* buffer,
|
|
||||||
int bufferLengthInBytes,
|
|
||||||
out int filledLengthInBytes,
|
|
||||||
out bool reachedEnd
|
|
||||||
) {
|
|
||||||
var lengthInFloats = bufferLengthInBytes / sizeof(float);
|
|
||||||
|
|
||||||
// FIXME: this gets gnarly with theorafile being not thread safe
|
|
||||||
// is there some way we could just manually update in VideoPlayer
|
|
||||||
// instead of going through AudioDevice?
|
|
||||||
lock (Device.StateLock)
|
|
||||||
{
|
|
||||||
int samples = Theorafile.tf_readaudio(
|
|
||||||
VideoHandle,
|
|
||||||
(IntPtr) buffer,
|
|
||||||
lengthInFloats
|
|
||||||
);
|
|
||||||
|
|
||||||
filledLengthInBytes = samples * sizeof(float);
|
|
||||||
reachedEnd = Theorafile.tf_eos(VideoHandle) == 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void OnReachedEnd() { }
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,127 +0,0 @@
|
||||||
/* Heavily based on https://github.com/FNA-XNA/FNA/blob/master/src/Media/Xiph/VideoPlayer.cs */
|
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using SDL2;
|
|
||||||
|
|
||||||
namespace MoonWorks.Video
|
|
||||||
{
|
|
||||||
public enum VideoState
|
|
||||||
{
|
|
||||||
Playing,
|
|
||||||
Paused,
|
|
||||||
Stopped
|
|
||||||
}
|
|
||||||
|
|
||||||
public unsafe class Video : IDisposable
|
|
||||||
{
|
|
||||||
internal IntPtr Handle;
|
|
||||||
private IntPtr rwData;
|
|
||||||
private void* videoData;
|
|
||||||
private int videoDataLength;
|
|
||||||
|
|
||||||
public double FramesPerSecond => fps;
|
|
||||||
public int Width => yWidth;
|
|
||||||
public int Height => yHeight;
|
|
||||||
public int UVWidth { get; }
|
|
||||||
public int UVHeight { get; }
|
|
||||||
|
|
||||||
private double fps;
|
|
||||||
private int yWidth;
|
|
||||||
private int yHeight;
|
|
||||||
|
|
||||||
private bool IsDisposed;
|
|
||||||
|
|
||||||
public Video(string filename)
|
|
||||||
{
|
|
||||||
if (!File.Exists(filename))
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Video file not found!");
|
|
||||||
}
|
|
||||||
|
|
||||||
var fileStream = new FileStream(filename, FileMode.Open, FileAccess.Read);
|
|
||||||
videoDataLength = (int) fileStream.Length;
|
|
||||||
videoData = NativeMemory.Alloc((nuint) videoDataLength);
|
|
||||||
var fileBufferSpan = new Span<byte>(videoData, videoDataLength);
|
|
||||||
fileStream.ReadExactly(fileBufferSpan);
|
|
||||||
fileStream.Close();
|
|
||||||
|
|
||||||
rwData = SDL.SDL_RWFromMem((IntPtr) videoData, videoDataLength);
|
|
||||||
if (Theorafile.tf_open_callbacks(rwData, out Handle, callbacks) < 0)
|
|
||||||
{
|
|
||||||
throw new ArgumentException("Invalid video file!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Theorafile.th_pixel_fmt format;
|
|
||||||
Theorafile.tf_videoinfo(
|
|
||||||
Handle,
|
|
||||||
out yWidth,
|
|
||||||
out yHeight,
|
|
||||||
out fps,
|
|
||||||
out format
|
|
||||||
);
|
|
||||||
|
|
||||||
if (format == Theorafile.th_pixel_fmt.TH_PF_420)
|
|
||||||
{
|
|
||||||
UVWidth = Width / 2;
|
|
||||||
UVHeight = Height / 2;
|
|
||||||
}
|
|
||||||
else if (format == Theorafile.th_pixel_fmt.TH_PF_422)
|
|
||||||
{
|
|
||||||
UVWidth = Width / 2;
|
|
||||||
UVHeight = Height;
|
|
||||||
}
|
|
||||||
else if (format == Theorafile.th_pixel_fmt.TH_PF_444)
|
|
||||||
{
|
|
||||||
UVWidth = Width;
|
|
||||||
UVHeight = Height;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw new NotSupportedException("Unrecognized YUV format!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (!IsDisposed)
|
|
||||||
{
|
|
||||||
if (disposing)
|
|
||||||
{
|
|
||||||
// dispose managed state (managed objects)
|
|
||||||
}
|
|
||||||
|
|
||||||
// free unmanaged resources (unmanaged objects)
|
|
||||||
Theorafile.tf_close(ref Handle);
|
|
||||||
SDL.SDL_RWclose(rwData);
|
|
||||||
NativeMemory.Free(videoData);
|
|
||||||
|
|
||||||
IsDisposed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~Video()
|
|
||||||
{
|
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
|
||||||
Dispose(disposing: false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Dispose()
|
|
||||||
{
|
|
||||||
// Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
|
|
||||||
Dispose(disposing: true);
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace MoonWorks.Video
|
||||||
|
{
|
||||||
|
public enum VideoState
|
||||||
|
{
|
||||||
|
Playing,
|
||||||
|
Paused,
|
||||||
|
Stopped
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue