TuttleOFX
1
|
00001 #include "SwscalePlugin.hpp" 00002 #include "SwscaleProcess.hpp" 00003 #include "SwscaleDefinitions.hpp" 00004 00005 #include <libav/LibAV.hpp> 00006 00007 #include <tuttle/plugin/ofxToGil/point.hpp> 00008 #include <terry/point/operations.hpp> 00009 #include <boost/numeric/conversion/cast.hpp> 00010 00011 00012 namespace tuttle { 00013 namespace plugin { 00014 namespace swscale { 00015 00016 using boost::numeric_cast; 00017 00018 00019 int filterParamToSwscaleFlag( const EParamFilter paramFilter ) 00020 { 00021 switch( paramFilter ) 00022 { 00023 case eParamFilterFastBilinear: 00024 return SWS_FAST_BILINEAR; 00025 case eParamFilterBilinear: 00026 return SWS_BILINEAR; 00027 case eParamFilterBicubic: 00028 return SWS_BICUBIC; 00029 case eParamFilterX: 00030 return SWS_X; 00031 case eParamFilterPoint: 00032 return SWS_POINT; 00033 case eParamFilterArea: 00034 return SWS_AREA; 00035 case eParamFilterBicublin: 00036 return SWS_BICUBLIN; 00037 case eParamFilterGauss: 00038 return SWS_GAUSS; 00039 case eParamFilterSinc: 00040 return SWS_SINC; 00041 case eParamFilterLanczos: 00042 return SWS_LANCZOS; 00043 case eParamFilterSpline: 00044 return SWS_SPLINE; 00045 } 00046 BOOST_ASSERT( false ); 00047 return SWS_FAST_BILINEAR; 00048 } 00049 00050 00051 00052 SwscalePlugin::SwscalePlugin( OfxImageEffectHandle handle ) 00053 : ImageEffectGilPlugin( handle ) 00054 { 00055 _paramMode = fetchChoiceParam ( kParamMode ); 00056 00057 _paramFormat = fetchChoiceParam ( kParamFormat ); 00058 00059 _paramScale = fetchDouble2DParam ( kParamModeScale ); 00060 00061 _paramSize = fetchInt2DParam ( kParamSize ); 00062 _paramSizeWidth = fetchIntParam ( kParamSizeWidth ); 00063 _paramSizeHeight = fetchIntParam ( kParamSizeHeight ); 00064 _paramSizeOrientation = fetchChoiceParam ( kParamSizeOrientation ); 00065 _paramSizeKeepRatio = fetchBooleanParam ( kParamSizeKeepRatio ); 00066 00067 _paramFilter = fetchChoiceParam ( kParamFilter ); 00068 00069 updateVisibleTools(); 00070 } 00071 00072 void SwscalePlugin::updateVisibleTools() 00073 { 00074 OFX::InstanceChangedArgs args( this->timeLineGetTime() ); 00075 00076 changedParam( args, kParamMode ); 00077 changedParam( args, kParamFilter ); 00078 changedParam( args, kParamSizeKeepRatio ); 00079 changedParam( args, kParamSizeOrientation ); 00080 } 00081 00082 SwscaleProcessParams SwscalePlugin::getProcessParams( const OfxPointD& renderScale ) const 00083 { 00084 SwscaleProcessParams params; 00085 00086 params._filter = static_cast<EParamFilter>( _paramFilter-> getValue() ); 00087 params._sws_filter = filterParamToSwscaleFlag( params._filter ); 00088 00089 return params; 00090 } 00091 00092 void SwscalePlugin::changedParam( const OFX::InstanceChangedArgs &args, const std::string ¶mName ) 00093 { 00094 ImageEffectGilPlugin::changedParam( args, paramName ); 00095 00096 if( paramName == kParamMode ) 00097 { 00098 switch( _paramMode->getValue() ) 00099 { 00100 case eParamModeFormat: 00101 { 00102 _paramScale -> setIsSecretAndDisabled( true ); 00103 _paramSize -> setIsSecretAndDisabled( true ); 00104 _paramSizeWidth -> setIsSecretAndDisabled( true ); 00105 _paramSizeHeight -> setIsSecretAndDisabled( true ); 00106 _paramSizeOrientation -> setIsSecretAndDisabled( true ); 00107 _paramSizeKeepRatio -> setIsSecretAndDisabled( true ); 00108 00109 _paramFormat -> setIsSecretAndDisabled( false ); 00110 break; 00111 } 00112 case eParamModeSize: 00113 { 00114 const bool keepRatio = _paramSizeKeepRatio->getValue(); 00115 const EParamSizeOrientation orientation = static_cast<EParamSizeOrientation>(_paramSizeOrientation->getValue()); 00116 00117 _paramFormat -> setIsSecretAndDisabled( true ); 00118 _paramScale -> setIsSecretAndDisabled( true ); 00119 00120 _paramSizeKeepRatio -> setIsSecretAndDisabled( false ); 00121 00122 _paramSizeWidth -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationX ); 00123 _paramSizeHeight -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationY ); 00124 _paramSizeOrientation -> setIsSecretAndDisabled( ! keepRatio ); 00125 _paramSize -> setIsSecretAndDisabled( keepRatio ); 00126 break; 00127 } 00128 case eParamModeScale: 00129 { 00130 _paramFormat -> setIsSecretAndDisabled( true ); 00131 _paramSize -> setIsSecretAndDisabled( true ); 00132 _paramSizeWidth -> setIsSecretAndDisabled( true ); 00133 _paramSizeHeight -> setIsSecretAndDisabled( true ); 00134 _paramSizeOrientation -> setIsSecretAndDisabled( true ); 00135 _paramSizeKeepRatio -> setIsSecretAndDisabled( true ); 00136 00137 _paramScale -> setIsSecretAndDisabled( false ); 00138 break; 00139 } 00140 } 00141 } 00142 else if( paramName == kParamFormat && args.reason == OFX::eChangeUserEdit ) 00143 { 00144 std::size_t width = 0; 00145 std::size_t height = 0; 00146 getFormatResolution( static_cast<EParamFormat>(_paramFormat->getValue()), width, height ); 00147 00148 _paramMode -> setValue( eParamModeFormat ); 00149 _paramSize -> setValue( numeric_cast<int>(width), numeric_cast<int>(height) ); 00150 _paramSizeWidth -> setValue( numeric_cast<int>(width) ); 00151 _paramSizeHeight -> setValue( numeric_cast<int>(height) ); 00152 } 00153 else if( paramName == kParamSize && args.reason == OFX::eChangeUserEdit ) 00154 { 00155 const OfxPointI s = _paramSize->getValue(); 00156 00157 _paramMode->setValue( eParamModeSize ); 00158 _paramSizeWidth -> setValue( s.x ); 00159 _paramSizeHeight -> setValue( s.y ); 00160 } 00161 else if( paramName == kParamSizeKeepRatio && args.reason == OFX::eChangeUserEdit ) 00162 { 00163 const bool keepRatio = _paramSizeKeepRatio->getValue(); 00164 const EParamSizeOrientation orientation = static_cast<EParamSizeOrientation>(_paramSizeOrientation->getValue()); 00165 00166 _paramSizeWidth -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationX ); 00167 _paramSizeHeight -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationY ); 00168 _paramSizeOrientation -> setIsSecretAndDisabled( ! keepRatio ); 00169 _paramSize -> setIsSecretAndDisabled( keepRatio ); 00170 } 00171 else if( paramName == kParamSizeOrientation && args.reason == OFX::eChangeUserEdit ) 00172 { 00173 const bool keepRatio = _paramSizeKeepRatio->getValue(); 00174 const EParamSizeOrientation orientation = static_cast<EParamSizeOrientation>(_paramSizeOrientation->getValue()); 00175 00176 _paramSizeWidth -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationX ); 00177 _paramSizeHeight -> setIsSecretAndDisabled( ! keepRatio || orientation != eParamSizeOrientationY ); 00178 } 00179 else if( paramName == kParamSizeWidth && args.reason == OFX::eChangeUserEdit ) 00180 { 00181 _paramMode -> setValue( eParamModeSize ); 00182 _paramSizeKeepRatio -> setValue( true ); 00183 _paramSizeOrientation -> setValue( eParamSizeOrientationX ); 00184 00185 _paramSize -> setValue( _paramSizeWidth->getValue(), _paramSize->getValue().y ); 00186 } 00187 else if( paramName == kParamSizeHeight && args.reason == OFX::eChangeUserEdit ) 00188 { 00189 _paramMode -> setValue( eParamModeSize ); 00190 _paramSizeKeepRatio -> setValue( true ); 00191 _paramSizeOrientation -> setValue( eParamSizeOrientationY ); 00192 00193 _paramSize -> setValue( _paramSize->getValue().x, _paramSizeHeight->getValue() ); 00194 } 00195 else if( paramName == kParamScale && args.reason == OFX::eChangeUserEdit ) 00196 { 00197 _paramMode->setValue( eParamModeScale ); 00198 } 00199 } 00200 00201 bool SwscalePlugin::getRegionOfDefinition( const OFX::RegionOfDefinitionArguments& args, OfxRectD& rod ) 00202 { 00203 using namespace boost::gil; 00204 00205 const OfxRectD srcRod = _clipSrc->getCanonicalRod( args.time ); 00206 const Point2 srcRodSize( srcRod.x2 - srcRod.x1, srcRod.y2 - srcRod.y1 ); 00207 00208 switch( _paramMode->getValue() ) 00209 { 00210 case eParamModeFormat : 00211 { 00212 std::size_t width = 0; 00213 std::size_t height = 0; 00214 getFormatResolution( static_cast<EParamFormat>(_paramFormat->getValue()), width, height ); 00215 rod.x1 = 0; 00216 rod.y1 = 0; 00217 rod.x2 = width; 00218 rod.y2 = height; 00219 00220 return true; 00221 } 00222 case eParamModeSize : 00223 { 00224 std::size_t sizex = 0; 00225 std::size_t sizey = 0; 00226 if( _paramSizeKeepRatio->getValue() ) 00227 { 00228 if( _paramSizeOrientation->getValue() == eParamSizeOrientationX ) 00229 { 00230 sizex = _paramSizeWidth->getValue(); 00231 sizey = srcRodSize.y / numeric_cast<double>(srcRodSize.x) * sizex; 00232 } 00233 else // direction == eParamSizeY 00234 { 00235 sizey = _paramSizeHeight->getValue(); 00236 sizex = srcRodSize.x / numeric_cast<double>(srcRodSize.y) * sizey; 00237 } 00238 } 00239 else 00240 { 00241 const OfxPointI s = _paramSize->getValue(); 00242 sizex = s.x; 00243 sizey = s.y; 00244 } 00245 00246 rod.x1 = 0; 00247 rod.y1 = 0; 00248 rod.x2 = sizex; 00249 rod.y2 = sizey; 00250 00251 return true; 00252 } 00253 case eParamModeScale : 00254 { 00255 const Point2 scale = ofxToGil( _paramScale->getValue() ); 00256 if( scale.x == 0.0 || scale.y == 0.0 ) 00257 return false; 00258 00259 const Point2 dstSize( srcRodSize * scale ); 00260 rod.x1 = 0; 00261 rod.y1 = 0; 00262 rod.x2 = dstSize.x; 00263 rod.y2 = dstSize.y; 00264 return true; 00265 } 00266 } 00267 00268 return false; 00269 } 00270 00271 //void SwscalePlugin::getRegionsOfInterest( const OFX::RegionsOfInterestArguments& args, OFX::RegionOfInterestSetter& rois ) 00272 //{ 00273 // // TODO: to enable tiles... 00274 //} 00275 00276 bool SwscalePlugin::isIdentity() const 00277 { 00278 switch( _paramMode->getValue() ) 00279 { 00280 case eParamModeFormat : 00281 { 00282 ///@todo could we read the input rod at this step? 00283 return false; 00284 } 00285 case eParamModeSize : 00286 { 00287 ///@todo could we read the input rod at this step? 00288 return false; 00289 } 00290 case eParamModeScale : 00291 { 00292 const Point2 scale = ofxToGil( _paramScale->getValue() ); 00293 if( scale.x == 1.0 && scale.y == 1.0 ) 00294 return true; 00295 return false; 00296 } 00297 } 00298 return false; 00299 } 00300 00301 bool SwscalePlugin::isIdentity( const OFX::RenderArguments& args, OFX::Clip*& identityClip, double& identityTime ) 00302 { 00303 if( isIdentity() ) 00304 { 00305 identityClip = _clipSrc; 00306 identityTime = args.time; 00307 return true; 00308 } 00309 return false; 00310 } 00311 00312 /** 00313 * @brief The overridden render function 00314 * @param[in] args Rendering parameters 00315 */ 00316 void SwscalePlugin::render( const OFX::RenderArguments &args ) 00317 { 00318 OFX::ImageEffectHostDescription* desc = OFX::getImageEffectHostDescription(); 00319 00320 if( desc->_supportedPixelDepths.size() == 1 && OFX::eBitDepthFloat == desc->_supportedPixelDepths.at(0) ) 00321 { 00322 BOOST_THROW_EXCEPTION( exception::BitDepthMismatch() 00323 << exception::user( "SwScale: unsupported plugin on this host." ) ); 00324 } 00325 00326 SwscaleProcess procObj( *this ); 00327 procObj.setupAndProcess( args ); 00328 } 00329 00330 00331 } 00332 } 00333 }