TuttleOFX  1
SwscaleProcess.cpp
Go to the documentation of this file.
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 }