node: split off traversing functions from renderer for usage elsewhere

Fixes issue where Viewer node wouldn't pick up correct length if a tracks
weren't in use.
This commit is contained in:
itsmattkc
2020-03-13 15:31:15 +11:00
parent 41da5dbd53
commit 9e4c79699e
18 changed files with 218 additions and 142 deletions
+29 -83
View File
@@ -87,95 +87,41 @@ bool RenderWorker::IsStarted()
return started_;
}
NodeValueTable RenderWorker::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);
// Check if we have a shader for this output
RunNodeAccelerated(node, dep.range(), database, &table);
return table;
}
NodeValueTable RenderWorker::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;
}
}
void RenderWorker::ReportUnavailableFootage(StreamPtr stream, Decoder::RetrieveState state, const rational& stream_time)
{
emit FootageUnavailable(stream, state, path_.range(), stream_time);
}
void RenderWorker::InputProcessingEvent(NodeInput* input, const TimeRange& input_time, NodeValueTable *table)
{
// Exception for Footage types where we actually retrieve some Footage data from a decoder
if (input->data_type() == NodeParam::kFootage) {
StreamPtr stream = ResolveStreamFromInput(input);
if (stream) {
DecoderPtr decoder = ResolveDecoderFromInput(stream);
if (decoder) {
Decoder::RetrieveState state = decoder->GetRetrieveState(input_time.out());
if (state == Decoder::kReady) {
FrameToValue(decoder, stream, input_time, table);
} else {
ReportUnavailableFootage(stream, state, input_time.out());
}
}
}
}
}
void RenderWorker::ProcessNodeEvent(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params)
{
// Check if we have a shader for this output
RunNodeAccelerated(node, range, input_params, output_params);
}
const NodeDependency &RenderWorker::CurrentPath() const
{
return path_;
}
#include "common/functiontimer.h"
NodeValueDatabase RenderWorker::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);
// Exception for Footage types where we actually retrieve some Footage data from a decoder
if (input->data_type() == NodeParam::kFootage) {
StreamPtr stream = ResolveStreamFromInput(input);
if (stream) {
DecoderPtr decoder = ResolveDecoderFromInput(stream);
if (decoder) {
Decoder::RetrieveState state = decoder->GetRetrieveState(input_time.out());
if (state == Decoder::kReady) {
FrameToValue(decoder, stream, input_time, &table);
} else {
ReportUnavailableFootage(stream, state, input_time.out());
}
}
}
}
database.Insert(input, table);
}
}
return database;
}
+12 -15
View File
@@ -3,13 +3,13 @@
#include <QObject>
#include "common/cancelableobject.h"
#include "common/constructors.h"
#include "node/output/track/track.h"
#include "node/node.h"
#include "decodercache.h"
#include "node/node.h"
#include "node/output/track/track.h"
#include "node/traverser.h"
class RenderWorker : public QObject, public CancelableObject
class RenderWorker : public QObject, public NodeTraverser
{
Q_OBJECT
public:
@@ -38,24 +38,21 @@ protected:
virtual void RunNodeAccelerated(const Node *node, const TimeRange& range, const NodeValueDatabase &input_params, NodeValueTable* output_params);
StreamPtr ResolveStreamFromInput(NodeInput* input);
DecoderPtr ResolveDecoderFromInput(StreamPtr stream);
virtual void FrameToValue(DecoderPtr decoder, StreamPtr stream, const TimeRange &range, NodeValueTable* table) = 0;
NodeValueTable ProcessNode(const NodeDependency &dep);
virtual NodeValueTable RenderBlock(const TrackOutput *track, const TimeRange& range) = 0;
NodeValueTable ProcessInput(const NodeInput* input, const TimeRange &range);
virtual void ReportUnavailableFootage(StreamPtr stream, Decoder::RetrieveState state, const rational& stream_time);
virtual void InputProcessingEvent(NodeInput *input, const TimeRange &input_time, NodeValueTable* table) override;
virtual void ProcessNodeEvent(const Node *node, const TimeRange &range, const NodeValueDatabase &input_params, NodeValueTable* output_params) override;
StreamPtr ResolveStreamFromInput(NodeInput* input);
DecoderPtr ResolveDecoderFromInput(StreamPtr stream);
const NodeDependency& CurrentPath() const;
private:
NodeValueDatabase GenerateDatabase(const Node *node, const TimeRange &range);
bool started_;
DecoderCache* decoder_cache_;