Did a beautification pass on IVideo and family

Removed property backing fields where applicable, introduced C#7 syntax for properties.
Renamed a bunch of interface properties and class private members with more descriptive names.
Did some inconsequential reordering.
This commit is contained in:
penev92
2021-08-01 20:41:46 +03:00
committed by Matthias Mailänder
parent 556413c91d
commit 0df3b34c52
5 changed files with 141 additions and 143 deletions

View File

@@ -13,13 +13,16 @@ namespace OpenRA.Video
{ {
public interface IVideo public interface IVideo
{ {
ushort Frames { get; } ushort FrameCount { get; }
byte Framerate { get; } byte Framerate { get; }
ushort Width { get; } ushort Width { get; }
ushort Height { get; } ushort Height { get; }
uint[,] FrameData { get; }
int CurrentFrame { get; } /// <summary>
/// Current frame color data in 32-bit BGRA.
/// </summary>
uint[,] CurrentFrameData { get; }
int CurrentFrameNumber { get; }
void AdvanceFrame(); void AdvanceFrame();
bool HasAudio { get; } bool HasAudio { get; }

View File

@@ -18,29 +18,38 @@ namespace OpenRA.Mods.Cnc.FileFormats
{ {
public class VqaReader : IVideo public class VqaReader : IVideo
{ {
public ushort Frames => frames; public ushort FrameCount { get; }
public byte Framerate => framerate; public byte Framerate { get; }
public ushort Width => width; public ushort Width { get; }
public ushort Height => height; public ushort Height { get; }
readonly ushort frames; public int CurrentFrameNumber { get; private set; }
readonly byte framerate; public uint[,] CurrentFrameData
readonly ushort width; {
readonly ushort height; get
{
if (cachedFrameNumber != CurrentFrameNumber)
DecodeFrameData();
Stream stream; return cachedCurrentFrameData;
int currentFrame; }
ushort numColors; }
ushort blockWidth;
ushort blockHeight; public bool HasAudio { get; set; }
byte chunkBufferParts; public byte[] AudioData { get; private set; } // audio for this frame: 22050Hz 16bit mono pcm, uncompressed.
int2 blocks; public int AudioChannels { get; }
uint[] offsets; public int SampleBits { get; }
uint[] palette; public int SampleRate { get; }
uint videoFlags; // if 0x10 is set the video is a 16 bit hq video (ts and later)
int sampleRate; readonly Stream stream;
int sampleBits; readonly ushort numColors;
int audioChannels; readonly ushort blockWidth;
readonly ushort blockHeight;
readonly byte chunkBufferParts;
readonly int2 blocks;
readonly uint[] offsets;
readonly uint[] palette;
readonly uint videoFlags; // if 0x10 is set the video is a 16 bit hq video (ts and later)
// Stores a list of subpixels, referenced by the VPTZ chunk // Stores a list of subpixels, referenced by the VPTZ chunk
byte[] cbf; byte[] cbf;
@@ -60,17 +69,8 @@ namespace OpenRA.Mods.Cnc.FileFormats
// Top half contains block info, bottom half contains references to cbf array // Top half contains block info, bottom half contains references to cbf array
byte[] origData; byte[] origData;
// Final frame output int cachedFrameNumber = -1;
uint[,] frameData; uint[,] cachedCurrentFrameData;
byte[] audioData; // audio for this frame: 22050Hz 16bit mono pcm, uncompressed.
bool hasAudio;
public byte[] AudioData => audioData;
public int CurrentFrame => currentFrame;
public int SampleRate => sampleRate;
public int SampleBits => sampleBits;
public int AudioChannels => audioChannels;
public bool HasAudio => hasAudio;
public VqaReader(Stream stream) public VqaReader(Stream stream)
{ {
@@ -87,15 +87,15 @@ namespace OpenRA.Mods.Cnc.FileFormats
/*var version = */stream.ReadUInt16(); /*var version = */stream.ReadUInt16();
videoFlags = stream.ReadUInt16(); videoFlags = stream.ReadUInt16();
frames = stream.ReadUInt16(); FrameCount = stream.ReadUInt16();
width = stream.ReadUInt16(); Width = stream.ReadUInt16();
height = stream.ReadUInt16(); Height = stream.ReadUInt16();
blockWidth = stream.ReadUInt8(); blockWidth = stream.ReadUInt8();
blockHeight = stream.ReadUInt8(); blockHeight = stream.ReadUInt8();
framerate = stream.ReadUInt8(); Framerate = stream.ReadUInt8();
chunkBufferParts = stream.ReadUInt8(); chunkBufferParts = stream.ReadUInt8();
blocks = new int2(width / blockWidth, height / blockHeight); blocks = new int2(Width / blockWidth, Height / blockHeight);
numColors = stream.ReadUInt16(); numColors = stream.ReadUInt16();
/*var maxBlocks = */stream.ReadUInt16(); /*var maxBlocks = */stream.ReadUInt16();
@@ -103,9 +103,9 @@ namespace OpenRA.Mods.Cnc.FileFormats
/*var unknown2 = */stream.ReadUInt32(); /*var unknown2 = */stream.ReadUInt32();
// Audio // Audio
sampleRate = stream.ReadUInt16(); SampleRate = stream.ReadUInt16();
audioChannels = stream.ReadByte(); AudioChannels = stream.ReadByte();
sampleBits = stream.ReadByte(); SampleBits = stream.ReadByte();
/*var unknown3 =*/stream.ReadUInt32(); /*var unknown3 =*/stream.ReadUInt32();
/*var unknown4 =*/stream.ReadUInt16(); /*var unknown4 =*/stream.ReadUInt16();
@@ -113,7 +113,7 @@ namespace OpenRA.Mods.Cnc.FileFormats
/*var unknown5 =*/stream.ReadUInt32(); /*var unknown5 =*/stream.ReadUInt32();
var frameSize = Exts.NextPowerOf2(Math.Max(width, height)); var frameSize = Exts.NextPowerOf2(Math.Max(Width, Height));
if (IsHqVqa) if (IsHqVqa)
{ {
@@ -123,14 +123,14 @@ namespace OpenRA.Mods.Cnc.FileFormats
} }
else else
{ {
cbfBuffer = new byte[width * height]; cbfBuffer = new byte[Width * Height];
cbf = new byte[width * height]; cbf = new byte[Width * Height];
cbp = new byte[width * height]; cbp = new byte[Width * Height];
origData = new byte[2 * blocks.X * blocks.Y]; origData = new byte[2 * blocks.X * blocks.Y];
} }
palette = new uint[numColors]; palette = new uint[numColors];
frameData = new uint[frameSize, frameSize]; cachedCurrentFrameData = new uint[frameSize, frameSize];
var type = stream.ReadASCII(4); var type = stream.ReadASCII(4);
while (type != "FINF") while (type != "FINF")
{ {
@@ -149,8 +149,8 @@ namespace OpenRA.Mods.Cnc.FileFormats
/*var unknown4 = */stream.ReadUInt16(); /*var unknown4 = */stream.ReadUInt16();
// Frame offsets // Frame offsets
offsets = new uint[frames]; offsets = new uint[FrameCount];
for (var i = 0; i < frames; i++) for (var i = 0; i < FrameCount; i++)
{ {
offsets[i] = stream.ReadUInt32(); offsets[i] = stream.ReadUInt32();
if (offsets[i] > 0x40000000) if (offsets[i] > 0x40000000)
@@ -165,7 +165,7 @@ namespace OpenRA.Mods.Cnc.FileFormats
public void Reset() public void Reset()
{ {
currentFrame = chunkBufferOffset = currentChunkBuffer = 0; CurrentFrameNumber = chunkBufferOffset = currentChunkBuffer = 0;
LoadFrame(); LoadFrame();
} }
@@ -175,10 +175,10 @@ namespace OpenRA.Mods.Cnc.FileFormats
var audio2 = new MemoryStream(); // right channel var audio2 = new MemoryStream(); // right channel
var adpcmIndex = 0; var adpcmIndex = 0;
var compressed = false; var compressed = false;
for (var i = 0; i < frames; i++) for (var i = 0; i < FrameCount; i++)
{ {
stream.Seek(offsets[i], SeekOrigin.Begin); stream.Seek(offsets[i], SeekOrigin.Begin);
var end = (i < frames - 1) ? offsets[i + 1] : stream.Length; var end = (i < FrameCount - 1) ? offsets[i + 1] : stream.Length;
while (stream.Position < end) while (stream.Position < end)
{ {
@@ -196,9 +196,9 @@ namespace OpenRA.Mods.Cnc.FileFormats
{ {
case "SND0": case "SND0":
case "SND2": case "SND2":
if (audioChannels == 0) if (AudioChannels == 0)
throw new NotSupportedException(); throw new NotSupportedException();
else if (audioChannels == 1) else if (AudioChannels == 1)
{ {
var rawAudio = stream.ReadBytes((int)length); var rawAudio = stream.ReadBytes((int)length);
audio1.WriteArray(rawAudio); audio1.WriteArray(rawAudio);
@@ -227,8 +227,8 @@ namespace OpenRA.Mods.Cnc.FileFormats
} }
} }
if (audioChannels == 1) if (AudioChannels == 1)
audioData = compressed ? ImaAdpcmReader.LoadImaAdpcmSound(audio1.ToArray(), ref adpcmIndex) : audio1.ToArray(); AudioData = compressed ? ImaAdpcmReader.LoadImaAdpcmSound(audio1.ToArray(), ref adpcmIndex) : audio1.ToArray();
else else
{ {
byte[] leftData, rightData; byte[] leftData, rightData;
@@ -245,40 +245,40 @@ namespace OpenRA.Mods.Cnc.FileFormats
rightData = ImaAdpcmReader.LoadImaAdpcmSound(audio2.ToArray(), ref adpcmIndex); rightData = ImaAdpcmReader.LoadImaAdpcmSound(audio2.ToArray(), ref adpcmIndex);
} }
audioData = new byte[rightData.Length + leftData.Length]; AudioData = new byte[rightData.Length + leftData.Length];
var rightIndex = 0; var rightIndex = 0;
var leftIndex = 0; var leftIndex = 0;
for (var i = 0; i < audioData.Length;) for (var i = 0; i < AudioData.Length;)
{ {
audioData[i++] = leftData[leftIndex++]; AudioData[i++] = leftData[leftIndex++];
audioData[i++] = leftData[leftIndex++]; AudioData[i++] = leftData[leftIndex++];
audioData[i++] = rightData[rightIndex++]; AudioData[i++] = rightData[rightIndex++];
audioData[i++] = rightData[rightIndex++]; AudioData[i++] = rightData[rightIndex++];
} }
} }
hasAudio = audioData.Length > 0; HasAudio = AudioData.Length > 0;
} }
public void AdvanceFrame() public void AdvanceFrame()
{ {
currentFrame++; CurrentFrameNumber++;
LoadFrame(); LoadFrame();
} }
void LoadFrame() void LoadFrame()
{ {
if (currentFrame >= frames) if (CurrentFrameNumber >= FrameCount)
return; return;
// Seek to the start of the frame // Seek to the start of the frame
stream.Seek(offsets[currentFrame], SeekOrigin.Begin); stream.Seek(offsets[CurrentFrameNumber], SeekOrigin.Begin);
var end = (currentFrame < frames - 1) ? offsets[currentFrame + 1] : stream.Length; var end = (CurrentFrameNumber < FrameCount - 1) ? offsets[CurrentFrameNumber + 1] : stream.Length;
while (stream.Position < end) while (stream.Position < end)
{ {
var type = stream.ReadASCII(4); var type = stream.ReadASCII(4);
var length = 0U; uint length;
if (type == "SN2J") if (type == "SN2J")
{ {
var jmp = int2.Swap(stream.ReadUInt32()); var jmp = int2.Swap(stream.ReadUInt32());
@@ -425,11 +425,9 @@ namespace OpenRA.Mods.Cnc.FileFormats
} }
} }
int cachedFrame = -1;
void DecodeFrameData() void DecodeFrameData()
{ {
cachedFrame = currentFrame; cachedFrameNumber = CurrentFrameNumber;
if (IsHqVqa) if (IsHqVqa)
{ {
/* The VP?? chunks of the video file contains an array of instructions for /* The VP?? chunks of the video file contains an array of instructions for
@@ -494,7 +492,7 @@ namespace OpenRA.Mods.Cnc.FileFormats
{ {
var cbfi = (mod * 256 + px) * 8 + j * blockWidth + i; var cbfi = (mod * 256 + px) * 8 + j * blockWidth + i;
var color = (mod == 0x0f) ? px : cbf[cbfi]; var color = (mod == 0x0f) ? px : cbf[cbfi];
frameData[y * blockHeight + j, x * blockWidth + i] = palette[color]; cachedCurrentFrameData[y * blockHeight + j, x * blockWidth + i] = palette[color];
} }
} }
} }
@@ -502,17 +500,6 @@ namespace OpenRA.Mods.Cnc.FileFormats
} }
} }
public uint[,] FrameData
{
get
{
if (cachedFrame != currentFrame)
DecodeFrameData();
return frameData;
}
}
bool IsHqVqa => (videoFlags & 0x10) == 16; bool IsHqVqa => (videoFlags & 0x10) == 16;
void WriteBlock(int blockNumber, int count, ref int x, ref int y) void WriteBlock(int blockNumber, int count, ref int x, ref int y)
@@ -527,7 +514,7 @@ namespace OpenRA.Mods.Cnc.FileFormats
{ {
var p = (bx + by * blockWidth) * 3; var p = (bx + by * blockWidth) * 3;
frameData[frameY + by, frameX + bx] = (uint)(0xFF << 24 | cbf[offset + p] << 16 | cbf[offset + p + 1] << 8 | cbf[offset + p + 2]); cachedCurrentFrameData[frameY + by, frameX + bx] = (uint)(0xFF << 24 | cbf[offset + p] << 16 | cbf[offset + p + 1] << 8 | cbf[offset + p + 2]);
} }
x++; x++;

View File

@@ -17,49 +17,55 @@ namespace OpenRA.Mods.Cnc.FileFormats
{ {
public class WsaReader : IVideo public class WsaReader : IVideo
{ {
public ushort FrameCount { get; }
public byte Framerate => 1;
public ushort Width { get; }
public ushort Height { get; }
public int CurrentFrameNumber { get; private set; }
public uint[,] CurrentFrameData
{
get
{
if (cachedFrameNumber != CurrentFrameNumber)
LoadFrame();
return cachedCurrentFrameData;
}
}
public bool HasAudio => false;
public byte[] AudioData => null;
public int AudioChannels => 0;
public int SampleBits => 0;
public int SampleRate => 0;
readonly Stream stream; readonly Stream stream;
public ushort Frames { get { return frameCount; } }
public byte Framerate { get { return 1; } }
public ushort Width { get { return width; } }
public ushort Height { get { return height; } }
readonly ushort frameCount;
readonly ushort width;
readonly ushort height;
readonly uint[] palette; readonly uint[] palette;
readonly uint[] frameOffsets; readonly uint[] frameOffsets;
uint[,] coloredFrameData; byte[] previousFramePaletteIndexData;
public uint[,] FrameData { get { return coloredFrameData; } } byte[] currentFramePaletteIndexData;
int currentFrame; int cachedFrameNumber = -1;
byte[] previousFrameData; uint[,] cachedCurrentFrameData;
byte[] currentFrameData;
public byte[] AudioData { get { return null; } }
public int CurrentFrame { get { return currentFrame; } }
public int SampleRate { get { return 0; } }
public int SampleBits { get { return 0; } }
public int AudioChannels { get { return 0; } }
public bool HasAudio { get { return false; } }
public WsaReader(Stream stream) public WsaReader(Stream stream)
{ {
this.stream = stream; this.stream = stream;
frameCount = stream.ReadUInt16(); FrameCount = stream.ReadUInt16();
var x = stream.ReadUInt16(); /*var x = */stream.ReadUInt16();
var y = stream.ReadUInt16(); /*var y = */stream.ReadUInt16();
width = stream.ReadUInt16(); Width = stream.ReadUInt16();
height = stream.ReadUInt16(); Height = stream.ReadUInt16();
var delta = stream.ReadUInt16() + 37; var delta = stream.ReadUInt16() + 37;
var flags = stream.ReadUInt16(); var flags = stream.ReadUInt16();
frameOffsets = new uint[frameCount + 2]; frameOffsets = new uint[FrameCount + 2];
for (var i = 0; i < frameOffsets.Length; i++) for (var i = 0; i < frameOffsets.Length; i++)
frameOffsets[i] = stream.ReadUInt32(); frameOffsets[i] = stream.ReadUInt32();
@@ -89,48 +95,48 @@ namespace OpenRA.Mods.Cnc.FileFormats
public void Reset() public void Reset()
{ {
currentFrame = 0; CurrentFrameNumber = 0;
previousFrameData = null; previousFramePaletteIndexData = null;
LoadFrame(); LoadFrame();
} }
public void AdvanceFrame() public void AdvanceFrame()
{ {
previousFrameData = currentFrameData; previousFramePaletteIndexData = currentFramePaletteIndexData;
currentFrame++; CurrentFrameNumber++;
LoadFrame(); LoadFrame();
} }
void LoadFrame() void LoadFrame()
{ {
if (currentFrame >= frameCount) if (CurrentFrameNumber >= FrameCount)
return; return;
stream.Seek(frameOffsets[currentFrame], SeekOrigin.Begin); stream.Seek(frameOffsets[CurrentFrameNumber], SeekOrigin.Begin);
var dataLength = frameOffsets[currentFrame + 1] - frameOffsets[currentFrame]; var dataLength = frameOffsets[CurrentFrameNumber + 1] - frameOffsets[CurrentFrameNumber];
var rawData = StreamExts.ReadBytes(stream, (int)dataLength); var rawData = StreamExts.ReadBytes(stream, (int)dataLength);
var intermediateData = new byte[width * height]; var intermediateData = new byte[Width * Height];
// Format80 decompression // Format80 decompression
LCWCompression.DecodeInto(rawData, intermediateData); LCWCompression.DecodeInto(rawData, intermediateData);
// and Format40 decompression // and Format40 decompression
currentFrameData = new byte[width * height]; currentFramePaletteIndexData = new byte[Width * Height];
if (previousFrameData == null) if (previousFramePaletteIndexData == null)
Array.Clear(currentFrameData, 0, currentFrameData.Length); Array.Clear(currentFramePaletteIndexData, 0, currentFramePaletteIndexData.Length);
else else
Array.Copy(previousFrameData, currentFrameData, currentFrameData.Length); Array.Copy(previousFramePaletteIndexData, currentFramePaletteIndexData, currentFramePaletteIndexData.Length);
XORDeltaCompression.DecodeInto(intermediateData, currentFrameData, 0); XORDeltaCompression.DecodeInto(intermediateData, currentFramePaletteIndexData, 0);
var c = 0; var c = 0;
var frameSize = Exts.NextPowerOf2(Math.Max(width, height)); var frameSize = Exts.NextPowerOf2(Math.Max(Width, Height));
coloredFrameData = new uint[frameSize, frameSize]; cachedCurrentFrameData = new uint[frameSize, frameSize];
for (var y = 0; y < height; y++) for (var y = 0; y < Height; y++)
for (var x = 0; x < width; x++) for (var x = 0; x < Width; x++)
coloredFrameData[y, x] = palette[currentFrameData[c++]]; cachedCurrentFrameData[y, x] = palette[currentFramePaletteIndexData[c++]];
} }
} }
} }

View File

@@ -165,7 +165,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var frameContainer = panel.GetOrNull("FRAME_SELECTOR"); var frameContainer = panel.GetOrNull("FRAME_SELECTOR");
if (frameContainer != null) if (frameContainer != null)
frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) || frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) ||
(isVideoLoaded && player != null && player.Video != null && player.Video.Frames > 1) || (isVideoLoaded && player != null && player.Video != null && player.Video.FrameCount > 1) ||
currentSoundFormat != null; currentSoundFormat != null;
frameSlider = panel.GetOrNull<SliderWidget>("FRAME_SLIDER"); frameSlider = panel.GetOrNull<SliderWidget>("FRAME_SLIDER");
@@ -180,7 +180,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
frameSlider.GetValue = () => frameSlider.GetValue = () =>
{ {
if (isVideoLoaded) if (isVideoLoaded)
return player.Video.CurrentFrame; return player.Video.CurrentFrameNumber;
if (currentSound != null) if (currentSound != null)
return currentSound.SeekPosition * currentSoundFormat.SampleRate; return currentSound.SeekPosition * currentSoundFormat.SampleRate;
@@ -197,7 +197,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
frameText.GetText = () => frameText.GetText = () =>
{ {
if (isVideoLoaded) if (isVideoLoaded)
return $"{player.Video.CurrentFrame + 1} / {player.Video.Frames}"; return $"{player.Video.CurrentFrameNumber + 1} / {player.Video.FrameCount}";
if (currentSoundFormat != null) if (currentSoundFormat != null)
return $"{Math.Round(currentSoundFormat.LengthInSeconds, 3)} sec"; return $"{Math.Round(currentSoundFormat.LengthInSeconds, 3)} sec";
@@ -516,7 +516,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (frameSlider != null) if (frameSlider != null)
{ {
frameSlider.MaximumValue = (float)player.Video.Frames - 1; frameSlider.MaximumValue = (float)player.Video.FrameCount - 1;
frameSlider.Ticks = 0; frameSlider.Ticks = 0;
} }
} }

View File

@@ -60,14 +60,14 @@ namespace OpenRA.Mods.Common.Widgets
Game.Sound.StopVideo(); Game.Sound.StopVideo();
onComplete = () => { }; onComplete = () => { };
invLength = video.Framerate * 1f / video.Frames; invLength = video.Framerate * 1f / video.FrameCount;
var size = Math.Max(video.Width, video.Height); var size = Math.Max(video.Width, video.Height);
var textureSize = Exts.NextPowerOf2(size); var textureSize = Exts.NextPowerOf2(size);
var videoSheet = new Sheet(SheetType.BGRA, new Size(textureSize, textureSize)); var videoSheet = new Sheet(SheetType.BGRA, new Size(textureSize, textureSize));
videoSheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear; videoSheet.GetTexture().ScaleFilter = TextureScaleFilter.Linear;
videoSheet.GetTexture().SetData(video.FrameData); videoSheet.GetTexture().SetData(video.CurrentFrameData);
videoSprite = new Sprite(videoSheet, videoSprite = new Sprite(videoSheet,
new Rectangle( new Rectangle(
@@ -93,27 +93,29 @@ namespace OpenRA.Mods.Common.Widgets
if (!stopped && !paused) if (!stopped && !paused)
{ {
var nextFrame = video.CurrentFrame + 1; int nextFrame;
if (video.HasAudio && !Game.Sound.DummyEngine) if (video.HasAudio && !Game.Sound.DummyEngine)
nextFrame = (int)float2.Lerp(0, video.Frames, Game.Sound.VideoSeekPosition * invLength); nextFrame = (int)float2.Lerp(0, video.FrameCount, Game.Sound.VideoSeekPosition * invLength);
else
nextFrame = video.CurrentFrameNumber + 1;
// 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.Frames || nextFrame < video.CurrentFrame) if (nextFrame > video.FrameCount || nextFrame < video.CurrentFrameNumber)
{ {
Stop(); Stop();
return; return;
} }
var skippedFrames = 0; var skippedFrames = 0;
while (nextFrame > video.CurrentFrame) while (nextFrame > video.CurrentFrameNumber)
{ {
video.AdvanceFrame(); video.AdvanceFrame();
videoSprite.Sheet.GetTexture().SetData(video.FrameData); videoSprite.Sheet.GetTexture().SetData(video.CurrentFrameData);
skippedFrames++; skippedFrames++;
} }
if (skippedFrames > 1) if (skippedFrames > 1)
Log.Write("perf", "VqaPlayer : {0} skipped {1} frames at position {2}", cachedVideo, skippedFrames, video.CurrentFrame); Log.Write("perf", "VqaPlayer : {0} skipped {1} frames at position {2}", cachedVideo, skippedFrames, video.CurrentFrameNumber);
} }
WidgetUtils.DrawSprite(videoSprite, videoOrigin, videoSize); WidgetUtils.DrawSprite(videoSprite, videoOrigin, videoSize);
@@ -216,7 +218,7 @@ namespace OpenRA.Mods.Common.Widgets
paused = true; paused = true;
Game.Sound.StopVideo(); Game.Sound.StopVideo();
video.Reset(); video.Reset();
videoSprite.Sheet.GetTexture().SetData(video.FrameData); videoSprite.Sheet.GetTexture().SetData(video.CurrentFrameData);
Game.RunAfterTick(onComplete); Game.RunAfterTick(onComplete);
} }