Loop videos seamlessly at the last decoded frame (#939)

Looped videos wrapped at the container duration, which is often longer
than the last frame the decoder delivers. The picture froze for the
difference before restarting. Track the actual end of the video stream
and wrap there instead.
This commit is contained in:
McSchneidar authored and GitHub committed 2026-10-22 18:41:39 +02:00
1 parent 2cdd30c6fc
commit 288c8631f0
2 files changed
+12 -4

No files matched your search

+4 -3
View File
@@ -124,12 +124,13 @@ namespace Vocaluxe.Lib.Video.Acinerella
if (Loop)
{
time = _LoopTime + _LoopTimer.ElapsedMilliseconds / 1000f;
if (time >= Length)
var loopLength = _Thread.LoopLength;
if (time >= loopLength)
{
do
{
time -= Length;
} while (time >= Length);
time -= loopLength;
} while (time >= loopLength);
_LoopTime = time;
_LoopTimer.Restart();
@@ -62,6 +62,7 @@ namespace Vocaluxe.Lib.Video.Acinerella
private bool _DropSeekEnabled = true; // Used to fallback to frame skipping if seek is failing once on this file
public float Length { get; private set; }
public float LoopLength { get; private set; }
public bool Loop { get; set; }
public CDecoderThread()
@@ -81,6 +82,7 @@ namespace Vocaluxe.Lib.Video.Acinerella
var instance = (SACInstance)Marshal.PtrToStructure(_Instance, typeof(SACInstance));
Length = instance.Info.Duration / 1000f;
LoopLength = Length;
var ok = instance.Opened && Length > 0.001f;
_DropSeekEnabled = true;
if (ok)
@@ -300,7 +302,7 @@ namespace Vocaluxe.Lib.Video.Acinerella
}
//If we don't the Length might be inaccurate (e.g. last frame ends at 19.98 but Length=20)
if (time >= Length - 2 * _FrameDuration)
if (time >= LoopLength - 2 * _FrameDuration)
{
return;
}
@@ -432,6 +434,11 @@ namespace Vocaluxe.Lib.Video.Acinerella
{
if (Loop)
{
if (!dropFrame && _LastDecodedTime > 0)
{
LoopLength = Math.Min(Length, _LastDecodedTime + _FrameDuration);
}
RequestTime = _LoopedRequestTime;
_Skip();
}