diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-01-26 13:42:55 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2016-01-26 13:44:43 +0300 |
commit | c8d2ebe13c1a93a7390df60607525c47614b4984 (patch) | |
tree | f6c5f8403db37778e4905d4f865070cec187089e /source/blender/compositor/operations | |
parent | f1f42c6172c7e656f42cb4895c0badf10f33a1ad (diff) |
Compositor: Speedup movie (un)distortion operation
Avoid per-pixel camera intrincs object construction and synchronization.
Here on a bit synthetic file it gives about 40% speedup with a single node.
Diffstat (limited to 'source/blender/compositor/operations')
-rw-r--r-- | source/blender/compositor/operations/COM_MovieDistortionOperation.cpp | 114 | ||||
-rw-r--r-- | source/blender/compositor/operations/COM_MovieDistortionOperation.h | 137 |
2 files changed, 71 insertions, 180 deletions
diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp index 4f34d7fb150..3b8f09fffb2 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.cpp @@ -15,9 +15,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand + * Sergey Sharybin */ #include "COM_MovieDistortionOperation.h" @@ -29,17 +30,6 @@ extern "C" { } -static vector<DistortionCache *> s_cache; - -void deintializeDistortionCache(void) -{ - while (s_cache.size() > 0) { - DistortionCache * cache = s_cache.back(); - s_cache.pop_back(); - delete cache; - } -} - MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperation() { this->addInputSocket(COM_DT_COLOR); @@ -47,40 +37,32 @@ MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperat this->setResolutionInputSocketIndex(0); this->m_inputOperation = NULL; this->m_movieClip = NULL; - this->m_cache = NULL; - this->m_distortion = distortion; + this->m_apply = distortion; } void MovieDistortionOperation::initExecution() { this->m_inputOperation = this->getInputSocketReader(0); if (this->m_movieClip) { + MovieTracking *tracking = &this->m_movieClip->tracking; MovieClipUser clipUser = {0}; int calibration_width, calibration_height; BKE_movieclip_user_set_frame(&clipUser, this->m_framenumber); - BKE_movieclip_get_size(this->m_movieClip, &clipUser, &calibration_width, &calibration_height); - - for (unsigned int i = 0; i < s_cache.size(); i++) { - DistortionCache *c = (DistortionCache *)s_cache[i]; - if (c->isCacheFor(this->m_movieClip, this->m_width, this->m_height, - calibration_width, calibration_height, this->m_distortion)) - { - this->m_cache = c; - this->m_cache->updateLastUsage(); - this->m_cache->getMargin(this->m_margin); - return; - } - } + BKE_movieclip_get_size(this->m_movieClip, + &clipUser, + &calibration_width, + &calibration_height); float delta[2]; rcti full_frame; full_frame.xmin = full_frame.ymin = 0; full_frame.xmax = this->m_width; full_frame.ymax = this->m_height; - BKE_tracking_max_distortion_delta_across_bound( - &this->m_movieClip->tracking, &full_frame, - !this->m_distortion, delta); + BKE_tracking_max_distortion_delta_across_bound(tracking, + &full_frame, + !this->m_apply, + delta); /* 5 is just in case we didn't hit real max of distortion in * BKE_tracking_max_undistortion_delta_across_bound @@ -88,17 +70,16 @@ void MovieDistortionOperation::initExecution() m_margin[0] = delta[0] + 5; m_margin[1] = delta[1] + 5; - DistortionCache *newC = new DistortionCache(this->m_movieClip, - this->m_width, this->m_height, - calibration_width, calibration_height, - this->m_distortion, - this->m_margin); - s_cache.push_back(newC); - this->m_cache = newC; + this->m_distortion = BKE_tracking_distortion_new(tracking, + calibration_width, + calibration_height); + this->m_calibration_width = calibration_width; + this->m_calibration_height = calibration_height; + this->m_pixel_aspect = tracking->camera.pixel_aspect; } else { - this->m_cache = NULL; m_margin[0] = m_margin[1] = 0; + this->m_distortion = NULL; } } @@ -106,27 +87,39 @@ void MovieDistortionOperation::deinitExecution() { this->m_inputOperation = NULL; this->m_movieClip = NULL; - while (s_cache.size() > COM_DISTORTIONCACHE_MAXSIZE) { - double minTime = PIL_check_seconds_timer(); - vector<DistortionCache*>::iterator minTimeIterator = s_cache.begin(); - for (vector<DistortionCache*>::iterator it = s_cache.begin(); it < s_cache.end(); it ++) { - DistortionCache * cache = *it; - if (cache->getTimeLastUsage() < minTime) { - minTime = cache->getTimeLastUsage(); - minTimeIterator = it; - } - } - s_cache.erase(minTimeIterator); + if (this->m_distortion != NULL) { + BKE_tracking_distortion_free(this->m_distortion); } } - -void MovieDistortionOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/) +void MovieDistortionOperation::executePixelSampled(float output[4], + float x, + float y, + PixelSampler /*sampler*/) { - - if (this->m_cache != NULL) { - float u, v; - this->m_cache->getUV(&this->m_movieClip->tracking, x, y, &u, &v); + if (this->m_distortion != NULL) { + /* float overscan = 0.0f; */ + const float pixel_aspect = this->m_pixel_aspect; + const float w = (float)this->m_width /* / (1 + overscan) */; + const float h = (float)this->m_height /* / (1 + overscan) */; + const float aspx = w / (float)this->m_calibration_width; + const float aspy = h / (float)this->m_calibration_height; + float in[2]; + float out[2]; + + in[0] = (x /* - 0.5 * overscan * w */) / aspx; + in[1] = (y /* - 0.5 * overscan * h */) / aspy / pixel_aspect; + + if (this->m_apply) { + BKE_tracking_distortion_undistort_v2(this->m_distortion, in, out); + } + else { + BKE_tracking_distortion_distort_v2(this->m_distortion, in, out); + } + + float u = out[0] * aspx /* + 0.5 * overscan * w */, + v = (out[1] * aspy /* + 0.5 * overscan * h */) * pixel_aspect; + this->m_inputOperation->readSampled(output, u, v, COM_PS_BILINEAR); } else { @@ -134,12 +127,17 @@ void MovieDistortionOperation::executePixelSampled(float output[4], float x, flo } } -bool MovieDistortionOperation::determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output) +bool MovieDistortionOperation::determineDependingAreaOfInterest( + rcti *input, + ReadBufferOperation *readOperation, + rcti *output) { rcti newInput; newInput.xmin = input->xmin - m_margin[0]; newInput.ymin = input->ymin - m_margin[1]; newInput.xmax = input->xmax + m_margin[0]; newInput.ymax = input->ymax + m_margin[1]; - return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output); + return NodeOperation::determineDependingAreaOfInterest(&newInput, + readOperation, + output); } diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index 38b1dbfa856..689fcfe11ad 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -15,9 +15,10 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * Contributor: - * Jeroen Bakker + * Contributor: + * Jeroen Bakker * Monique Dewanchand + * Sergey Sharybin */ #ifndef _COM_MovieDistortionOperation_h_ @@ -29,145 +30,37 @@ extern "C" { # include "BKE_tracking.h" -# include "PIL_time.h" } -#define COM_DISTORTIONCACHE_MAXSIZE 10 - -class DistortionCache { -private: - short m_distortion_model; - float m_k1, m_k2, m_k3; - float m_division_k1, m_division_k2; - float m_principal_x; - float m_principal_y; - float m_pixel_aspect; - int m_width; - int m_height; - int m_calibration_width; - int m_calibration_height; - bool m_inverted; - double timeLastUsage; - int m_margin[2]; - -public: - DistortionCache(MovieClip *movieclip, - int width, int height, - int calibration_width, int calibration_height, - bool inverted, - const int margin[2]) - { - this->m_distortion_model = movieclip->tracking.camera.distortion_model; - this->m_k1 = movieclip->tracking.camera.k1; - this->m_k2 = movieclip->tracking.camera.k2; - this->m_k3 = movieclip->tracking.camera.k3; - this->m_division_k1 = movieclip->tracking.camera.division_k1; - this->m_division_k2 = movieclip->tracking.camera.division_k2; - this->m_principal_x = movieclip->tracking.camera.principal[0]; - this->m_principal_y = movieclip->tracking.camera.principal[1]; - this->m_pixel_aspect = movieclip->tracking.camera.pixel_aspect; - this->m_width = width; - this->m_height = height; - this->m_calibration_width = calibration_width; - this->m_calibration_height = calibration_height; - this->m_inverted = inverted; - copy_v2_v2_int(this->m_margin, margin); - this->updateLastUsage(); - } - - void updateLastUsage() { - this->timeLastUsage = PIL_check_seconds_timer(); - } - - inline double getTimeLastUsage() { - return this->timeLastUsage; - } - - bool isCacheFor(MovieClip *movieclip, - int width, int height, - int calibration_width, int claibration_height, - bool inverted) - { - return this->m_distortion_model == movieclip->tracking.camera.distortion_model && - this->m_k1 == movieclip->tracking.camera.k1 && - this->m_k2 == movieclip->tracking.camera.k2 && - this->m_k3 == movieclip->tracking.camera.k3 && - this->m_division_k1 == movieclip->tracking.camera.division_k1 && - this->m_division_k2 == movieclip->tracking.camera.division_k2 && - this->m_principal_x == movieclip->tracking.camera.principal[0] && - this->m_principal_y == movieclip->tracking.camera.principal[1] && - this->m_pixel_aspect == movieclip->tracking.camera.pixel_aspect && - this->m_inverted == inverted && - this->m_width == width && - this->m_height == height && - this->m_calibration_width == calibration_width && - this->m_calibration_height == claibration_height; - } - - void getUV(MovieTracking *trackingData, - float x, - float y, - float *r_u, - float *r_v) - { - if (x < 0 || x >= this->m_width || y < 0 || y >= this->m_height) { - *r_u = x; - *r_v = y; - } - else { - /* float overscan = 0.0f; */ - const float w = (float)this->m_width /* / (1 + overscan) */; - const float h = (float)this->m_height /* / (1 + overscan) */; - const float aspx = w / (float)this->m_calibration_width; - const float aspy = h / (float)this->m_calibration_height; - float in[2]; - float out[2]; - - in[0] = (x /* - 0.5 * overscan * w */) / aspx; - in[1] = (y /* - 0.5 * overscan * h */) / aspy / this->m_pixel_aspect; - - if (this->m_inverted) { - BKE_tracking_undistort_v2(trackingData, in, out); - } - else { - BKE_tracking_distort_v2(trackingData, in, out); - } - - *r_u = out[0] * aspx /* + 0.5 * overscan * w */; - *r_v = (out[1] * aspy /* + 0.5 * overscan * h */) * this->m_pixel_aspect; - } - } - - void getMargin(int margin[2]) - { - copy_v2_v2_int(margin, m_margin); - } -}; - class MovieDistortionOperation : public NodeOperation { private: - DistortionCache *m_cache; SocketReader *m_inputOperation; MovieClip *m_movieClip; int m_margin[2]; protected: - bool m_distortion; + bool m_apply; int m_framenumber; + struct MovieDistortion *m_distortion; + int m_calibration_width, m_calibration_height; + float m_pixel_aspect; + public: MovieDistortionOperation(bool distortion); - void executePixelSampled(float output[4], float x, float y, PixelSampler sampler); + void executePixelSampled(float output[4], + float x, float y, + PixelSampler sampler); void initExecution(); void deinitExecution(); - + void setMovieClip(MovieClip *clip) { this->m_movieClip = clip; } void setFramenumber(int framenumber) { this->m_framenumber = framenumber; } - bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output); + bool determineDependingAreaOfInterest(rcti *input, + ReadBufferOperation *readOperation, + rcti *output); }; -void deintializeDistortionCache(void); - #endif |