Skip to content

Commit

Permalink
BGAObject refactor, fix concurrent access to bgfx textures
Browse files Browse the repository at this point in the history
  • Loading branch information
GoaLitiuM committed Sep 27, 2016
1 parent 7da2056 commit 5226f5d
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 100 deletions.
8 changes: 1 addition & 7 deletions Pulsus/FFmpeg/FFmpegHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,7 @@ public static byte[] ImageFromFile(string path, out int width, out int height, o
height = video.height;
bytesPerPixel = 4;

if (video.isVideo)
{
video.ReadNextFrame();
return video.imageBytes;
}
else
return video.ReadFrames();
return video.ReadFrame();
}
}

Expand Down
10 changes: 7 additions & 3 deletions Pulsus/FFmpeg/FFmpegVideo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,13 +105,17 @@ public void Update(double deltaTime)
}
}

public byte[] ReadFrames()
public byte[] ReadFrame()
{
if (!ffContext.ReadFrame())
return null;

ffContext.GetFrameData(ref bytes, 0);
ffContext.GetFrameData(ref bytes, 0);
nextFramePts = ffContext.framePts;

presentedFrames++;
decodedFrames++;

return bytes;
}

Expand Down Expand Up @@ -147,7 +151,7 @@ private void LoadThread()
}
}

public bool ReadNextFrame()
private bool ReadNextFrame()
{
// decoder is one frame ahead of presentation
if (decodedFrames <= presentedFrames)
Expand Down
110 changes: 22 additions & 88 deletions Pulsus/Gameplay/BGAObject.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.IO;
using Pulsus.FFmpeg;
using Pulsus.Graphics;

Expand All @@ -8,51 +7,18 @@ namespace Pulsus.Gameplay
public class BGAObject : IDisposable
{
public Texture2D texture { get; private set; }
public string filename { get; private set; }
public string path { get; private set; }
public string name { get; private set; }

private FFmpegVideo video;
public FFmpegVideo video { get; private set; }

public bool isVideo { get { return video != null && video.isVideo; } }
public double frametime { get { return video == null ? 0.0 : video.frametime; } }
public bool isVideo { get { return video != null; } }
public double frametime { get { return video.frametime; } }
public bool loaded { get { return texture != null; } }

// alternate paths where to look up missing files
static string[] lookupPaths =
public BGAObject(string path, string name)
{
"", // current directory
"bg/",
"../", // previous directory (compatibility fix for charts in sub-folders)
};

static string[] lookupExtensions =
{
// image formats
".bmp",
".png",
".jpg",
".tga",

// video formats
".mpg",
".avi",
".mp4",
".flv",
".mp4",
".mkv",
".wmv",
".ogv",
".webm",
".mov",
".swf",
".3gp",
".asf",
".m4v",
};

public BGAObject(string filename, string name)
{
this.filename = filename;
this.path = path;
this.name = name;
}

Expand All @@ -64,65 +30,33 @@ public void Dispose()
video.Dispose();
}

public bool Load(string basePath = "")
public void SetVideo(FFmpegVideo video)
{
string fullPath = Utility.FindRealFile(Path.Combine(basePath, filename), lookupPaths, lookupExtensions);
if (!File.Exists(fullPath))
{
Log.Warning("BGA file not found: " + filename);
return false;
}

video = new FFmpegVideo();
try
{
video.Load(fullPath);
texture = new Texture2D(video.width, video.height);
video.OnNextFrame += (data) => texture.SetData(data);
}
catch when (Path.GetExtension(filename).ToLower() == ".lua")
{
// scripted background are not supported (yet?)
Log.Error("Failed to load BGA '" + filename + "', scripted BGA not supported");
return false;
}
catch (ApplicationException e)
{
Log.Error("Failed to load BGA '" + filename + "': " + e.Message);

if (video != null)
video.Dispose();
video = null;

return false;
}

if (isVideo)
{
// preload first frame of the video
video.ReadNextFrame();
}
else
{
// fully load image files
video.OnNextFrame(video.ReadFrames());
video.Dispose();
video = null;
}

return true;
this.video = video;
video.OnNextFrame = UpdateTexture;
}

public void Start()
{
if (isVideo)
if (video != null)
video.Start();
}

public void Update(double deltaTime)
{
if (isVideo)
if (video != null)
video.Update(deltaTime);
}

private void UpdateTexture(byte[] data)
{
if (texture == null)
texture = new Texture2D(video.width, video.height);

texture.SetData(data);

if (!video.isVideo)
video = null;
}
}
}
71 changes: 69 additions & 2 deletions Pulsus/Gameplay/EventPlayers/Loader.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using Pulsus.Audio;
using Pulsus.FFmpeg;

namespace Pulsus.Gameplay
{
Expand All @@ -15,6 +16,7 @@ public class Loader : EventPlayer
public bool skipBGA = false;

AudioEngine audio;
object rendererLock = new object();

ConcurrentQueue<SoundObject> soundQueue = new ConcurrentQueue<SoundObject>();
ConcurrentQueue<BGAObject> bgaQueue = new ConcurrentQueue<BGAObject>();
Expand All @@ -41,6 +43,31 @@ public class Loader : EventPlayer
".m4a",
};

static string[] lookupImageExtensions =
{
// image formats
".bmp",
".png",
".jpg",
".tga",

// video formats
".gif",
".mpg",
".avi",
".mp4",
".flv",
".mkv",
".wmv",
".ogv",
".webm",
".mov",
".swf",
".3gp",
".asf",
".m4v",
};

public Loader(Chart chart, AudioEngine audio)
: base(chart)
{
Expand Down Expand Up @@ -238,6 +265,46 @@ private void LoadSound(SoundObject soundObject)
Log.Error("Sound file not found: " + soundObject.soundFile.path);
}

private void LoadBGA(BGAObject bgaObject)
{
string path = Path.Combine(basePath, bgaObject.path);
path = Utility.FindRealFile(path, lookupPaths, lookupImageExtensions);
if (File.Exists(path))
{
if (Path.GetExtension(bgaObject.path).ToLower() == ".lua")
{
Log.Error("Failed to load BGA '" + bgaObject.path + "', scripted BGAs are not supported");
return;
}

FFmpegVideo video = new FFmpegVideo();
try
{
video.Load(path);

byte[] bytes = video.ReadFrame();

bgaObject.SetVideo(video);
lock (rendererLock)
video.OnNextFrame(bytes);
}
catch (ThreadAbortException)
{
}
catch (Exception e)
{
Log.Error("Failed to load BGA '" + Path.GetFileName(bgaObject.path) + "': " + e.Message);
}
finally
{
if (!video.isVideo)
video.Dispose();
}
}
else
Log.Warning("BGA file not found: " + bgaObject.path);
}

private void LoadThread()
{
try
Expand All @@ -253,7 +320,7 @@ private void LoadThread()
if (sound != null && !sound.loaded)
LoadSound(sound);
else if (bga != null && !bga.loaded)
bga.Load(basePath);
LoadBGA(bga);
else if (!playing && soundQueue.Count == 0 && bgaQueue.Count == 0)
break;
}
Expand Down

0 comments on commit 5226f5d

Please sign in to comment.