TuttleOFX
1
|
00001 #include "SwscaleProcess.hpp" 00002 00003 namespace tuttle { 00004 namespace plugin { 00005 namespace swscale { 00006 00007 SwscaleProcess::SwscaleProcess( SwscalePlugin &effect ) 00008 : ImageFilterProcessor( effect, eImageOrientationFromTopToBottom ) 00009 , _plugin( effect ) 00010 , _context( NULL ) 00011 { 00012 this->setNoMultiThreading(); 00013 } 00014 00015 00016 void SwscaleProcess::setup( const OFX::RenderArguments& args ) 00017 { 00018 ImageFilterProcessor::setup( args ); 00019 _params = _plugin.getProcessParams( args.renderScale ); 00020 } 00021 00022 PixelFormat ofxPixelComponentToSwsPixelFormat( const OFX::EPixelComponent component, const OFX::EBitDepth bitDepth ) 00023 { 00024 switch( component ) 00025 { 00026 case OFX::ePixelComponentRGBA: 00027 switch( bitDepth ) 00028 { 00029 case OFX::eBitDepthCustom: 00030 case OFX::eBitDepthNone: 00031 BOOST_THROW_EXCEPTION( exception::BitDepthMismatch() 00032 << exception::user( "Dpx: Unkown bit depth" ) ); 00033 break; 00034 case OFX::eBitDepthUByte: return PIX_FMT_RGBA; 00035 case OFX::eBitDepthUShort: return PIX_FMT_NONE; 00036 case OFX::eBitDepthFloat: return PIX_FMT_NONE; 00037 } 00038 break; 00039 case OFX::ePixelComponentRGB: 00040 switch( bitDepth ) 00041 { 00042 case OFX::eBitDepthCustom: 00043 case OFX::eBitDepthNone: 00044 BOOST_THROW_EXCEPTION( exception::BitDepthMismatch() 00045 << exception::user( "Dpx: Unkown bit depth" ) ); 00046 break; 00047 case OFX::eBitDepthUByte: return PIX_FMT_RGB24; 00048 case OFX::eBitDepthUShort: return PIX_FMT_RGB48; 00049 case OFX::eBitDepthFloat: return PIX_FMT_NONE; 00050 } 00051 break; 00052 case OFX::ePixelComponentAlpha: 00053 switch( bitDepth ) 00054 { 00055 case OFX::eBitDepthCustom: 00056 case OFX::eBitDepthNone: 00057 BOOST_THROW_EXCEPTION( exception::BitDepthMismatch() 00058 << exception::user( "Dpx: Unkown bit depth" ) ); 00059 break; 00060 case OFX::eBitDepthUByte: return PIX_FMT_GRAY8; 00061 case OFX::eBitDepthUShort: return PIX_FMT_GRAY16; 00062 case OFX::eBitDepthFloat: return PIX_FMT_NONE; 00063 } 00064 break; 00065 case OFX::ePixelComponentNone: 00066 case OFX::ePixelComponentCustom: 00067 return PIX_FMT_NONE; 00068 } 00069 BOOST_ASSERT( false ); 00070 return PIX_FMT_NONE; 00071 } 00072 00073 /** 00074 * @brief Function called by rendering thread each time a process must be done. 00075 * @param[in] procWindowRoW Processing window 00076 */ 00077 void SwscaleProcess::multiThreadProcessImages( const OfxRectI& procWindow ) 00078 { 00079 OFX::EPixelComponent component = this->_src->getPixelComponents(); 00080 OFX::EBitDepth bitDepth = this->_src->getPixelDepth(); 00081 PixelFormat pixFmt = ofxPixelComponentToSwsPixelFormat( component, bitDepth ); 00082 00083 if( pixFmt == PIX_FMT_NONE ) 00084 { 00085 BOOST_THROW_EXCEPTION( exception::BitDepthMismatch() 00086 << exception::user( "SwScale: unsupported bit depth / channel input." ) ); 00087 } 00088 00089 _context = sws_getCachedContext( _context, 00090 this->_src->getBoundsSize().x, this->_src->getBoundsSize().y, 00091 pixFmt, 00092 this->_dst->getBoundsSize().x, this->_dst->getBoundsSize().y, 00093 pixFmt, 00094 _params._sws_filter, 00095 NULL, NULL, NULL ); 00096 if ( !_context ) 00097 { 00098 BOOST_THROW_EXCEPTION( exception::Failed() 00099 << exception::user( "swscale: Could not get swscale context." ) ); 00100 } 00101 00102 // set filtering mode 00103 // @todo: sws set filtermode( _params._sws_filter ) 00104 00105 // for tile support... (currently disabled) 00106 // void* srcPtr = this->_src->getPixelAddress( procWindow.x1, procWindow.y1 ); 00107 // void* dstPtr = this->_dst->getPixelAddress( procWindow.x1, procWindow.y1 ); 00108 00109 // for simple buffer access 00110 uint8_t* srcPtr = (uint8_t*)this->_src->getPixelData(); 00111 uint8_t* dstPtr = (uint8_t*)this->_dst->getPixelData(); 00112 if ( !srcPtr || !dstPtr ) 00113 { 00114 BOOST_THROW_EXCEPTION( exception::Failed() 00115 << exception::user( "swscale: Pixel data pointer invalid." ) ); 00116 } 00117 00118 // "this->_src->getRowDistanceBytes()" is not the same than "this->_src->getBoundsSize().x * pixelBytes" 00119 // The buffer could contain a padding between lines. 00120 00121 int srcStride = this->_src->getRowDistanceBytes(); 00122 int dstStride = this->_dst->getRowDistanceBytes(); 00123 int ret = sws_scale( _context, &srcPtr, &srcStride, 0, 00124 this->_src->getBoundsSize().y, &dstPtr, &dstStride ); 00125 if ( ret < 0 ) 00126 BOOST_THROW_EXCEPTION( exception::Failed() 00127 << exception::user( "swscale: Scaling failed." ) 00128 << exception::dev( ret ) ); 00129 } 00130 00131 void SwscaleProcess::postProcess() 00132 { 00133 sws_freeContext( _context ); 00134 } 00135 00136 00137 } 00138 } 00139 }