Merge branch 'master' into typos
This commit is contained in:
@@ -46,6 +46,8 @@ set(OLIVE_SOURCES
|
||||
node/output.cpp
|
||||
node/param.h
|
||||
node/param.cpp
|
||||
node/traverser.h
|
||||
node/traverser.cpp
|
||||
node/value.h
|
||||
node/value.cpp
|
||||
PARENT_SCOPE
|
||||
|
||||
@@ -202,22 +202,28 @@ void Block::LengthInputChanged()
|
||||
emit LengthChanged(length());
|
||||
}
|
||||
|
||||
void Block::Link(Block *a, Block *b)
|
||||
bool Block::Link(Block *a, Block *b)
|
||||
{
|
||||
if (a == b || a == nullptr || b == nullptr) {
|
||||
return;
|
||||
if (a == b || !a || !b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assume both clips are already linked since Link() and Unlink() should be the only entry points to this array
|
||||
if (a->linked_clips_.contains(b)) {
|
||||
return;
|
||||
// Prevent duplicate link entries (assume that we only need to check one clip since this should be the only function
|
||||
// that adds to the linked array)
|
||||
if (Block::AreLinked(a, b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
a->linked_clips_.append(b);
|
||||
b->linked_clips_.append(a);
|
||||
|
||||
emit a->LinksChanged();
|
||||
emit b->LinksChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Block::Link(QList<Block *> blocks)
|
||||
void Block::Link(const QList<Block*>& blocks)
|
||||
{
|
||||
foreach (Block* a, blocks) {
|
||||
foreach (Block* b, blocks) {
|
||||
@@ -226,10 +232,32 @@ void Block::Link(QList<Block *> blocks)
|
||||
}
|
||||
}
|
||||
|
||||
void Block::Unlink(Block *a, Block *b)
|
||||
bool Block::Unlink(Block *a, Block *b)
|
||||
{
|
||||
if (a == b || !a || !b) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!Block::AreLinked(a, b)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
a->linked_clips_.removeOne(b);
|
||||
b->linked_clips_.removeOne(a);
|
||||
|
||||
emit a->LinksChanged();
|
||||
emit b->LinksChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Block::Unlink(const QList<Block *> &blocks)
|
||||
{
|
||||
foreach (Block* a, blocks) {
|
||||
foreach (Block* b, blocks) {
|
||||
Unlink(a, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Block::AreLinked(Block *a, Block *b)
|
||||
|
||||
@@ -76,9 +76,10 @@ public:
|
||||
QString block_name() const;
|
||||
void set_block_name(const QString& name);
|
||||
|
||||
static void Link(Block* a, Block* b);
|
||||
static void Link(QList<Block*> blocks);
|
||||
static void Unlink(Block* a, Block* b);
|
||||
static bool Link(Block* a, Block* b);
|
||||
static void Link(const QList<Block*>& blocks);
|
||||
static bool Unlink(Block* a, Block* b);
|
||||
static void Unlink(const QList<Block*>& blocks);
|
||||
static bool AreLinked(Block* a, Block* b);
|
||||
const QVector<Block*>& linked_clips();
|
||||
bool HasLinks();
|
||||
@@ -103,6 +104,8 @@ signals:
|
||||
|
||||
void LengthChanged(const rational& length);
|
||||
|
||||
void LinksChanged();
|
||||
|
||||
protected:
|
||||
rational SequenceToMediaTime(const rational& sequence_time) const;
|
||||
|
||||
|
||||
+86
-85
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "common/bezier.h"
|
||||
#include "common/lerp.h"
|
||||
#include "common/xmlreadloop.h"
|
||||
#include "common/xmlutils.h"
|
||||
#include "node.h"
|
||||
#include "output.h"
|
||||
#include "inputarray.h"
|
||||
@@ -91,111 +91,111 @@ void NodeInput::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& par
|
||||
return;
|
||||
}
|
||||
|
||||
if (attr.name() == "keyframing") {
|
||||
set_is_keyframing(attr.value() == "1");
|
||||
if (attr.name() == QStringLiteral("keyframing")) {
|
||||
set_is_keyframing(attr.value() == QStringLiteral("1"));
|
||||
}
|
||||
}
|
||||
|
||||
XMLReadLoop(reader, "input") {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reader->isStartElement()) {
|
||||
if (reader->name() == "standard") {
|
||||
// Load standard value
|
||||
int val_index = 0;
|
||||
if (reader->name() == QStringLiteral("standard")) {
|
||||
// Load standard value
|
||||
int val_index = 0;
|
||||
|
||||
XMLReadLoop(reader, "standard") {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reader->name() == QStringLiteral("value")) {
|
||||
QString value_text = reader->readElementText();
|
||||
|
||||
if (value_text.isEmpty()) {
|
||||
standard_value_.replace(val_index, QVariant());
|
||||
} else {
|
||||
standard_value_.replace(val_index, StringToValue(value_text, footage_connections));
|
||||
}
|
||||
|
||||
if (reader->isStartElement() && reader->name() == "value") {
|
||||
reader->readNext();
|
||||
val_index++;
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else if (reader->name() == QStringLiteral("keyframes")) {
|
||||
int track = 0;
|
||||
|
||||
QString value_text = reader->text().toString();
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (value_text.isEmpty()) {
|
||||
standard_value_.replace(val_index, QVariant());
|
||||
} else {
|
||||
standard_value_.replace(val_index, StringToValue(value_text, footage_connections));
|
||||
if (reader->name() == QStringLiteral("track")) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
val_index++;
|
||||
}
|
||||
}
|
||||
} else if (reader->name() == "keyframes") {
|
||||
int track = 0;
|
||||
if (reader->name() == QStringLiteral("key")) {
|
||||
rational key_time;
|
||||
NodeKeyframe::Type key_type;
|
||||
QVariant key_value;
|
||||
QPointF key_in_handle;
|
||||
QPointF key_out_handle;
|
||||
|
||||
XMLReadLoop(reader, "keyframes") {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reader->isStartElement() && reader->name() == "track") {
|
||||
XMLReadLoop(reader, "track") {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reader->name() == "key") {
|
||||
rational key_time;
|
||||
NodeKeyframe::Type key_type;
|
||||
QVariant key_value;
|
||||
QPointF key_in_handle;
|
||||
QPointF key_out_handle;
|
||||
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (attr.name() == "time") {
|
||||
key_time = rational::fromString(attr.value().toString());
|
||||
} else if (attr.name() == "type") {
|
||||
key_type = static_cast<NodeKeyframe::Type>(attr.value().toInt());
|
||||
} else if (attr.name() == "inhandlex") {
|
||||
key_in_handle.setX(attr.value().toDouble());
|
||||
} else if (attr.name() == "inhandley") {
|
||||
key_in_handle.setY(attr.value().toDouble());
|
||||
} else if (attr.name() == "outhandlex") {
|
||||
key_out_handle.setX(attr.value().toDouble());
|
||||
} else if (attr.name() == "outhandley") {
|
||||
key_out_handle.setY(attr.value().toDouble());
|
||||
}
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
reader->readNext();
|
||||
|
||||
key_value = StringToValue(reader->text().toString(), footage_connections);
|
||||
|
||||
NodeKeyframePtr key = NodeKeyframe::Create(key_time, key_value, key_type, track);
|
||||
key->set_bezier_control_in(key_in_handle);
|
||||
key->set_bezier_control_out(key_out_handle);
|
||||
key->set_parent(this);
|
||||
keyframe_tracks_[track].append(key);
|
||||
if (attr.name() == QStringLiteral("time")) {
|
||||
key_time = rational::fromString(attr.value().toString());
|
||||
} else if (attr.name() == QStringLiteral("type")) {
|
||||
key_type = static_cast<NodeKeyframe::Type>(attr.value().toInt());
|
||||
} else if (attr.name() == QStringLiteral("inhandlex")) {
|
||||
key_in_handle.setX(attr.value().toDouble());
|
||||
} else if (attr.name() == QStringLiteral("inhandley")) {
|
||||
key_in_handle.setY(attr.value().toDouble());
|
||||
} else if (attr.name() == QStringLiteral("outhandlex")) {
|
||||
key_out_handle.setX(attr.value().toDouble());
|
||||
} else if (attr.name() == QStringLiteral("outhandley")) {
|
||||
key_out_handle.setY(attr.value().toDouble());
|
||||
}
|
||||
}
|
||||
|
||||
key_value = StringToValue(reader->readElementText(), footage_connections);
|
||||
|
||||
NodeKeyframePtr key = NodeKeyframe::Create(key_time, key_value, key_type, track);
|
||||
key->set_bezier_control_in(key_in_handle);
|
||||
key->set_bezier_control_out(key_out_handle);
|
||||
key->set_parent(this);
|
||||
keyframe_tracks_[track].append(key);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
|
||||
track++;
|
||||
}
|
||||
|
||||
track++;
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
} else if (reader->name() == "connections") {
|
||||
XMLReadLoop(reader, "connections") {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reader->isStartElement() && reader->name() == "connection") {
|
||||
reader->readNext();
|
||||
|
||||
input_connections.append({this, reader->text().toULongLong()});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LoadInternal(reader, param_ptrs, input_connections, footage_connections, cancelled);
|
||||
}
|
||||
} else if (reader->name() == QStringLiteral("connections")) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reader->name() == QStringLiteral("connection")) {
|
||||
input_connections.append({this, reader->readElementText().toULongLong()});
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LoadInternal(reader, param_ptrs, input_connections, footage_connections, cancelled);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,8 +268,9 @@ const NodeParam::DataType &NodeInput::data_type() const
|
||||
return data_type_;
|
||||
}
|
||||
|
||||
void NodeInput::LoadInternal(QXmlStreamReader*, QHash<quintptr, NodeOutput *>&, QList<SerializedConnection>&, QList<FootageConnection>&, const QAtomicInt*)
|
||||
void NodeInput::LoadInternal(QXmlStreamReader* reader, QHash<quintptr, NodeOutput *>&, QList<SerializedConnection>&, QList<FootageConnection>&, const QAtomicInt*)
|
||||
{
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
|
||||
void NodeInput::SaveInternal(QXmlStreamWriter*) const
|
||||
|
||||
@@ -28,8 +28,3 @@ QString AudioInput::Description() const
|
||||
{
|
||||
return tr("Import an audio footage stream.");
|
||||
}
|
||||
|
||||
NodeValueTable AudioInput::Value(const NodeValueDatabase &value) const
|
||||
{
|
||||
return value[footage_input_];
|
||||
}
|
||||
|
||||
@@ -15,9 +15,6 @@ public:
|
||||
virtual QString Category() const override;
|
||||
virtual QString Description() const override;
|
||||
|
||||
protected:
|
||||
virtual NodeValueTable Value(const NodeValueDatabase& value) const override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
||||
@@ -69,22 +69,18 @@ void MediaInput::FootageChanged()
|
||||
return;
|
||||
}
|
||||
|
||||
if (connected_footage_ != nullptr) {
|
||||
if (connected_footage_->type() == Stream::kImage || connected_footage_->type() == Stream::kVideo) {
|
||||
disconnect(connected_footage_.get(), SIGNAL(ColorSpaceChanged()), this, SLOT(FootageColorSpaceChanged()));
|
||||
}
|
||||
if (connected_footage_) {
|
||||
disconnect(connected_footage_.get(), &Stream::ParametersChanged, this, &MediaInput::FootageParametersChanged);
|
||||
}
|
||||
|
||||
connected_footage_ = new_footage;
|
||||
|
||||
if (connected_footage_ != nullptr) {
|
||||
if (connected_footage_->type() == Stream::kImage || connected_footage_->type() == Stream::kVideo) {
|
||||
connect(connected_footage_.get(), SIGNAL(ColorSpaceChanged()), this, SLOT(FootageColorSpaceChanged()));
|
||||
}
|
||||
if (connected_footage_) {
|
||||
connect(connected_footage_.get(), &Stream::ParametersChanged, this, &MediaInput::FootageParametersChanged);
|
||||
}
|
||||
}
|
||||
|
||||
void MediaInput::FootageColorSpaceChanged()
|
||||
void MediaInput::FootageParametersChanged()
|
||||
{
|
||||
InvalidateCache(0, RATIONAL_MAX, footage_input_);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ protected:
|
||||
private slots:
|
||||
void FootageChanged();
|
||||
|
||||
void FootageColorSpaceChanged();
|
||||
void FootageParametersChanged();
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include <QApplication>
|
||||
|
||||
#include "common/xmlreadloop.h"
|
||||
#include "common/xmlutils.h"
|
||||
#include "node.h"
|
||||
|
||||
NodeInputArray::NodeInputArray(const QString &id, const DataType &type, const QVariant &default_value) :
|
||||
@@ -166,13 +166,17 @@ void NodeInputArray::RemoveAt(int index)
|
||||
|
||||
void NodeInputArray::LoadInternal(QXmlStreamReader *reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<SerializedConnection> &input_connections, QList<FootageConnection>& footage_connections, const QAtomicInt* cancelled)
|
||||
{
|
||||
if (reader->name() == "subparameters") {
|
||||
XMLReadLoop(reader, "subparameters") {
|
||||
if (reader->name() == "input") {
|
||||
if (reader->name() == QStringLiteral("subparameters")) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (reader->name() == QStringLiteral("input")) {
|
||||
Append();
|
||||
At(GetSize() - 1)->Load(reader, param_ptrs, input_connections, footage_connections, cancelled);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
NodeInput::Load(reader, param_ptrs, input_connections, footage_connections, cancelled);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+25
-25
@@ -24,7 +24,7 @@
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
|
||||
#include "common/xmlreadloop.h"
|
||||
#include "common/xmlutils.h"
|
||||
|
||||
Node::Node() :
|
||||
can_be_deleted_(true)
|
||||
@@ -50,39 +50,39 @@ Node::~Node()
|
||||
}
|
||||
}
|
||||
|
||||
void Node::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput *> &output_ptrs, QList<NodeInput::SerializedConnection>& input_connections, QList<NodeParam::FootageConnection>& footage_connections, const QAtomicInt* cancelled, const QString& element)
|
||||
void Node::Load(QXmlStreamReader *reader, QHash<quintptr, NodeOutput *> &output_ptrs, QList<NodeInput::SerializedConnection>& input_connections, QList<NodeParam::FootageConnection>& footage_connections, const QAtomicInt* cancelled)
|
||||
{
|
||||
XMLReadLoop(reader, (element.isEmpty() ? "node" : element)) {
|
||||
while (XMLReadNextStartElement(reader)) {
|
||||
if (cancelled && *cancelled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (reader->isStartElement()) {
|
||||
if (reader->name() == "input" || reader->name() == "output") {
|
||||
QString param_id;
|
||||
if (reader->name() == QStringLiteral("input") || reader->name() == QStringLiteral("output")) {
|
||||
QString param_id;
|
||||
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == "id") {
|
||||
param_id = attr.value().toString();
|
||||
XMLAttributeLoop(reader, attr) {
|
||||
if (attr.name() == QStringLiteral("id")) {
|
||||
param_id = attr.value().toString();
|
||||
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (param_id.isEmpty()) {
|
||||
qDebug() << "Found parameter with no ID";
|
||||
continue;
|
||||
}
|
||||
|
||||
NodeParam* param = GetParameterWithID(param_id);
|
||||
|
||||
if (!param) {
|
||||
qDebug() << "No parameter in" << id() << "with parameter" << param_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
param->Load(reader, output_ptrs, input_connections, footage_connections, cancelled);
|
||||
}
|
||||
|
||||
if (param_id.isEmpty()) {
|
||||
qDebug() << "Found parameter with no ID";
|
||||
continue;
|
||||
}
|
||||
|
||||
NodeParam* param = GetParameterWithID(param_id);
|
||||
|
||||
if (!param) {
|
||||
qDebug() << "No parameter in" << id() << "with parameter" << param_id;
|
||||
continue;
|
||||
}
|
||||
|
||||
param->Load(reader, output_ptrs, input_connections, footage_connections, cancelled);
|
||||
} else {
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -67,7 +67,7 @@ public:
|
||||
/**
|
||||
* @brief Clear current node variables and replace them with
|
||||
*/
|
||||
void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<NodeInput::SerializedConnection> &input_connections, QList<NodeParam::FootageConnection>& footage_connections, const QAtomicInt *cancelled, const QString &element = QString());
|
||||
void Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& param_ptrs, QList<NodeInput::SerializedConnection> &input_connections, QList<NodeParam::FootageConnection>& footage_connections, const QAtomicInt *cancelled);
|
||||
|
||||
/**
|
||||
* @brief Save this node into a text/XML format
|
||||
|
||||
+3
-1
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "output.h"
|
||||
|
||||
#include "common/xmlreadloop.h"
|
||||
#include "common/xmlutils.h"
|
||||
#include "node/node.h"
|
||||
|
||||
NodeOutput::NodeOutput(const QString &id) :
|
||||
@@ -55,6 +55,8 @@ void NodeOutput::Load(QXmlStreamReader* reader, QHash<quintptr, NodeOutput*>& pa
|
||||
param_ptrs.insert(saved_ptr, this);
|
||||
}
|
||||
}
|
||||
|
||||
reader->skipCurrentElement();
|
||||
}
|
||||
|
||||
void NodeOutput::Save(QXmlStreamWriter *writer) const
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "viewer.h"
|
||||
|
||||
#include "node/traverser.h"
|
||||
|
||||
ViewerOutput::ViewerOutput()
|
||||
{
|
||||
texture_input_ = new NodeInput("tex_in", NodeInput::kTexture);
|
||||
@@ -28,9 +30,6 @@ ViewerOutput::ViewerOutput()
|
||||
samples_input_ = new NodeInput("samples_in", NodeInput::kSamples);
|
||||
AddInput(samples_input_);
|
||||
|
||||
length_input_ = new NodeInput("length_in", NodeInput::kRational);
|
||||
AddInput(length_input_);
|
||||
|
||||
// Create TrackList instances
|
||||
track_inputs_.resize(Timeline::kTrackTypeCount);
|
||||
track_lists_.resize(Timeline::kTrackTypeCount);
|
||||
@@ -91,11 +90,6 @@ NodeInput *ViewerOutput::samples_input() const
|
||||
return samples_input_;
|
||||
}
|
||||
|
||||
NodeInput *ViewerOutput::length_input() const
|
||||
{
|
||||
return length_input_;
|
||||
}
|
||||
|
||||
void ViewerOutput::InvalidateCache(const rational &start_range, const rational &end_range, NodeInput *from)
|
||||
{
|
||||
Node::InvalidateCache(start_range, end_range, from);
|
||||
@@ -104,8 +98,6 @@ void ViewerOutput::InvalidateCache(const rational &start_range, const rational &
|
||||
emit VideoChangedBetween(TimeRange(start_range, end_range));
|
||||
} else if (from == samples_input()) {
|
||||
emit AudioChangedBetween(TimeRange(start_range, end_range));
|
||||
} else if (from == length_input()) {
|
||||
emit LengthChanged(Length());
|
||||
}
|
||||
|
||||
SendInvalidateCache(start_range, end_range);
|
||||
@@ -146,18 +138,23 @@ void ViewerOutput::set_audio_params(const AudioParams &audio)
|
||||
|
||||
rational ViewerOutput::Length()
|
||||
{
|
||||
if (!length_input_->IsConnected()) {
|
||||
return timeline_length_;
|
||||
NodeTraverser traverser;
|
||||
|
||||
rational video_length;
|
||||
|
||||
if (texture_input_->IsConnected()) {
|
||||
NodeValueTable t = traverser.ProcessNode(NodeDependency(texture_input_->get_connected_node(), 0, 0));
|
||||
video_length = t.Get(NodeParam::kNumber, "length").value<rational>();
|
||||
}
|
||||
|
||||
Node* connected_node = length_input_->get_connected_node();
|
||||
rational audio_length;
|
||||
|
||||
if (connected_node) {
|
||||
// This is kind of messy?
|
||||
return connected_node->Value(NodeValueDatabase()).Get(NodeParam::kNumber, "length").value<rational>();
|
||||
if (samples_input_->IsConnected()) {
|
||||
NodeValueTable t = traverser.ProcessNode(NodeDependency(samples_input_->get_connected_node(), 0, 0));
|
||||
audio_length = t.Get(NodeParam::kNumber, "length").value<rational>();
|
||||
}
|
||||
|
||||
return 0;
|
||||
return qMax(video_length, qMax(audio_length, timeline_length_));
|
||||
}
|
||||
|
||||
const QUuid &ViewerOutput::uuid() const
|
||||
|
||||
@@ -52,7 +52,6 @@ public:
|
||||
|
||||
NodeInput* texture_input() const;
|
||||
NodeInput* samples_input() const;
|
||||
NodeInput* length_input() const;
|
||||
|
||||
virtual void InvalidateCache(const rational &start_range, const rational &end_range, NodeInput *from = nullptr) override;
|
||||
virtual void InvalidateVisible(NodeInput *from) override;
|
||||
@@ -117,8 +116,6 @@ private:
|
||||
|
||||
NodeInput* samples_input_;
|
||||
|
||||
NodeInput* length_input_;
|
||||
|
||||
VideoParams video_params_;
|
||||
|
||||
AudioParams audio_params_;
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
#include "traverser.h"
|
||||
|
||||
#include "node.h"
|
||||
|
||||
NodeTraverser::NodeTraverser()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NodeValueDatabase NodeTraverser::GenerateDatabase(const Node* node, const TimeRange &range)
|
||||
{
|
||||
NodeValueDatabase database;
|
||||
|
||||
// We need to insert tables into the database for each input
|
||||
foreach (NodeParam* param, node->parameters()) {
|
||||
if (IsCancelled()) {
|
||||
return NodeValueDatabase();
|
||||
}
|
||||
|
||||
if (param->type() == NodeParam::kInput) {
|
||||
NodeInput* input = static_cast<NodeInput*>(param);
|
||||
TimeRange input_time = node->InputTimeAdjustment(input, range);
|
||||
|
||||
NodeValueTable table = ProcessInput(input, input_time);
|
||||
|
||||
InputProcessingEvent(input, input_time, &table);
|
||||
|
||||
database.Insert(input, table);
|
||||
}
|
||||
}
|
||||
|
||||
return database;
|
||||
}
|
||||
|
||||
NodeValueTable NodeTraverser::ProcessNode(const NodeDependency& dep)
|
||||
{
|
||||
const Node* node = dep.node();
|
||||
|
||||
if (node->IsTrack()) {
|
||||
// If the range is not wholly contained in this Block, we'll need to do some extra processing
|
||||
return RenderBlock(static_cast<const TrackOutput*>(node), dep.range());
|
||||
}
|
||||
|
||||
// FIXME: Cache certain values here if we've already processed them before
|
||||
|
||||
// Generate database of input values of node
|
||||
NodeValueDatabase database = GenerateDatabase(node, dep.range());
|
||||
|
||||
// By this point, the node should have all the inputs it needs to render correctly
|
||||
NodeValueTable table = node->Value(database);
|
||||
|
||||
ProcessNodeEvent(node, dep.range(), database, &table);
|
||||
|
||||
return table;
|
||||
}
|
||||
|
||||
NodeValueTable NodeTraverser::RenderBlock(const TrackOutput *track, const TimeRange &range)
|
||||
{
|
||||
// By default, don't bother traversing blocks
|
||||
return NodeValueTable();
|
||||
}
|
||||
|
||||
NodeValueTable NodeTraverser::ProcessInput(const NodeInput *input, const TimeRange& range)
|
||||
{
|
||||
if (input->IsConnected()) {
|
||||
// Value will equal something from the connected node, follow it
|
||||
return ProcessNode(NodeDependency(input->get_connected_node(), range));
|
||||
} else {
|
||||
// Push onto the table the value at this time from the input
|
||||
QVariant input_value = input->get_value_at_time(range.in());
|
||||
|
||||
NodeValueTable table;
|
||||
table.Push(input->data_type(), input_value);
|
||||
return table;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef NODETRAVERSER_H
|
||||
#define NODETRAVERSER_H
|
||||
|
||||
#include "codec/decoder.h"
|
||||
#include "common/cancelableobject.h"
|
||||
#include "dependency.h"
|
||||
#include "node/output/track/track.h"
|
||||
#include "project/item/footage/stream.h"
|
||||
#include "value.h"
|
||||
|
||||
class NodeTraverser : public CancelableObject
|
||||
{
|
||||
public:
|
||||
NodeTraverser();
|
||||
|
||||
NodeValueTable ProcessNode(const NodeDependency &dep);
|
||||
|
||||
protected:
|
||||
NodeValueDatabase GenerateDatabase(const Node *node, const TimeRange &range);
|
||||
|
||||
virtual NodeValueTable RenderBlock(const TrackOutput *track, const TimeRange& range);
|
||||
|
||||
NodeValueTable ProcessInput(const NodeInput* input, const TimeRange &range);
|
||||
|
||||
virtual void InputProcessingEvent(NodeInput*, const TimeRange&, NodeValueTable*){}
|
||||
|
||||
virtual void ProcessNodeEvent(const Node*, const TimeRange&, const NodeValueDatabase&, NodeValueTable*){}
|
||||
|
||||
};
|
||||
|
||||
#endif // NODETRAVERSER_H
|
||||
+2
-6
@@ -58,13 +58,9 @@ NodeValueTable::NodeValueTable()
|
||||
|
||||
QVariant NodeValueTable::Get(const NodeParam::DataType &type, const QString &tag) const
|
||||
{
|
||||
int value_index = GetInternal(type, tag);
|
||||
NodeValue v = GetWithMeta(type, tag);
|
||||
|
||||
if (value_index >= 0) {
|
||||
return values_.at(value_index).data();
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
return v.data();
|
||||
}
|
||||
|
||||
NodeValue NodeValueTable::GetWithMeta(const NodeParam::DataType &type, const QString &tag) const
|
||||
|
||||
Reference in New Issue
Block a user