threaded video decoding
parent
0f9511f0f6
commit
1954665c93
|
@ -10,19 +10,18 @@ namespace MoonWorks.Video
|
|||
|
||||
public int Width => width;
|
||||
public int Height => height;
|
||||
public double FramesPerSecond => 28.97;
|
||||
public double FramesPerSecond { get; set; }
|
||||
public Dav1dfile.PixelLayout PixelLayout => pixelLayout;
|
||||
public int UVWidth { get; }
|
||||
public int UVHeight { get; }
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
private double fps;
|
||||
private Dav1dfile.PixelLayout pixelLayout;
|
||||
|
||||
bool IsDisposed;
|
||||
|
||||
public VideoAV1(string filename)
|
||||
public VideoAV1(string filename, double framesPerSecond)
|
||||
{
|
||||
if (!File.Exists(filename))
|
||||
{
|
||||
|
@ -55,6 +54,8 @@ namespace MoonWorks.Video
|
|||
{
|
||||
throw new NotSupportedException("Unrecognized YUV format!");
|
||||
}
|
||||
|
||||
FramesPerSecond = framesPerSecond;
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
|
|
|
@ -21,17 +21,26 @@ namespace MoonWorks.Video
|
|||
private Texture vTexture = null;
|
||||
private Sampler LinearSampler;
|
||||
|
||||
private object readLock = new object();
|
||||
private bool frameDataUpdated;
|
||||
|
||||
private IntPtr yDataHandle;
|
||||
private IntPtr uDataHandle;
|
||||
private IntPtr vDataHandle;
|
||||
private uint yDataLength;
|
||||
private uint uvDataLength;
|
||||
private uint yStride;
|
||||
private uint uvStride;
|
||||
|
||||
private int currentFrame;
|
||||
|
||||
private Stopwatch timer;
|
||||
private double lastTimestamp;
|
||||
private double timeElapsed;
|
||||
|
||||
private Stopwatch profilingTimer = new Stopwatch();
|
||||
|
||||
private bool disposed;
|
||||
|
||||
public VideoPlayer(GraphicsDevice graphicsDevice, AudioDevice audioDevice)
|
||||
public VideoPlayer(GraphicsDevice graphicsDevice)
|
||||
{
|
||||
GraphicsDevice = graphicsDevice;
|
||||
if (GraphicsDevice.VideoPipeline == null)
|
||||
|
@ -154,11 +163,6 @@ namespace MoonWorks.Video
|
|||
Video = null;
|
||||
}
|
||||
|
||||
public void Update()
|
||||
{
|
||||
if (Video == null) { return; }
|
||||
}
|
||||
|
||||
public void Render()
|
||||
{
|
||||
if (Video == null || State == VideoState.Stopped)
|
||||
|
@ -172,27 +176,13 @@ namespace MoonWorks.Video
|
|||
int thisFrame = ((int) (timeElapsed / (1000.0 / Video.FramesPerSecond)));
|
||||
if (thisFrame > currentFrame)
|
||||
{
|
||||
profilingTimer.Restart();
|
||||
int readResult = Dav1dfile.df_readvideo(
|
||||
Video.Handle,
|
||||
thisFrame - currentFrame,
|
||||
out var yData,
|
||||
out var uData,
|
||||
out var vData,
|
||||
out var yDataLength,
|
||||
out var uvDataLength,
|
||||
out var yStride,
|
||||
out var uvStride
|
||||
);
|
||||
profilingTimer.Stop();
|
||||
System.Console.WriteLine($"Frame decoded in: {profilingTimer.Elapsed.TotalMilliseconds}");
|
||||
|
||||
if (readResult == 1 || currentFrame == -1)
|
||||
if (frameDataUpdated)
|
||||
{
|
||||
UpdateRenderTexture(yData, uData, vData, yDataLength, uvDataLength, yStride, uvStride);
|
||||
UpdateRenderTexture();
|
||||
}
|
||||
|
||||
currentFrame = thisFrame;
|
||||
System.Threading.Tasks.Task.Run(ReadNextFrame);
|
||||
}
|
||||
|
||||
bool ended = Dav1dfile.df_eos(Video.Handle) == 1;
|
||||
|
@ -217,39 +207,42 @@ namespace MoonWorks.Video
|
|||
}
|
||||
}
|
||||
|
||||
private void UpdateRenderTexture(IntPtr yData, IntPtr uData, IntPtr vData, uint yDataLength, uint uvDataLength, uint yStride, uint uvStride)
|
||||
private void UpdateRenderTexture()
|
||||
{
|
||||
var commandBuffer = GraphicsDevice.AcquireCommandBuffer();
|
||||
lock (readLock)
|
||||
{
|
||||
var commandBuffer = GraphicsDevice.AcquireCommandBuffer();
|
||||
|
||||
commandBuffer.SetTextureDataYUV(
|
||||
yTexture,
|
||||
uTexture,
|
||||
vTexture,
|
||||
yData,
|
||||
uData,
|
||||
vData,
|
||||
yDataLength,
|
||||
uvDataLength,
|
||||
yStride,
|
||||
uvStride
|
||||
);
|
||||
commandBuffer.SetTextureDataYUV(
|
||||
yTexture,
|
||||
uTexture,
|
||||
vTexture,
|
||||
yDataHandle,
|
||||
uDataHandle,
|
||||
vDataHandle,
|
||||
yDataLength,
|
||||
uvDataLength,
|
||||
yStride,
|
||||
uvStride
|
||||
);
|
||||
|
||||
commandBuffer.BeginRenderPass(
|
||||
new ColorAttachmentInfo(RenderTexture, Color.Black)
|
||||
);
|
||||
commandBuffer.BeginRenderPass(
|
||||
new ColorAttachmentInfo(RenderTexture, Color.Black)
|
||||
);
|
||||
|
||||
commandBuffer.BindGraphicsPipeline(GraphicsDevice.VideoPipeline);
|
||||
commandBuffer.BindFragmentSamplers(
|
||||
new TextureSamplerBinding(yTexture, LinearSampler),
|
||||
new TextureSamplerBinding(uTexture, LinearSampler),
|
||||
new TextureSamplerBinding(vTexture, LinearSampler)
|
||||
);
|
||||
commandBuffer.BindGraphicsPipeline(GraphicsDevice.VideoPipeline);
|
||||
commandBuffer.BindFragmentSamplers(
|
||||
new TextureSamplerBinding(yTexture, LinearSampler),
|
||||
new TextureSamplerBinding(uTexture, LinearSampler),
|
||||
new TextureSamplerBinding(vTexture, LinearSampler)
|
||||
);
|
||||
|
||||
commandBuffer.DrawPrimitives(0, 1, 0, 0);
|
||||
commandBuffer.DrawPrimitives(0, 1, 0, 0);
|
||||
|
||||
commandBuffer.EndRenderPass();
|
||||
commandBuffer.EndRenderPass();
|
||||
|
||||
GraphicsDevice.Submit(commandBuffer);
|
||||
GraphicsDevice.Submit(commandBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
private static Texture CreateRenderTexture(GraphicsDevice graphicsDevice, int width, int height)
|
||||
|
@ -276,20 +269,30 @@ namespace MoonWorks.Video
|
|||
|
||||
private void InitializeDav1dStream()
|
||||
{
|
||||
// Grab the first video frame ASAP.
|
||||
Dav1dfile.df_readvideo(
|
||||
Video.Handle,
|
||||
1,
|
||||
out var _,
|
||||
out var _,
|
||||
out var _,
|
||||
out var _,
|
||||
out var _,
|
||||
out var _,
|
||||
out var _);
|
||||
System.Threading.Tasks.Task.Run(ReadNextFrame);
|
||||
currentFrame = -1;
|
||||
}
|
||||
|
||||
private void ReadNextFrame()
|
||||
{
|
||||
lock (readLock)
|
||||
{
|
||||
if (Dav1dfile.df_readvideo(
|
||||
Video.Handle,
|
||||
1,
|
||||
out yDataHandle,
|
||||
out uDataHandle,
|
||||
out vDataHandle,
|
||||
out yDataLength,
|
||||
out uvDataLength,
|
||||
out yStride,
|
||||
out uvStride) == 1
|
||||
) {
|
||||
frameDataUpdated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposed)
|
||||
|
|
Loading…
Reference in New Issue