drop Theorafile
parent
c70560025d
commit
e1f934d445
|
@ -10,9 +10,6 @@
|
|||
[submodule "lib/WellspringCS"]
|
||||
path = lib/WellspringCS
|
||||
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"]
|
||||
path = lib/dav1dfile
|
||||
url = git@github.com:MoonsideGames/dav1dfile.git
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
<Compile Include="lib\FAudio\csharp\FAudio.cs" />
|
||||
<Compile Include="lib\RefreshCS\src\Refresh.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\dav1dfile\csharp\dav1dfile.cs" />
|
||||
</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