Skip to content

Commit

Permalink
Keep video in sync with audio
Browse files Browse the repository at this point in the history
  • Loading branch information
pchote committed Aug 11, 2010
1 parent ca6debd commit b88512d
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 28 deletions.
25 changes: 18 additions & 7 deletions OpenRA.FileFormats/Graphics/VqaReader.cs
Expand Up @@ -109,11 +109,15 @@ public VqaReader( Stream stream )

CollectAudioData();

// Load the first frame
currentFrame = 0;
AdvanceFrame();
Reset();
}


public void Reset()
{
currentFrame = cbOffset = cbChunk = 0;
LoadFrame();
}

void CollectAudioData()
{
var ms = new MemoryStream();
Expand Down Expand Up @@ -147,9 +151,18 @@ void CollectAudioData()

audioData = AudLoader.LoadSound(ms.ToArray(), ref adpcmIndex);
}


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);
Expand All @@ -176,8 +189,6 @@ public void AdvanceFrame()
// 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
Expand Down
44 changes: 23 additions & 21 deletions OpenRA.Game/Widgets/VqaPlayerWidget.cs
Expand Up @@ -12,6 +12,7 @@
using System.Drawing;
using OpenRA.FileFormats;
using OpenRA.Graphics;
using OpenRA.Support;

namespace OpenRA.Widgets
{
Expand All @@ -23,41 +24,42 @@ public class VqaPlayerWidget : Widget
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);
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();
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);

nextFrame = 0;
videoSprite.sheet.Texture.SetData(video.FrameData());
first = false;
}

if (dt > timestep)
while (nextFrame > video.CurrentFrame)
{
lastTime = t;
advanceNext = true;
videoSprite.sheet.Texture.SetData(video.FrameData());
video.AdvanceFrame();
if (nextFrame == video.CurrentFrame)
videoSprite.sheet.Texture.SetData(video.FrameData());
}

Game.Renderer.RgbaSpriteRenderer.DrawSprite(videoSprite, new int2(RenderBounds.X,RenderBounds.Y), "chrome");
Expand Down

0 comments on commit b88512d

Please sign in to comment.