Setup entry point + integrated moonworks stuff
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using Nerfed.Runtime.Graphics;
|
||||
|
||||
namespace Nerfed.Runtime.Video;
|
||||
|
||||
// Note that all public methods are async.
|
||||
internal class VideoAV1Stream : GraphicsResource
|
||||
{
|
||||
public IntPtr Handle => handle;
|
||||
IntPtr handle;
|
||||
|
||||
public bool Loaded => handle != IntPtr.Zero;
|
||||
public bool Ended => Dav1dfile.df_eos(Handle) == 1;
|
||||
|
||||
public IntPtr yDataHandle;
|
||||
public IntPtr uDataHandle;
|
||||
public IntPtr vDataHandle;
|
||||
public uint yDataLength;
|
||||
public uint uvDataLength;
|
||||
public uint yStride;
|
||||
public uint uvStride;
|
||||
|
||||
public bool FrameDataUpdated { get; set; }
|
||||
|
||||
private BlockingCollection<Action> Actions = new BlockingCollection<Action>();
|
||||
|
||||
private bool Running = false;
|
||||
|
||||
Thread Thread;
|
||||
|
||||
public VideoAV1Stream(GraphicsDevice device) : base(device)
|
||||
{
|
||||
handle = IntPtr.Zero;
|
||||
|
||||
Running = true;
|
||||
|
||||
Thread = new Thread(ThreadMain);
|
||||
Thread.Start();
|
||||
}
|
||||
|
||||
private void ThreadMain()
|
||||
{
|
||||
while (Running)
|
||||
{
|
||||
// block until we can take an action, then run it
|
||||
Action action = Actions.Take();
|
||||
action.Invoke();
|
||||
}
|
||||
|
||||
// shutting down...
|
||||
while (Actions.TryTake(out Action action))
|
||||
{
|
||||
action.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
public void Load(string filename)
|
||||
{
|
||||
Actions.Add(() => LoadHelper(filename));
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Actions.Add(ResetHelper);
|
||||
}
|
||||
|
||||
public void ReadNextFrame()
|
||||
{
|
||||
Actions.Add(ReadNextFrameHelper);
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
Actions.Add(UnloadHelper);
|
||||
}
|
||||
|
||||
private void LoadHelper(string filename)
|
||||
{
|
||||
if (!Loaded)
|
||||
{
|
||||
if (Dav1dfile.df_fopen(filename, out handle) == 0)
|
||||
{
|
||||
Log.Error("Failed to load video file: " + filename);
|
||||
throw new Exception("Failed to load video file!");
|
||||
}
|
||||
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetHelper()
|
||||
{
|
||||
if (Loaded)
|
||||
{
|
||||
Dav1dfile.df_reset(handle);
|
||||
ReadNextFrame();
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadNextFrameHelper()
|
||||
{
|
||||
if (Loaded && !Ended)
|
||||
{
|
||||
lock (this)
|
||||
{
|
||||
if (Dav1dfile.df_readvideo(
|
||||
handle,
|
||||
1,
|
||||
out IntPtr yDataHandle,
|
||||
out IntPtr uDataHandle,
|
||||
out IntPtr vDataHandle,
|
||||
out uint yDataLength,
|
||||
out uint uvDataLength,
|
||||
out uint yStride,
|
||||
out uint uvStride) == 1
|
||||
) {
|
||||
this.yDataHandle = yDataHandle;
|
||||
this.uDataHandle = uDataHandle;
|
||||
this.vDataHandle = vDataHandle;
|
||||
this.yDataLength = yDataLength;
|
||||
this.uvDataLength = uvDataLength;
|
||||
this.yStride = yStride;
|
||||
this.uvStride = uvStride;
|
||||
|
||||
FrameDataUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UnloadHelper()
|
||||
{
|
||||
if (Loaded)
|
||||
{
|
||||
Dav1dfile.df_close(handle);
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (!IsDisposed)
|
||||
{
|
||||
Unload();
|
||||
Running = false;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Thread.Join();
|
||||
}
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user