diff --git a/src/filters/new_interframe.cpp b/src/filters/new_interframe.cpp index 2f09309b..428447cb 100644 --- a/src/filters/new_interframe.cpp +++ b/src/filters/new_interframe.cpp @@ -32,23 +32,16 @@ SmartIB::~SmartIB() frm1 = frm2 = frm3 = NULL; } -void SmartIB::run(u32 *srcPtr, unsigned int num_threads,unsigned int thread_number) +void SmartIB::run(u32 *srcPtr) { - //Actual width needs to take into account the +1 border - unsigned int width = getWidth() +1; - //Height to process (for multithreading) - unsigned int band_height = getHeight() / num_threads; - //First pixel to operate on (for multithreading) - u32 offset = band_height * thread_number * width; - - u32 *src0 = srcPtr + offset; - u32 *src1 = frm1 + offset; - u32 *src2 = frm2 + offset; - u32 *src3 = frm3 + offset; + u32 *src0 = srcPtr; + u32 *src1 = frm1; + u32 *src2 = frm2; + u32 *src3 = frm3; u32 colorMask = 0xfefefe; - for (unsigned int i = 0; i < width*band_height; i++) + for (unsigned int i = 0; i < getWidth()*getHeight(); i++) { u32 color = src0[i]; src0[i] = @@ -81,21 +74,14 @@ MotionBlurIB::~MotionBlurIB() frm1=NULL; } -void MotionBlurIB::run(u32 *srcPtr, unsigned int num_threads,unsigned int thread_number) +void MotionBlurIB::run(u32 *srcPtr) { - //Actual width needs to take into account the +1 border - unsigned int width = getWidth() +1; - //Height to process (for multithreading) - unsigned int band_height = getHeight() / num_threads; - //First pixel to operate on (for multithreading) - u32 offset = band_height * thread_number * width; - - u32 *src0 = srcPtr + offset; - u32 *src1 = frm1 + offset; + u32 *src0 = srcPtr; + u32 *src1 = frm1; u32 colorMask = 0xfefefe; - for (unsigned int i = 0; i < width*band_height; i++) + for (unsigned int i = 0; i < getWidth()*getHeight(); i++) { u32 color = src0[i]; src0[i] = (((color & colorMask) >> 1) + diff --git a/src/filters/new_interframe.hpp b/src/filters/new_interframe.hpp index 6dffb2b0..4bcb9175 100644 --- a/src/filters/new_interframe.hpp +++ b/src/filters/new_interframe.hpp @@ -29,7 +29,7 @@ public: unsigned int getWidth() {return width;} unsigned int getHeight() {return height;} ///New smarter Interframe function - virtual void run(u32 *srcPtr, unsigned int num_threads=1,unsigned int thread_number=0) {} + virtual void run(u32 *srcPtr) {} virtual bool exists() {return false;} }; @@ -49,7 +49,7 @@ public: SmartIB(unsigned int _width,unsigned int _height); ~SmartIB(); std::string getName() {return "SmartIB";} - void run(u32 *srcPtr, unsigned int num_threads=1,unsigned int thread_number=0); + void run(u32 *srcPtr); bool exists() {return true;} }; @@ -63,7 +63,7 @@ public: MotionBlurIB(unsigned int _width,unsigned int _height); ~MotionBlurIB(); std::string getName() {return "MotionBlurIB";} - void run(u32 *srcPtr, unsigned int num_threads=1,unsigned int thread_number=0); + void run(u32 *srcPtr); bool exists() {return true;} }; @@ -79,7 +79,8 @@ class interframe_factory public: static interframe_filter * createIFB(ifbfunc filter_select,unsigned int width,unsigned int height) { - switch(filter_select) { + switch(filter_select) + { case IFB_SMART: return new SmartIB(width,height); break; @@ -91,6 +92,19 @@ public: break; } } + static bool exists(ifbfunc filter_select) + { + switch(filter_select) + { + case IFB_SMART: + case IFB_MOTION_BLUR: + return true; + break; + default: + return false; + break; + } + } }; #endif //NEW_INTERFRAME_HPP diff --git a/src/wx/panel.cpp b/src/wx/panel.cpp index 32091a62..442f7f48 100644 --- a/src/wx/panel.cpp +++ b/src/wx/panel.cpp @@ -1007,6 +1007,16 @@ class FilterThread : public wxThread public: FilterThread() : wxThread(wxTHREAD_JOINABLE), lock(), sig(lock) {} + //Cleanup on exit + ~FilterThread() + { + if(iFilter) + { + delete iFilter; + iFilter = NULL; + } + } + wxMutex lock; wxCondition sig; wxSemaphore *done; @@ -1024,16 +1034,14 @@ public: ExitCode Entry() { - //The filter is run with each thread handling bands of data - //This is how tall each of those bands are - unsigned int band_height = height/nthreads; // This is the lower height value of the band this thread will process - int band_lower = band_height * threadno; + int band_lower = height * threadno; //Set the starting location for the destination buffer dst += width * scale * band_lower * scale; while(sig.Wait() == wxCOND_NO_ERROR) { + //If no source, do thread cleanup before exiting if(!src ) { lock.Unlock(); return (wxThread::ExitCode) 0; @@ -1045,15 +1053,15 @@ public: return (wxThread::ExitCode) -1; } - //Run the interframe blending filter - iFilter->run(src, nthreads, threadno); + //Set the start of the source pointer to the first pixel of the appropriate height + src += width * band_lower; - //Set the start of the source pointer to the first pixel of the appropriate height - src += width * band_lower; + //Run the interframe blending filter + iFilter->run(src); // naturally, any of these with accumulation buffers like those of // the IFB filters will screw up royally as well - mainFilter->run(src, dst, band_height); + mainFilter->run(src, dst, height); done->Post(); } @@ -1070,11 +1078,11 @@ DrawingPanel::DrawingPanel(int _width, int _height) : myFilter = new filter(std::string(gopts.filter.mb_str(wxConvUTF8))); - iFilter = interframe_factory::createIFB((ifbfunc)gopts.ifb,width,height); - scale = myFilter->getScale(); myFilter->setWidth(width); + isFiltered = interframe_factory::exists((ifbfunc)gopts.ifb) || myFilter->exists(); + //Do a quick run to initialize the filter //\TODO: Fix the filters so this is no longer needed myFilter->run(reinterpret_cast(&todraw), reinterpret_cast(&todraw), height); @@ -1082,16 +1090,20 @@ DrawingPanel::DrawingPanel(int _width, int _height) : // Create and start up new threads nthreads = gopts.max_threads; if(nthreads) { + //The filter is run with each thread handling bands of data + //This is how tall each of those bands are + unsigned int band_height = height/nthreads; + //Create and initialize the threads threads = new FilterThread[nthreads]; for(int i = 0; i < nthreads; i++) { threads[i].threadno = i; threads[i].nthreads = nthreads; threads[i].width = width; - threads[i].height = height; + threads[i].height = band_height; threads[i].scale = scale; threads[i].dst = reinterpret_cast(&todraw); threads[i].mainFilter=myFilter; - threads[i].iFilter=iFilter; + threads[i].iFilter=interframe_factory::createIFB((ifbfunc)gopts.ifb,width,band_height); threads[i].done = &filt_done; threads[i].lock.Lock(); threads[i].Create(); @@ -1188,12 +1200,6 @@ DrawingPanel::~DrawingPanel() delete myFilter; myFilter = NULL; } - //Interframe Filter cleanup - if(iFilter) - { - delete iFilter; - iFilter = NULL; - } } IMPLEMENT_CLASS2(BasicDrawingPanel, DrawingPanel, wxPanel) @@ -1207,7 +1213,7 @@ BasicDrawingPanel::BasicDrawingPanel(wxWindow *parent, int _width, int _height) wxFULL_REPAINT_ON_RESIZE), DrawingPanel(_width, _height) { // wxImage is 24-bit RGB, so 24-bit is preferred. Filters require 32, though - if(!myFilter->exists() && !iFilter->exists()) + if(!isFiltered) { // changing from 32 to 24 does not require regenerating color tables systemColorDepth = 24; diff --git a/src/wx/wxvbam.h b/src/wx/wxvbam.h index dc2f529e..ab868e75 100644 --- a/src/wx/wxvbam.h +++ b/src/wx/wxvbam.h @@ -485,11 +485,12 @@ public: protected: virtual void DrawArea(wxWindowDC&) = 0; filter * myFilter; - interframe_filter * iFilter; int width, height, scale; // largest buffer required is 32-bit * (max width + 1) * (max height + 2) * (4x4) scaling factor u8 todraw[257 * 226 * 4 * 16]; FilterThread *threads; + ///Is the output going through a filter? + bool isFiltered; int nthreads; wxSemaphore filt_done; const RENDER_PLUGIN_INFO *rpi; // also flag indicating plugin loaded