diff --git a/src/proc/engine/nodefactory.cpp b/src/proc/engine/nodefactory.cpp new file mode 100644 index 000000000..d439232f3 --- /dev/null +++ b/src/proc/engine/nodefactory.cpp @@ -0,0 +1,41 @@ +/* + NodeFactory - Interface for creating processing nodes of variouos kinds + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + + +#include "proc/engine/nodefactory.hpp" +#include "proc/mobject/session/effect.hpp" + +namespace engine { + + using mobject::Placement; + using mobject::session::Effect; + + + /** create a processing node able to render an effect */ + PTrafo + NodeFactory::operator() (Placement const&) + { + UNIMPLEMENTED ("create proc node for Effect/Plugin"); + } + + +} // namespace engine diff --git a/src/proc/engine/nodefactory.hpp b/src/proc/engine/nodefactory.hpp new file mode 100644 index 000000000..8dbcc5f0c --- /dev/null +++ b/src/proc/engine/nodefactory.hpp @@ -0,0 +1,70 @@ +/* + NODEFACTORY.hpp - Interface for creating processing nodes of variouos kinds + + Copyright (C) Lumiera.org + 2008, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#ifndef ENGINE_NODEFACTORY_H +#define ENGINE_NODEFACTORY_H + +#include "proc/engine/procnode.hpp" +#include "proc/mobject/placement.hpp" + + + +namespace mobject { + namespace session { + + class Clip; + class Effect; + typedef Placement PEffect; + // TODO: class Transition; + + } // namespace mobject::session + +} // namespace mobject + + +namespace engine { + + using std::vector; + + class Trafo; + typedef Trafo* PTrafo; ///< @todo handle ProcNode by pointer or by shared-ptr?? + + + /** + * Create processing nodes based on given objects of the high-level model. + */ + class NodeFactory + { + /** custom deleter func allowing a smart-ptr + * to take ownership of processing nodes + */ + static void deleterFunc (ProcNode* pno) { delete pno; } + + public: + + PTrafo operator() (mobject::session::PEffect const&); + + }; + +} // namespace engine +#endif diff --git a/src/proc/engine/procnode.cpp b/src/proc/engine/procnode.cpp index 48e33c498..984c4dece 100644 --- a/src/proc/engine/procnode.cpp +++ b/src/proc/engine/procnode.cpp @@ -22,12 +22,14 @@ #include "proc/engine/procnode.hpp" +#include "proc/engine/nodefactory.hpp" -namespace engine - { +namespace engine { - /** */ + /** Storage for the (single, static) ProcNode factory object. + */ + NodeFactory ProcNode::create; } // namespace engine diff --git a/src/proc/engine/procnode.hpp b/src/proc/engine/procnode.hpp index ae210f96b..e2a4c89b9 100644 --- a/src/proc/engine/procnode.hpp +++ b/src/proc/engine/procnode.hpp @@ -29,12 +29,16 @@ #include "proc/mobject/parameter.hpp" -using std::vector; +namespace engine { -namespace engine - { + using std::vector; + + class ProcNode; + class NodeFactory; + + typedef ProcNode* PNode; ///< @todo handle ProcNode by pointer or by shared-ptr?? /** @@ -42,16 +46,37 @@ namespace engine */ class ProcNode { - protected: typedef mobject::Parameter Param; /** The predecessor in a processing pipeline. * I.e. a source to get data to be processed */ - ProcNode * datasrc; + PNode datasrc; vector params; + protected: + ProcNode(); + virtual ~ProcNode() {}; + + friend class NodeFactory; + + + /** do the actual calculations. + * @internal dispatch to implementation. + * Client code should use #render() + * @todo obviously we need a parameter!!! + */ + virtual void process() = 0; + + public: + static NodeFactory create; + + /** render and pull output from this node. + * @todo define the parameter!!! + */ + void render() { this->process(); } + }; } // namespace engine diff --git a/src/proc/engine/trafo.hpp b/src/proc/engine/trafo.hpp index 8d2155661..d1b6ba3cb 100644 --- a/src/proc/engine/trafo.hpp +++ b/src/proc/engine/trafo.hpp @@ -42,9 +42,23 @@ namespace engine */ class Trafo : public ProcNode { - /////////// + protected: + Trafo() : ProcNode() { }; + + friend class NodeFactory; + + + + /** do the actual calculations. + * @internal dispatch to implementation. + * Client code should use #render() + * @todo obviously we need a parameter!!! + */ + virtual void process() = 0; }; + typedef Trafo* PTrafo; ///< @todo handle ProcNode by pointer or by shared-ptr?? + } // namespace engine diff --git a/src/proc/mobject/builder/mould.hpp b/src/proc/mobject/builder/mould.hpp index 6c714157a..be29f2b21 100644 --- a/src/proc/mobject/builder/mould.hpp +++ b/src/proc/mobject/builder/mould.hpp @@ -39,19 +39,21 @@ namespace mobject { /** - * Interface: a holder tool used by the builder to - * wire up a specific building situation and then to - * apply/execute a single building step. Mould is the - * passive part, while usually the ProcPatt is the active - * counterpart. By means of the Mould interface, the specifics - * of a build situation are abstracted away, thus allowing the - * processing pattern to be defined as working on symbolic - * locations. The most common location is "current", denoting - * the render node just being built. + * Interface: a workbench-like tool used by the builder + * for wiring up a specific building situation, followed by + * the application/execution of a single building step. Mould is + * conceived as the passive part, while usually the ProcPatt plays + * the role of the active counterpart. By means of the Mould interface, + * the specifics of a build situation are abstracted away, thus allowing + * the processing pattern to be defined as working on symbolic locations. + * Most commonly this is "current", denoting the render node just being built. *
  • PipeMould supports attaching an effect to a pipe
  • *
  • combining pipes via a transition is done by a CombiningMould
  • *
  • a SourceChainMould allows to start out from a source reader and build a clip
  • - *
  • wiring general connections is supported by the WiringMould
  • + *
  • wiring general connections is supported by the WiringMould
  • + *
+ * @see ToolFactory + * @see NodeCreatorTool */ class Mould { diff --git a/src/proc/mobject/builder/operationpoint.hpp b/src/proc/mobject/builder/operationpoint.hpp index d48e9ecf6..daa0f18d6 100644 --- a/src/proc/mobject/builder/operationpoint.hpp +++ b/src/proc/mobject/builder/operationpoint.hpp @@ -24,12 +24,18 @@ #ifndef MOBJECT_BUILDER_OPERATIONPOINT_H #define MOBJECT_BUILDER_OPERATIONPOINT_H +#include "proc/engine/procnode.hpp" +#include "common/query.hpp" +#include +#include namespace mobject { namespace builder { + using std::vector; + using std::string; /** * A point in the render node network under construction. @@ -40,8 +46,23 @@ namespace mobject { */ class OperationPoint { - public: + typedef engine::PNode PNode; + vector refPoint_; + const string streamID_; + + public: + /** create node(s) corresponding to the given Processor-Asset + * and wire them as a successor to this OperationPoint; then + * move this point to point at the resulting new exit node(s) + */ + void attach (asset::PProc const&); + + /** connect the output this OperationPoint referes such as to + * connect or combine with the input of the already existing + * nodes accessible via the target OperationPoint. + */ + void join (OperationPoint& target); }; diff --git a/src/proc/mobject/builder/toolfactory.hpp b/src/proc/mobject/builder/toolfactory.hpp index 5d30c9eea..ecb9f7949 100644 --- a/src/proc/mobject/builder/toolfactory.hpp +++ b/src/proc/mobject/builder/toolfactory.hpp @@ -25,6 +25,7 @@ #define MOBJECT_BUILDER_TOOLFACTORY_H #include "proc/mobject/builder/buildertool.hpp" +#include "proc/mobject/builder/mould.hpp" #include "proc/asset/pipe.hpp" #include "proc/mobject/session/clip.hpp" #include "proc/mobject/builder/wiringrequest.hpp" diff --git a/src/proc/mobject/session/mobjectfactory.hpp b/src/proc/mobject/session/mobjectfactory.hpp index 427385194..e1a7a5695 100644 --- a/src/proc/mobject/session/mobjectfactory.hpp +++ b/src/proc/mobject/session/mobjectfactory.hpp @@ -28,8 +28,8 @@ -namespace asset - { +namespace asset { + class Clip; class Media; class Track; @@ -37,10 +37,9 @@ namespace asset } -namespace mobject - { - namespace session - { +namespace mobject { + namespace session { + class Clip; class Track; class Effect; @@ -57,10 +56,10 @@ namespace mobject public: - Placement operator() (const asset::Clip&, const asset::Media&); - Placement operator() (const asset::Clip&, vector); + Placement operator() (asset::Clip const&, asset::Media const&); + Placement operator() (asset::Clip const&, vector); Placement operator() (PTrackAsset&); - Placement operator() (const asset::Effect&); + Placement operator() (asset::Effect const&); }; diff --git a/wiki/renderengine.html b/wiki/renderengine.html index c55d698a2..44b635e79 100644 --- a/wiki/renderengine.html +++ b/wiki/renderengine.html @@ -773,13 +773,14 @@ As the builder has to create a render node network implementing most of the feat !!pattern of operation The working pattern of this builder mechanics can be described as triggering, enqueuing, priorizing, recursing and exhausting. Without the priorizing part, it would be a depth-first call graph without any context state, forcing us to have all cross reference information available at every node or element to be treated. We prefer to avoid this overhead by ordering the operations into several phases and within these phases into correlated entities with the help of a ''weighting function'' and scheduling with a ''priority queue'' -
+
The [[Builder]] uses different kinds of tools for creating a network of render nodes from a given high-level model. When breaking down this (necessarily complex) process into small manageable chunks, we arrive at [[elementary building situations|BuilderPrimitives]]. For each of these there is a specialized tool. We denote these tools as "moulds" because they are a rather passive holder for the objects to be attached and wired up. They are shaped according to the basic form the connections have to follow for each of these basic situations:
 * attaching an effect to a pipe
 * combining pipes via a transition
 * starting out a pipe from a source reader
 * general connections from the exit node of a pipe to the port of another pipe
-In all those cases, the active part is provided by [[processing patterns|ProcPatt]] &mdash; sort of micro programs executed within the context of a given mould: the processing pattern defines the steps to take (in the standard/basic case this is just "attach"), while the mould holds and provides the location where these steps will operate.
+In all those cases, the active part is provided by [[processing patterns|ProcPatt]] &mdash; sort of micro programs executed within the context of a given mould: the processing pattern defines the steps to take (in the standard/basic case this is just "attach"), while the mould holds and provides the location where these steps will operate. Actually, this location is represented as a OperationPoint, provided by the mould and abstracting the details of making multi-channel connections. +
While assembling and building up the render engines node network, a small number of primitive building situations is encountered repeatedly. The BuilderToolKit provides a "[[mould|BuilderMould]]" for each of these situations, typically involving parametrisation and the application of a [[processing pattern|ProcPatt]].
@@ -852,13 +853,9 @@ While building, the application of such a visiting tool (especially the [[NodeCr
 
 
-
+
Besides the primary working tool within the builder (namely the [[Node Creator Tool|PlanningNodeCreatorTool]]), on a lower level, we encounter several [[elementary building situations|BuilderPrimitives]] &mdash; and for each of these elementary situations we can retrieve a suitable "fitting tool" or [[mould|BuilderMould]]. The palette of these moulds is called the ''tool kit'' of the builder. It is subject to configuration by rules.
 
-!! {{red{open questions}}}
-* how to address these moulds
-* how to type them
-* how to parametrize them
 
 !!addressing a mould
 All mould instances are owned and managed by the [[tool factory|BuilderToolFactory]], and can be referred to by their type ({{{PipeMould}}}, {{{CombiningMould}}}, {{{SourceChainMould}}}, {{{WiringMould}}}) and a concrete object instance (of suitable type). The returned mould (instance) acts as a handle to stick together the given object instance (from the high-level model) with the corresponding point in the low-level node network under construction. As consequence of this approach, the tool factory instance holds a snapshot of the current building state, including all the active spots in the build process. As the latter is driven by objects from the high-level model appearing (in a sensible order &rarr; see BuilderMechanics) within the NodeCreatorTool, new moulds will be created and fitted as necessary, and existing moulds will be exhausted when finished, until the render node network is complete.
@@ -869,7 +866,10 @@ As each mould kind is different, it has a {{{prepare(...)}}} function with suita
 !!sequence of operations
 When {{{operate()}}} doesn't throw, the result is a list of //successor moulds// &mdash; you shouldn't use the original mould after triggering its operation, because it may have been retracted as a result and reused for another purpose by the tool factory. It is not necessary to store these resulting moulds either (as they can be retrieved as described above), but they can be used right away for the next building step if applicable. In the state they are returned from a successful building step (mould operation = execution of a contained [[processing pattern|ProcPatt]]), they are usually already holding a reference to the part of the network just created and need to be configured only with the next high-level object (effect, placement, pipe, processing pattern or similar, depending on the concrete situation) in order to carry out the next step.
 
-&rarr;see also: BuilderPrimitives for the elementary working situations corresponding to these fitting tools
+!!single connection step
+at the lowest level within the builder there is the step of building a //connection.// This step is executed by the processing pattern with the help of the mould. Actually, making such a connection is more complicated, because in the standard case it will connect N media streams simultaneously (N=2 for stereo sound or 3D video, N=6 for 5.1 Surround, N=9 for 2nd order Ambisonics). These details are encapsulated within the OperationPoint, which is provides by the mould and exhibits a common interface for the processing pattern to express the connecting operation.
+
+&rarr;see also: BuilderPrimitives for the elementary working situations corresponding to each of these [[builder moulds|BuilderMould]]
 
@@ -1831,6 +1831,14 @@ But because I know the opinions on this topc are varying (users tend to be delig My proposed aproach is to treat OpenGL as a separate video raw data type, requiring separete and specialized [[Processing Nodes|ProcNode]] for all calculations. Thus the Builder could connect OpenGL nodes if it is possible to cover the whole render path for preview and fall back to the normal ~ProcNodes for all relevant renders
+
+
A low-level abstraction within the [[Builder]] &mdash; it serves to encapsulate the details of making multi-channel connections between the render nodes: In some cases, a node can handle N channels internally, while in other cases we need to replicate the node N times and wire each channel individually.
+
+The operation point is provided by the current BuilderMould and used by the [[processing pattern|ProcPatt]] executing within this mould and conducting the current build step. The operation point's interface allows //to abstract//&nbsp; these details, as well as to //gain additional control//&nbsp; if necessary (e.g. addressing only one of the channels). The most prominent build instruction used within the processing patterns (which is the instruction {{{"attach"}}}) relies on the aforementioned //approach of abstracted handling,// letting the operation point determine automatically how to make the connection.
+
+This is possible because the operation point has been provided (by the mould) with informations about the media stream type to be wired, while at the same time relying on the [[render node interface|ProcNode]] for finding out whats possible and making the desired connections.
+
+
The Lumiera Processing Layer is comprised of various subsystems and can be separated into a low-level and a high-level part. At the low-level end is the [[Render Engine|OverviewRenderEngine]] which basically is a network of render nodes cooperating closely with the Backend Layer in order to carry out the actual playback and media transforming calculations. Whereas on the high-level side we find several different [[Media Objects|MObjects]] that can be placed into the [[EDL]], edited and manipulated. This is complemented by the [[Asset Management|Asset]], which is the "bookkeeping view" of all the different "things" within each [[Session|SessionOverview]].
 
@@ -2657,8 +2665,17 @@ The system is ''open'' inasmuch every part mirrors the structure of correspondin
 &rarr; [[Implementation Details|ImplementationDetails]] {{red{WIP}}}
 
-
+
A data processing node within the Render Engine. Its key feature is the possibility to pull from it one (freely addressable) [[Frame]] of calculated data. Further, each ~ProcNode has the ability to be wired with other nodes and [[Parameter Providers|ParamProvider]]
+
+!! {{red{open questions}}}
+* how to address a node
+* how to type them
+* how to discover the number and type of the ports
+* how to discover the possible parameter ports
+* how to define and query for additional capabilities
+
+&rarr; see also the [[open design process draft|http://www.pipapo.org/pipawiki/Lumiera/DesignProcess/DesignRenderNodesInterface]]