VideoPlayer only uses one VideoAV1Stream

threaded_video_fix
cosmonaut 2024-03-12 12:44:58 -07:00
parent 97aed05a88
commit 02f6428fce
1 changed files with 23 additions and 39 deletions

View File

@ -16,11 +16,7 @@ namespace MoonWorks.Video
public float PlaybackSpeed { get; set; } = 1; public float PlaybackSpeed { get; set; } = 1;
private VideoAV1 Video = null; private VideoAV1 Video = null;
private VideoAV1Stream CurrentStream = null; private VideoAV1Stream Stream { get; }
// "double buffering" so we can loop without a stutter
private VideoAV1Stream StreamA { get; }
private VideoAV1Stream StreamB { get; }
private Texture yTexture = null; private Texture yTexture = null;
private Texture uTexture = null; private Texture uTexture = null;
@ -37,8 +33,7 @@ namespace MoonWorks.Video
public VideoPlayer(GraphicsDevice device) : base(device) public VideoPlayer(GraphicsDevice device) : base(device)
{ {
StreamA = new VideoAV1Stream(device); Stream = new VideoAV1Stream(device);
StreamB = new VideoAV1Stream(device);
LinearSampler = new Sampler(device, SamplerCreateInfo.LinearClamp); LinearSampler = new Sampler(device, SamplerCreateInfo.LinearClamp);
@ -180,8 +175,7 @@ namespace MoonWorks.Video
State = VideoState.Stopped; State = VideoState.Stopped;
StreamA.Unload(); Stream.Unload();
StreamB.Unload();
Video = null; Video = null;
} }
@ -202,27 +196,26 @@ namespace MoonWorks.Video
int thisFrame = ((int) (timeElapsed / (1000.0 / Video.FramesPerSecond))); int thisFrame = ((int) (timeElapsed / (1000.0 / Video.FramesPerSecond)));
if (thisFrame > currentFrame) if (thisFrame > currentFrame)
{ {
if (CurrentStream.FrameDataUpdated) if (Stream.FrameDataUpdated)
{ {
UpdateRenderTexture(); UpdateRenderTexture();
CurrentStream.FrameDataUpdated = false; Stream.FrameDataUpdated = false;
} }
currentFrame = thisFrame; currentFrame = thisFrame;
CurrentStream.ReadNextFrame(); Stream.ReadNextFrame();
} }
if (CurrentStream.Ended) if (Stream.Ended)
{ {
timer.Stop(); timer.Stop();
timer.Reset(); timer.Reset();
CurrentStream.Reset(); Stream.Reset();
if (Loop) if (Loop)
{ {
// Start over on the next stream! // Start over!
CurrentStream = (CurrentStream == StreamA) ? StreamB : StreamA;
currentFrame = -1; currentFrame = -1;
timer.Start(); timer.Start();
} }
@ -237,12 +230,14 @@ namespace MoonWorks.Video
{ {
uint uOffset; uint uOffset;
uint vOffset; uint vOffset;
uint yStride;
uint uvStride;
lock (CurrentStream) lock (Stream)
{ {
var ySpan = new Span<byte>((void*) CurrentStream.yDataHandle, (int) CurrentStream.yDataLength); var ySpan = new Span<byte>((void*) Stream.yDataHandle, (int) Stream.yDataLength);
var uSpan = new Span<byte>((void*) CurrentStream.uDataHandle, (int) CurrentStream.uvDataLength); var uSpan = new Span<byte>((void*) Stream.uDataHandle, (int) Stream.uvDataLength);
var vSpan = new Span<byte>((void*) CurrentStream.vDataHandle, (int) CurrentStream.uvDataLength); var vSpan = new Span<byte>((void*) Stream.vDataHandle, (int) Stream.uvDataLength);
if (TransferBuffer == null || TransferBuffer.Size < ySpan.Length + uSpan.Length + vSpan.Length) if (TransferBuffer == null || TransferBuffer.Size < ySpan.Length + uSpan.Length + vSpan.Length)
{ {
@ -255,6 +250,9 @@ namespace MoonWorks.Video
uOffset = (uint) ySpan.Length; uOffset = (uint) ySpan.Length;
vOffset = (uint) (ySpan.Length + vSpan.Length); vOffset = (uint) (ySpan.Length + vSpan.Length);
yStride = Stream.yStride;
uvStride = Stream.uvStride;
} }
var commandBuffer = Device.AcquireCommandBuffer(); var commandBuffer = Device.AcquireCommandBuffer();
@ -267,7 +265,7 @@ namespace MoonWorks.Video
new BufferImageCopy new BufferImageCopy
{ {
BufferOffset = 0, BufferOffset = 0,
BufferStride = CurrentStream.yStride, BufferStride = yStride,
BufferImageHeight = yTexture.Height BufferImageHeight = yTexture.Height
}, },
WriteOptions.Cycle WriteOptions.Cycle
@ -278,7 +276,7 @@ namespace MoonWorks.Video
uTexture, uTexture,
new BufferImageCopy{ new BufferImageCopy{
BufferOffset = uOffset, BufferOffset = uOffset,
BufferStride = CurrentStream.uvStride, BufferStride = uvStride,
BufferImageHeight = uTexture.Height BufferImageHeight = uTexture.Height
}, },
WriteOptions.Cycle WriteOptions.Cycle
@ -290,7 +288,7 @@ namespace MoonWorks.Video
new BufferImageCopy new BufferImageCopy
{ {
BufferOffset = vOffset, BufferOffset = vOffset,
BufferStride = CurrentStream.uvStride, BufferStride = uvStride,
BufferImageHeight = vTexture.Height BufferImageHeight = vTexture.Height
}, },
WriteOptions.Cycle WriteOptions.Cycle
@ -340,30 +338,16 @@ namespace MoonWorks.Video
private void InitializeDav1dStream() private void InitializeDav1dStream()
{ {
StreamA.Load(Video.Filename); Stream.Load(Video.Filename);
StreamB.Load(Video.Filename);
CurrentStream = StreamA;
currentFrame = -1; currentFrame = -1;
} }
private void ResetDav1dStreams() private void ResetDav1dStreams()
{ {
StreamA.Reset(); Stream.Reset();
StreamB.Reset();
CurrentStream = StreamA;
currentFrame = -1; currentFrame = -1;
} }
private static void HandleTaskException(Task task)
{
if (task.Exception.InnerException is not TaskCanceledException)
{
throw task.Exception;
}
}
protected override void Dispose(bool disposing) protected override void Dispose(bool disposing)
{ {
if (!IsDisposed) if (!IsDisposed)