UI updates and preroll buffer to 8 frames
This commit is contained in:
@@ -63,6 +63,7 @@ constexpr GLuint kDecodedVideoTextureUnit = 1;
|
||||
constexpr GLuint kSourceHistoryTextureUnitBase = 2;
|
||||
constexpr GLuint kPackedVideoTextureUnit = 2;
|
||||
constexpr GLuint kGlobalParamsBindingPoint = 0;
|
||||
constexpr unsigned kPrerollFrameCount = 8;
|
||||
const char* kVertexShaderSource =
|
||||
"#version 430 core\n"
|
||||
"out vec2 vTexCoord;\n"
|
||||
@@ -1233,7 +1234,7 @@ bool OpenGLComposite::Start()
|
||||
mTotalPlayoutFrames = 0;
|
||||
|
||||
// Preroll frames
|
||||
for (unsigned i = 0; i < 5; i++)
|
||||
for (unsigned i = 0; i < kPrerollFrameCount; i++)
|
||||
{
|
||||
// Take each video frame from the front of the queue and move it to the back
|
||||
IDeckLinkMutableVideoFrame* outputVideoFrame = mDLOutputVideoFrameQueue.front();
|
||||
|
||||
@@ -53,6 +53,25 @@ bool MatchesControlKey(const std::string& candidate, const std::string& key)
|
||||
return candidate == key || SimplifyControlKey(candidate) == SimplifyControlKey(key);
|
||||
}
|
||||
|
||||
bool TryParseLayerIdNumber(const std::string& layerId, uint64_t& number)
|
||||
{
|
||||
const std::string prefix = "layer-";
|
||||
if (layerId.rfind(prefix, 0) != 0 || layerId.size() == prefix.size())
|
||||
return false;
|
||||
|
||||
uint64_t parsed = 0;
|
||||
for (std::size_t index = prefix.size(); index < layerId.size(); ++index)
|
||||
{
|
||||
const unsigned char ch = static_cast<unsigned char>(layerId[index]);
|
||||
if (!std::isdigit(ch))
|
||||
return false;
|
||||
parsed = parsed * 10 + static_cast<uint64_t>(ch - '0');
|
||||
}
|
||||
|
||||
number = parsed;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<double> JsonArrayToNumbers(const JsonValue& value)
|
||||
{
|
||||
std::vector<double> numbers;
|
||||
@@ -583,6 +602,7 @@ bool RuntimeHost::Initialize(std::string& error)
|
||||
return false;
|
||||
if (!ScanShaderPackages(error))
|
||||
return false;
|
||||
NormalizePersistentLayerIdsLocked();
|
||||
|
||||
for (LayerPersistentState& layer : mPersistentState.layers)
|
||||
{
|
||||
@@ -1469,15 +1489,31 @@ bool RuntimeHost::WriteTextFile(const std::filesystem::path& path, const std::st
|
||||
std::error_code fsError;
|
||||
std::filesystem::create_directories(path.parent_path(), fsError);
|
||||
|
||||
std::ofstream output(path, std::ios::binary);
|
||||
const std::filesystem::path temporaryPath = path.string() + ".tmp";
|
||||
std::ofstream output(temporaryPath, std::ios::binary | std::ios::trunc);
|
||||
if (!output)
|
||||
{
|
||||
error = "Could not write file: " + path.string();
|
||||
error = "Could not write file: " + temporaryPath.string();
|
||||
return false;
|
||||
}
|
||||
|
||||
output << contents;
|
||||
return output.good();
|
||||
output.close();
|
||||
if (!output.good())
|
||||
{
|
||||
error = "Could not finish writing file: " + temporaryPath.string();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!MoveFileExA(temporaryPath.string().c_str(), path.string().c_str(), MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH))
|
||||
{
|
||||
const DWORD lastError = GetLastError();
|
||||
std::filesystem::remove(temporaryPath, fsError);
|
||||
error = "Could not replace file: " + path.string() + " (Win32 error " + std::to_string(lastError) + ")";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RuntimeHost::ResolvePaths(std::string& error)
|
||||
@@ -1728,6 +1764,38 @@ bool RuntimeHost::DeserializeLayerStackLocked(const JsonValue& layersValue, std:
|
||||
return true;
|
||||
}
|
||||
|
||||
void RuntimeHost::NormalizePersistentLayerIdsLocked()
|
||||
{
|
||||
std::set<std::string> usedIds;
|
||||
uint64_t maxLayerNumber = mNextLayerId;
|
||||
|
||||
for (LayerPersistentState& layer : mPersistentState.layers)
|
||||
{
|
||||
uint64_t layerNumber = 0;
|
||||
const bool hasReusableId = !layer.id.empty() &&
|
||||
usedIds.find(layer.id) == usedIds.end() &&
|
||||
TryParseLayerIdNumber(layer.id, layerNumber);
|
||||
|
||||
if (hasReusableId)
|
||||
{
|
||||
usedIds.insert(layer.id);
|
||||
maxLayerNumber = std::max(maxLayerNumber, layerNumber);
|
||||
continue;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
++maxLayerNumber;
|
||||
layer.id = "layer-" + std::to_string(maxLayerNumber);
|
||||
}
|
||||
while (usedIds.find(layer.id) != usedIds.end());
|
||||
|
||||
usedIds.insert(layer.id);
|
||||
}
|
||||
|
||||
mNextLayerId = maxLayerNumber;
|
||||
}
|
||||
|
||||
std::vector<std::string> RuntimeHost::GetStackPresetNamesLocked() const
|
||||
{
|
||||
std::vector<std::string> presetNames;
|
||||
|
||||
@@ -112,6 +112,7 @@ private:
|
||||
JsonValue BuildStateValue() const;
|
||||
JsonValue SerializeLayerStackLocked() const;
|
||||
bool DeserializeLayerStackLocked(const JsonValue& layersValue, std::vector<LayerPersistentState>& layers, std::string& error);
|
||||
void NormalizePersistentLayerIdsLocked();
|
||||
std::vector<std::string> GetStackPresetNamesLocked() const;
|
||||
std::string MakeSafePresetFileStem(const std::string& presetName) const;
|
||||
JsonValue SerializeParameterValue(const ShaderParameterDefinition& definition, const ShaderParameterValue& value) const;
|
||||
|
||||
Reference in New Issue
Block a user