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:
committed by
Matthias Mailänder
parent
556413c91d
commit
0df3b34c52
@@ -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; }
|
||||||
|
|||||||
@@ -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++;
|
||||||
|
|||||||
@@ -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++]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user