drop Theorafile

pull/49/head
cosmonaut 2023-06-07 14:10:48 -07:00
parent c70560025d
commit e1f934d445
7 changed files with 10 additions and 200 deletions

3
.gitmodules vendored
View File

@ -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

View File

@ -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

View File

@ -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() { }
}
}

View File

@ -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);
}
}
}

9
src/Video/VideoState.cs Normal file
View File

@ -0,0 +1,9 @@
namespace MoonWorks.Video
{
public enum VideoState
{
Playing,
Paused,
Stopped
}
}