Keep video in sync with audio

This commit is contained in:
Paul Chote
2010-08-11 23:02:45 +12:00
parent ca6debde66
commit b88512df43
2 changed files with 42 additions and 29 deletions

View File

@@ -109,9 +109,13 @@ namespace OpenRA.FileFormats
CollectAudioData();
// Load the first frame
currentFrame = 0;
AdvanceFrame();
Reset();
}
public void Reset()
{
currentFrame = cbOffset = cbChunk = 0;
LoadFrame();
}
void CollectAudioData()
@@ -150,6 +154,15 @@ namespace OpenRA.FileFormats
public void AdvanceFrame()
{
currentFrame++;
LoadFrame();
}
void LoadFrame()
{
if (currentFrame >= Frames)
return;
// Seek to the start of the frame
stream.Seek(offsets[currentFrame], SeekOrigin.Begin);
BinaryReader reader = new BinaryReader(stream);
@@ -176,8 +189,6 @@ namespace OpenRA.FileFormats
// Chunks are aligned on even bytes; advance by a byte if the next one is null
if (reader.PeekChar() == 0) reader.ReadByte();
}
if (++currentFrame == Frames)
currentFrame = cbOffset = cbChunk = 0;
}
// VQA Frame

View File

@@ -12,6 +12,7 @@ using System;
using System.Drawing;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Support;
namespace OpenRA.Widgets
{
@@ -23,41 +24,42 @@ namespace OpenRA.Widgets
Sprite videoSprite;
VqaReader video = null;
float invLength;
public void LoadVideo(string filename)
{
video = new VqaReader(FileSystem.Open(filename));
timestep = 1e3f/video.Framerate;
timestep = 1f/video.Framerate;
invLength = video.Framerate*1f/video.Frames;
var size = OpenRA.Graphics.Util.NextPowerOf2(Math.Max(video.Width, video.Height));
videoSprite = new Sprite(new Sheet(new Size(size,size)), new Rectangle( 0, 0, video.Width, video.Height ), TextureChannel.Alpha);
}
int lastTime;
bool first = true;
bool advanceNext = false;
Stopwatch sw = new Stopwatch();
public override void DrawInner(World world)
{
if (video == null)
{
LoadVideo(Video);
var nextFrame = (int)float2.Lerp(0, video.Frames, (float)(sw.ElapsedTime()*invLength));
if (first || nextFrame > video.Frames)
{
video.Reset();
sw.Reset();
Sound.PlayRaw(video.AudioData);
}
int t = Environment.TickCount;
int dt = t - lastTime;
if (advanceNext)
{
if (video.CurrentFrame == 0)
Sound.PlayRaw(video.AudioData);
advanceNext = false;
video.AdvanceFrame();
}
if (dt > timestep)
{
lastTime = t;
advanceNext = true;
nextFrame = 0;
videoSprite.sheet.Texture.SetData(video.FrameData());
first = false;
}
while (nextFrame > video.CurrentFrame)
{
video.AdvanceFrame();
if (nextFrame == video.CurrentFrame)
videoSprite.sheet.Texture.SetData(video.FrameData());
}
Game.Renderer.RgbaSpriteRenderer.DrawSprite(videoSprite, new int2(RenderBounds.X,RenderBounds.Y), "chrome");