Video FrameRate is now taken into account when video has no audio.

This commit is contained in:
IceReaper
2023-05-14 14:18:51 +02:00
committed by Matthias Mailänder
parent 41669d246f
commit 5572650da2

View File

@@ -10,6 +10,7 @@
#endregion #endregion
using System; using System;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using OpenRA.Graphics; using OpenRA.Graphics;
@@ -26,7 +27,7 @@ namespace OpenRA.Mods.Common.Widgets
public bool DrawOverlay = true; public bool DrawOverlay = true;
public bool Skippable = true; public bool Skippable = true;
public bool Paused { get; private set; } public bool Paused => !playTime.IsRunning;
public IVideo Video { get; private set; } = null; public IVideo Video { get; private set; } = null;
Sprite videoSprite, overlaySprite; Sprite videoSprite, overlaySprite;
@@ -36,7 +37,7 @@ namespace OpenRA.Mods.Common.Widgets
float2 videoOrigin, videoSize; float2 videoOrigin, videoSize;
float2 overlayOrigin, overlaySize; float2 overlayOrigin, overlaySize;
float overlayScale; float overlayScale;
bool stopped; readonly Stopwatch playTime = new();
int textureWidth; int textureWidth;
int textureHeight; int textureHeight;
@@ -69,7 +70,7 @@ namespace OpenRA.Mods.Common.Widgets
cachedVideoFileName = filename; cachedVideoFileName = filename;
if (!stopped) if (Video != null)
CloseVideo(); CloseVideo();
Task.Run(() => Task.Run(() =>
@@ -114,8 +115,7 @@ namespace OpenRA.Mods.Common.Widgets
if (video == null) if (video == null)
return; return;
stopped = true; playTime.Reset();
Paused = true;
Game.Sound.StopVideo(); Game.Sound.StopVideo();
onComplete = () => { }; onComplete = () => { };
@@ -150,13 +150,13 @@ namespace OpenRA.Mods.Common.Widgets
if (Video == null) if (Video == null)
return; return;
if (!stopped && !Paused) if (!Paused)
{ {
int nextFrame; int nextFrame;
if (Video.HasAudio && !Game.Sound.DummyEngine) if (Video.HasAudio && !Game.Sound.DummyEngine)
nextFrame = (int)float2.Lerp(0, Video.FrameCount, Game.Sound.VideoSeekPosition * invLength); nextFrame = (int)float2.Lerp(0, Video.FrameCount, Game.Sound.VideoSeekPosition * invLength);
else else
nextFrame = Video.CurrentFrameIndex + 1; nextFrame = (int)float2.Lerp(0, Video.FrameCount, (float)playTime.Elapsed.TotalSeconds * invLength);
// Without the 2nd check the sound playback sometimes ends before the final frame is displayed which causes the player to be stuck on the first frame // Without the 2nd check the sound playback sometimes ends before the final frame is displayed which causes the player to be stuck on the first frame
if (nextFrame > Video.FrameCount || nextFrame < Video.CurrentFrameIndex) if (nextFrame > Video.FrameCount || nextFrame < Video.CurrentFrameIndex)
@@ -169,10 +169,12 @@ namespace OpenRA.Mods.Common.Widgets
while (nextFrame > Video.CurrentFrameIndex) while (nextFrame > Video.CurrentFrameIndex)
{ {
Video.AdvanceFrame(); Video.AdvanceFrame();
videoSprite.Sheet.GetTexture().SetData(Video.CurrentFrameData, textureWidth, textureHeight);
skippedFrames++; skippedFrames++;
} }
if (skippedFrames > 0)
videoSprite.Sheet.GetTexture().SetData(Video.CurrentFrameData, textureWidth, textureHeight);
if (skippedFrames > 1) if (skippedFrames > 1)
Log.Write("perf", $"{nameof(VideoPlayerWidget)}: {cachedVideoFileName} skipped {skippedFrames} frames at position {Video.CurrentFrameIndex}"); Log.Write("perf", $"{nameof(VideoPlayerWidget)}: {cachedVideoFileName} skipped {skippedFrames} frames at position {Video.CurrentFrameIndex}");
} }
@@ -258,30 +260,29 @@ namespace OpenRA.Mods.Common.Widgets
return; return;
onComplete = after; onComplete = after;
if (stopped && Video.HasAudio) if (playTime.ElapsedTicks == 0 && Video.HasAudio)
Game.Sound.PlayVideo(Video.AudioData, Video.AudioChannels, Video.SampleBits, Video.SampleRate); Game.Sound.PlayVideo(Video.AudioData, Video.AudioChannels, Video.SampleBits, Video.SampleRate);
else else
Game.Sound.PlayVideo(); Game.Sound.PlayVideo();
stopped = Paused = false; playTime.Start();
} }
public void Pause() public void Pause()
{ {
if (stopped || Paused || Video == null) if (Paused || Video == null)
return; return;
Paused = true; playTime.Stop();
Game.Sound.PauseVideo(); Game.Sound.PauseVideo();
} }
public void Stop() public void Stop()
{ {
if (stopped || Video == null) if (Video == null)
return; return;
stopped = true; playTime.Reset();
Paused = true;
Game.Sound.StopVideo(); Game.Sound.StopVideo();
Video.Reset(); Video.Reset();
videoSprite.Sheet.GetTexture().SetData(Video.CurrentFrameData, textureWidth, textureHeight); videoSprite.Sheet.GetTexture().SetData(Video.CurrentFrameData, textureWidth, textureHeight);