TuttleOFX  1
ImageEffectNode.hpp
Go to the documentation of this file.
00001 #ifndef _TUTTLE_HOST_IMAGEEFFECTNODE_HPP_
00002 #define _TUTTLE_HOST_IMAGEEFFECTNODE_HPP_
00003 
00004 #include "INode.hpp"
00005 
00006 #include <tuttle/host/attribute/Param.hpp>
00007 #include <tuttle/host/attribute/ClipImage.hpp>
00008 #include <tuttle/host/graph/ProcessVertexData.hpp>
00009 #include <tuttle/host/graph/ProcessVertexAtTimeData.hpp>
00010 
00011 #include <tuttle/host/ofx/OfxhImageEffectNode.hpp>
00012 
00013 #include <boost/numeric/conversion/cast.hpp>
00014 
00015 namespace tuttle {
00016 namespace host {
00017 
00018 class ImageEffectNode : public INode
00019         , public ofx::imageEffect::OfxhImageEffectNode
00020 {
00021 public:
00022         typedef ImageEffectNode This;
00023 
00024 public:
00025         ImageEffectNode( ofx::imageEffect::OfxhImageEffectPlugin&         plugin,
00026                          ofx::imageEffect::OfxhImageEffectNodeDescriptor& desc,
00027                          const std::string&                               context );
00028 
00029         ImageEffectNode( const ImageEffectNode& other );
00030 
00031         ~ImageEffectNode();
00032 
00033         std::string getLabel() const { return ofx::imageEffect::OfxhImageEffectNodeBase::getLabel(); }
00034         const std::string&               getName() const                           { return ofx::imageEffect::OfxhImageEffectNodeBase::getName(); }
00035         void                             setName( const std::string& name )        { return ofx::imageEffect::OfxhImageEffectNodeBase::setName(name); }
00036         std::size_t                      getNbParams() const { return ofx::attribute::OfxhParamSet::getNbParams(); }
00037         const ofx::attribute::OfxhParam& getParam( const std::string& name ) const { return ofx::attribute::OfxhParamSet::getParam( name ); }
00038         ofx::attribute::OfxhParam&       getParam( const std::string& name )       { return ofx::attribute::OfxhParamSet::getParam( name ); }
00039         const ofx::attribute::OfxhParam& getParamByScriptName( const std::string& name, const bool acceptPartialName = false ) const { return ofx::attribute::OfxhParamSet::getParamByScriptName( name, acceptPartialName ); }
00040         ofx::attribute::OfxhParam&       getParamByScriptName( const std::string& name, const bool acceptPartialName = false )       { return ofx::attribute::OfxhParamSet::getParamByScriptName( name, acceptPartialName ); }
00041         const ofx::attribute::OfxhParam& getParam( const std::size_t  index ) const { return ofx::attribute::OfxhParamSet::getParam( index ); }
00042         ofx::attribute::OfxhParam&       getParam( const std::size_t  index )       { return ofx::attribute::OfxhParamSet::getParam( index ); }
00043 
00044         const ofx::property::OfxhSet& getProperties() const { return ofx::imageEffect::OfxhImageEffectNodeBase::getProperties(); }
00045         ofx::property::OfxhSet&       getEditableProperties() { return ofx::imageEffect::OfxhImageEffectNodeBase::getEditableProperties(); }
00046 
00047         std::vector<int> getVersion() const
00048         {
00049                 // don't works on many plugins
00050                 //return getProperties().fetchIntProperty( kOfxPropVersion ).getValues();
00051                 // so get values from plugin
00052                 std::vector<int> v;
00053                 v.push_back( getDescriptor().getPlugin().getVersionMajor() );
00054                 v.push_back( getDescriptor().getPlugin().getVersionMinor() );
00055                 return v;
00056         }
00057 
00058         ImageEffectNode* clone() const
00059         {
00060                 return new ImageEffectNode( *this );
00061         }
00062 
00063         bool operator==( const INode& other ) const;
00064         bool operator==( const ImageEffectNode& other ) const;
00065 
00066         const ENodeType getNodeType() const { return eNodeTypeImageEffect; }
00067 
00068         void connect( const INode& sourceEffect, attribute::Attribute& attr );
00069 
00070         attribute::ClipImage&       getClip( const std::string& name, const bool acceptPartialName = false )       { return dynamic_cast<attribute::ClipImage&>( ofx::attribute::OfxhClipImageSet::getClip( name, acceptPartialName ) ); }
00071         const attribute::ClipImage& getClip( const std::string& name, const bool acceptPartialName = false ) const { return dynamic_cast<const attribute::ClipImage&>( ofx::attribute::OfxhClipImageSet::getClip( name, acceptPartialName ) ); }
00072 
00073         attribute::Attribute& getAttribute( const std::string& name ) { return getClip( name ); }
00074         attribute::Attribute& getSingleInputAttribute();
00075 
00076         const attribute::Attribute& getSingleInputAttribute() const { return const_cast<ImageEffectNode*>( this )->getSingleInputAttribute(); }
00077 
00078         ofx::attribute::OfxhParamSet& getParamSet() { return *this; }
00079         const ofx::attribute::OfxhParamSet& getParamSet() const { return *this; }
00080 
00081         ofx::attribute::OfxhClipImageSet& getClipImageSet() { return *this; }
00082         const ofx::attribute::OfxhClipImageSet& getClipImageSet() const { return *this; }
00083         
00084         std::size_t getLocalHashAtTime( const OfxTime time ) const;
00085         
00086         OfxRectD getRegionOfDefinition( const OfxTime time ) const
00087         {
00088                 return getData(time)._apiImageEffect._renderRoD;
00089         }
00090         
00091         OfxRangeD getTimeDomain() const
00092         {
00093                 return getData()._timeDomain;
00094         }
00095 
00096         void debugOutputImage( const OfxTime time ) const;
00097 
00098         OfxRangeD getDefaultTimeDomain() const;
00099 
00100         /// @group Implementation of INode virtual functions
00101         /// @{
00102         OfxRangeD computeTimeDomain();
00103 
00104         void setup1();
00105         void setup2_reverse();
00106         void setup3();
00107         
00108         void beginSequence( graph::ProcessVertexData& vData );
00109 
00110         INode::ClipTimesSetMap getTimesNeeded( const OfxTime time ) const { return OfxhImageEffectNode::getFramesNeeded(time); }
00111 
00112         void preProcess1( graph::ProcessVertexAtTimeData& vData );
00113         void preProcess2_reverse( graph::ProcessVertexAtTimeData& vData );
00114         
00115         bool isIdentity( const graph::ProcessVertexAtTimeData& vData, std::string& clip, OfxTime& time ) const;
00116         void preProcess_infos( const graph::ProcessVertexAtTimeData& vData, const OfxTime time, graph::ProcessVertexAtTimeInfo& nodeInfos ) const;
00117         void process( graph::ProcessVertexAtTimeData& vData );
00118         void postProcess( graph::ProcessVertexAtTimeData& vData );
00119 
00120         void endSequence( graph::ProcessVertexData& vData );
00121         /// @}
00122 
00123         std::ostream& print( std::ostream& os ) const;
00124 
00125         friend std::ostream& operator<<( std::ostream& os, const This& v );
00126 
00127 
00128         ////////////////////////////////////////////////////////////////////////////////
00129         ////////////////////////////////////////////////////////////////////////////////
00130         ////////////////////////////////////////////////////////////////////////////////
00131         // overridden for imageEffect::OfxhImageEffectNode
00132 
00133         /// get default output fielding. This is passed into the clip prefs action
00134         /// and  might be mapped (if the host allows such a thing)
00135         const std::string& getDefaultOutputFielding() const;
00136 
00137         /**
00138          * @return 1 to abort processing
00139          */
00140         int abort();
00141 
00142         /**
00143          * Allocating memory using the memoryPool
00144          */
00145         ofx::OfxhMemory* newMemoryInstance( size_t nBytes );
00146 
00147         /// make a clip
00148         ofx::attribute::OfxhClipImage* newClipImage( const ofx::attribute::OfxhClipImageDescriptor& descriptor );
00149 
00150 #ifndef SWIG
00151         /// vmessage
00152         void vmessage( const char* type,
00153                        const char* id,
00154                        const char* format,
00155                        va_list     args ) const OFX_EXCEPTION_SPEC;
00156 #endif
00157         
00158         // The size of the current project in canonical coordinates.
00159         // The size of a project is a sub set of the kOfxImageEffectPropProjectExtent. For example a
00160         // project may be a PAL SD project, but only be a letter-box within that. The project size is
00161         // the size of this sub window.
00162         void getProjectSize( double& xSize, double& ySize ) const;
00163 
00164         // The offset of the current project in canonical coordinates.
00165         // The offset is related to the kOfxImageEffectPropProjectSize and is the offset from the origin
00166         // of the project 'subwindow'. For example for a PAL SD project that is in letterbox form, the
00167         // project offset is the offset to the bottom left hand corner of the letter box. The project
00168         // offset is in canonical coordinates.
00169         void getProjectOffset( double& xOffset, double& yOffset ) const;
00170 
00171         // The extent of the current project in canonical coordinates.
00172         // The extent is the size of the 'output' for the current project. See ProjectCoordinateSystems
00173         // for more infomation on the project extent. The extent is in canonical coordinates and only
00174         // returns the top right position, as the extent is always rooted at 0,0. For example a PAL SD
00175         // project would have an extent of 768, 576.
00176         void getProjectExtent( double& xSize, double& ySize ) const;
00177 
00178         // The pixel aspect ratio of the current project
00179         double getProjectPixelAspectRatio() const;
00180 
00181         // The pixel components type of the current project
00182         const std::string getProjectPixelComponentsType() const;
00183 
00184         // The pixel bit depth of the current project
00185         const std::string getProjectBitDepth() const;
00186 
00187         // The duration of the effect
00188         // This contains the duration of the plug-in effect, in frames.
00189         double getEffectDuration() const;
00190 
00191         /// This is called whenever a param is changed by the plugin so that
00192         /// the recursive instanceChangedAction will be fed the correct frame
00193         double getFrameRecursive() const;
00194 
00195         /// This is called whenever a param is changed by the plugin so that
00196         /// the recursive instanceChangedAction will be fed the correct
00197         /// renderScale
00198         void getRenderScaleRecursive( double& x, double& y ) const;
00199 
00200         ////////////////////////////////////////////////////////////////////////////////
00201         ////////////////////////////////////////////////////////////////////////////////
00202         ////////////////////////////////////////////////////////////////////////////////
00203         // overridden for Param::SetInstance
00204 
00205         /// make a parameter instance
00206         ///
00207         /// Client host code needs to implement this
00208         ofx::attribute::OfxhParam* newParam( const ofx::attribute::OfxhParamDescriptor& Descriptor ) OFX_EXCEPTION_SPEC;
00209 
00210         /// Triggered when the plug-in calls OfxParameterSuiteV1::paramEditBegin
00211         ///
00212         /// Client host code needs to implement this
00213         void editBegin( const std::string& name ) OFX_EXCEPTION_SPEC;
00214 
00215         /// Triggered when the plug-in calls OfxParameterSuiteV1::paramEditEnd
00216         ///
00217         /// Client host code needs to implement this
00218         void editEnd() OFX_EXCEPTION_SPEC;
00219 
00220         ////////////////////////////////////////////////////////////////////////////////
00221         ////////////////////////////////////////////////////////////////////////////////
00222         ////////////////////////////////////////////////////////////////////////////////
00223         // overridden for OfxhIProgress
00224 
00225         /// Start doing progress.
00226         void progressStart( const std::string& message );
00227 
00228         /// finish yer progress
00229         void progressEnd();
00230 
00231         /// set the progress to some level of completion,
00232         /// returns true if you should abandon processing, false to continue
00233         bool progressUpdate( const double t );
00234 
00235         ////////////////////////////////////////////////////////////////////////////////
00236         ////////////////////////////////////////////////////////////////////////////////
00237         ////////////////////////////////////////////////////////////////////////////////
00238         // overridden for OfxhITimeLine
00239 
00240         /// get the current time on the timeline. This is not necessarily the same
00241         /// time as being passed to an action (eg render)
00242         double timelineGetTime();
00243 
00244         /// set the timeline to a specific time
00245         void timelineGotoTime( double t );
00246 
00247         /// get the first and last times available on the effect's timeline
00248         void timelineGetBounds( double& t1, double& t2 );
00249 
00250         const OfxRangeD& getEffectFrameRange() const
00251         {
00252                 return getData()._renderTimeRange;
00253         }
00254 
00255         void beginSequenceRenderAction( OfxTime   startFrame,
00256                                 OfxTime   endFrame,
00257                                 OfxTime   step,
00258                                 bool      interactive,
00259                                 OfxPointD renderScale ) OFX_EXCEPTION_SPEC;
00260 
00261 private:
00262         void checkClipsConnections() const;
00263 
00264         void initComponents();
00265         void initInputClipsPixelAspectRatio();
00266         void initPixelAspectRatio();
00267         void initInputClipsFps();
00268         void initFps();
00269         
00270         void maximizeBitDepthFromReadsToWrites();
00271         void maximizeBitDepthFromWritesToReads();
00272         void coutBitDepthConnections() const;
00273         void validBitDepthConnections() const;
00274 };
00275 
00276 }
00277 }
00278 
00279 #endif