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.
This commit is contained in:
@@ -264,33 +264,23 @@ void libmv_cameraIntrinsicsDistortFloat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void libmv_cameraIntrinsicsApply(
|
void libmv_cameraIntrinsicsApply(
|
||||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y,
|
||||||
double* x1,
|
double* x1,
|
||||||
double* y1) {
|
double* y1) {
|
||||||
/* Do a lens distortion if focal length is non-zero only. */
|
CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
|
||||||
if (libmv_camera_intrinsics_options->focal_length) {
|
intrinsics->ApplyIntrinsics(x, y, x1, y1);
|
||||||
CameraIntrinsics* camera_intrinsics =
|
|
||||||
libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
|
|
||||||
camera_intrinsics->ApplyIntrinsics(x, y, x1, y1);
|
|
||||||
LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void libmv_cameraIntrinsicsInvert(
|
void libmv_cameraIntrinsicsInvert(
|
||||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y,
|
||||||
double* x1,
|
double* x1,
|
||||||
double* y1) {
|
double* y1) {
|
||||||
/* Do a lens un-distortion if focal length is non-zero only/ */
|
CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
|
||||||
if (libmv_camera_intrinsics_options->focal_length) {
|
intrinsics->InvertIntrinsics(x, y, x1, y1);
|
||||||
CameraIntrinsics *camera_intrinsics =
|
|
||||||
libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
|
|
||||||
camera_intrinsics->InvertIntrinsics(x, y, x1, y1);
|
|
||||||
LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void libmv_cameraIntrinsicsFillFromOptions(
|
static void libmv_cameraIntrinsicsFillFromOptions(
|
||||||
|
@@ -108,14 +108,14 @@ void libmv_cameraIntrinsicsDistortFloat(
|
|||||||
float* destination_image);
|
float* destination_image);
|
||||||
|
|
||||||
void libmv_cameraIntrinsicsApply(
|
void libmv_cameraIntrinsicsApply(
|
||||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y,
|
||||||
double* x1,
|
double* x1,
|
||||||
double* y1);
|
double* y1);
|
||||||
|
|
||||||
void libmv_cameraIntrinsicsInvert(
|
void libmv_cameraIntrinsicsInvert(
|
||||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
const struct libmv_CameraIntrinsics* libmv_intrinsics,
|
||||||
double x,
|
double x,
|
||||||
double y,
|
double y,
|
||||||
double* x1,
|
double* x1,
|
||||||
|
@@ -303,29 +303,23 @@ void libmv_cameraIntrinsicsDistortFloat(
|
|||||||
/* ************ utils ************ */
|
/* ************ utils ************ */
|
||||||
|
|
||||||
void libmv_cameraIntrinsicsApply(
|
void libmv_cameraIntrinsicsApply(
|
||||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
const struct libmv_CameraIntrinsics* /*libmv_intrinsics*/,
|
||||||
double x,
|
double /*x*/,
|
||||||
double y,
|
double /*y*/,
|
||||||
double* x1,
|
double* x1,
|
||||||
double* y1) {
|
double* y1) {
|
||||||
double focal_length = libmv_camera_intrinsics_options->focal_length;
|
*x1 = 0.0;
|
||||||
double principal_x = libmv_camera_intrinsics_options->principal_point_x;
|
*y1 = 0.0;
|
||||||
double principal_y = libmv_camera_intrinsics_options->principal_point_y;
|
|
||||||
*x1 = x * focal_length + principal_x;
|
|
||||||
*y1 = y * focal_length + principal_y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void libmv_cameraIntrinsicsInvert(
|
void libmv_cameraIntrinsicsInvert(
|
||||||
const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
|
const struct libmv_CameraIntrinsics* /*libmv_intrinsics*/,
|
||||||
double x,
|
double /*x*/,
|
||||||
double y,
|
double /*y*/,
|
||||||
double* x1,
|
double* x1,
|
||||||
double* y1) {
|
double* y1) {
|
||||||
double focal_length = libmv_camera_intrinsics_options->focal_length;
|
*x1 = 0.0;
|
||||||
double principal_x = libmv_camera_intrinsics_options->principal_point_x;
|
*y1 = 0.0;
|
||||||
double principal_y = libmv_camera_intrinsics_options->principal_point_y;
|
|
||||||
*x1 = (x - principal_x) / focal_length;
|
|
||||||
*y1 = (y - principal_y) / focal_length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void libmv_homography2DFromCorrespondencesEuc(/* const */ double (* /*x1*/)[2],
|
void libmv_homography2DFromCorrespondencesEuc(/* const */ double (* /*x1*/)[2],
|
||||||
|
@@ -200,6 +200,12 @@ void BKE_tracking_distortion_set_threads(struct MovieDistortion *distortion, int
|
|||||||
struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion);
|
struct MovieDistortion *BKE_tracking_distortion_copy(struct MovieDistortion *distortion);
|
||||||
struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking,
|
struct ImBuf *BKE_tracking_distortion_exec(struct MovieDistortion *distortion, struct MovieTracking *tracking,
|
||||||
struct ImBuf *ibuf, int width, int height, float overscan, bool undistort);
|
struct ImBuf *ibuf, int width, int height, float overscan, bool undistort);
|
||||||
|
void BKE_tracking_distortion_distort_v2(struct MovieDistortion *distortion,
|
||||||
|
const float co[2],
|
||||||
|
float r_co[2]);
|
||||||
|
void BKE_tracking_distortion_undistort_v2(struct MovieDistortion *distortion,
|
||||||
|
const float co[2],
|
||||||
|
float r_co[2]);
|
||||||
void BKE_tracking_distortion_free(struct MovieDistortion *distortion);
|
void BKE_tracking_distortion_free(struct MovieDistortion *distortion);
|
||||||
|
|
||||||
void BKE_tracking_distort_v2(struct MovieTracking *tracking, const float co[2], float r_co[2]);
|
void BKE_tracking_distort_v2(struct MovieTracking *tracking, const float co[2], float r_co[2]);
|
||||||
|
@@ -69,6 +69,10 @@
|
|||||||
|
|
||||||
typedef struct MovieDistortion {
|
typedef struct MovieDistortion {
|
||||||
struct libmv_CameraIntrinsics *intrinsics;
|
struct libmv_CameraIntrinsics *intrinsics;
|
||||||
|
/* Parameters needed for coordinates normalization. */
|
||||||
|
float principal[2];
|
||||||
|
float pixel_aspect;
|
||||||
|
float focal;
|
||||||
} MovieDistortion;
|
} MovieDistortion;
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
@@ -1878,6 +1882,11 @@ MovieDistortion *BKE_tracking_distortion_new(MovieTracking *tracking,
|
|||||||
distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
|
distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
|
||||||
distortion->intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
|
distortion->intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
|
||||||
|
|
||||||
|
const MovieTrackingCamera *camera = &tracking->camera;
|
||||||
|
copy_v2_v2(distortion->principal, camera->principal);
|
||||||
|
distortion->pixel_aspect = camera->pixel_aspect;
|
||||||
|
distortion->focal = camera->focal;
|
||||||
|
|
||||||
return distortion;
|
return distortion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1891,6 +1900,11 @@ void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *
|
|||||||
calibration_height,
|
calibration_height,
|
||||||
&camera_intrinsics_options);
|
&camera_intrinsics_options);
|
||||||
|
|
||||||
|
const MovieTrackingCamera *camera = &tracking->camera;
|
||||||
|
copy_v2_v2(distortion->principal, camera->principal);
|
||||||
|
distortion->pixel_aspect = camera->pixel_aspect;
|
||||||
|
distortion->focal = camera->focal;
|
||||||
|
|
||||||
libmv_cameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics);
|
libmv_cameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1904,7 +1918,7 @@ MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
|
|||||||
MovieDistortion *new_distortion;
|
MovieDistortion *new_distortion;
|
||||||
|
|
||||||
new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
|
new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
|
||||||
|
*new_distortion = *distortion;
|
||||||
new_distortion->intrinsics = libmv_cameraIntrinsicsCopy(distortion->intrinsics);
|
new_distortion->intrinsics = libmv_cameraIntrinsicsCopy(distortion->intrinsics);
|
||||||
|
|
||||||
return new_distortion;
|
return new_distortion;
|
||||||
@@ -1962,6 +1976,36 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *
|
|||||||
return resibuf;
|
return resibuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BKE_tracking_distortion_distort_v2(MovieDistortion *distortion,
|
||||||
|
const float co[2],
|
||||||
|
float r_co[2])
|
||||||
|
{
|
||||||
|
const float aspy = 1.0f / distortion->pixel_aspect;
|
||||||
|
|
||||||
|
/* Normalize coords. */
|
||||||
|
float inv_focal = 1.0f / distortion->focal;
|
||||||
|
double x = (co[0] - distortion->principal[0]) * inv_focal,
|
||||||
|
y = (co[1] - distortion->principal[1] * aspy) * inv_focal;
|
||||||
|
|
||||||
|
libmv_cameraIntrinsicsApply(distortion->intrinsics, x, y, &x, &y);
|
||||||
|
|
||||||
|
/* Result is in image coords already. */
|
||||||
|
r_co[0] = x;
|
||||||
|
r_co[1] = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BKE_tracking_distortion_undistort_v2(MovieDistortion *distortion,
|
||||||
|
const float co[2],
|
||||||
|
float r_co[2])
|
||||||
|
{
|
||||||
|
double x = co[0], y = co[1];
|
||||||
|
libmv_cameraIntrinsicsInvert(distortion->intrinsics, x, y, &x, &y);
|
||||||
|
|
||||||
|
const float aspy = 1.0f / distortion->pixel_aspect;
|
||||||
|
r_co[0] = (float)x * distortion->focal + distortion->principal[0];
|
||||||
|
r_co[1] = (float)y * distortion->focal + distortion->principal[1] * aspy;
|
||||||
|
}
|
||||||
|
|
||||||
void BKE_tracking_distortion_free(MovieDistortion *distortion)
|
void BKE_tracking_distortion_free(MovieDistortion *distortion)
|
||||||
{
|
{
|
||||||
libmv_cameraIntrinsicsDestroy(distortion->intrinsics);
|
libmv_cameraIntrinsicsDestroy(distortion->intrinsics);
|
||||||
@@ -1971,40 +2015,43 @@ void BKE_tracking_distortion_free(MovieDistortion *distortion)
|
|||||||
|
|
||||||
void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
|
void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
|
||||||
{
|
{
|
||||||
MovieTrackingCamera *camera = &tracking->camera;
|
const MovieTrackingCamera *camera = &tracking->camera;
|
||||||
|
const float aspy = 1.0f / tracking->camera.pixel_aspect;
|
||||||
|
|
||||||
libmv_CameraIntrinsicsOptions camera_intrinsics_options;
|
libmv_CameraIntrinsicsOptions camera_intrinsics_options;
|
||||||
double x, y;
|
|
||||||
float aspy = 1.0f / tracking->camera.pixel_aspect;
|
|
||||||
|
|
||||||
tracking_cameraIntrinscisOptionsFromTracking(tracking,
|
tracking_cameraIntrinscisOptionsFromTracking(tracking,
|
||||||
0, 0,
|
0, 0,
|
||||||
&camera_intrinsics_options);
|
&camera_intrinsics_options);
|
||||||
|
libmv_CameraIntrinsics *intrinsics =
|
||||||
|
libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
|
||||||
|
|
||||||
/* normalize coords */
|
/* Normalize coordinates. */
|
||||||
x = (co[0] - camera->principal[0]) / camera->focal;
|
double x = (co[0] - camera->principal[0]) / camera->focal,
|
||||||
y = (co[1] - camera->principal[1] * aspy) / camera->focal;
|
y = (co[1] - camera->principal[1] * aspy) / camera->focal;
|
||||||
|
|
||||||
libmv_cameraIntrinsicsApply(&camera_intrinsics_options, x, y, &x, &y);
|
libmv_cameraIntrinsicsApply(intrinsics, x, y, &x, &y);
|
||||||
|
libmv_cameraIntrinsicsDestroy(intrinsics);
|
||||||
|
|
||||||
/* result is in image coords already */
|
/* Result is in image coords already. */
|
||||||
r_co[0] = x;
|
r_co[0] = x;
|
||||||
r_co[1] = y;
|
r_co[1] = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
|
void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
|
||||||
{
|
{
|
||||||
MovieTrackingCamera *camera = &tracking->camera;
|
const MovieTrackingCamera *camera = &tracking->camera;
|
||||||
|
const float aspy = 1.0f / tracking->camera.pixel_aspect;
|
||||||
|
|
||||||
libmv_CameraIntrinsicsOptions camera_intrinsics_options;
|
libmv_CameraIntrinsicsOptions camera_intrinsics_options;
|
||||||
double x = co[0], y = co[1];
|
|
||||||
float aspy = 1.0f / tracking->camera.pixel_aspect;
|
|
||||||
|
|
||||||
tracking_cameraIntrinscisOptionsFromTracking(tracking,
|
tracking_cameraIntrinscisOptionsFromTracking(tracking,
|
||||||
0, 0,
|
0, 0,
|
||||||
&camera_intrinsics_options);
|
&camera_intrinsics_options);
|
||||||
|
libmv_CameraIntrinsics *intrinsics =
|
||||||
|
libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
|
||||||
|
|
||||||
libmv_cameraIntrinsicsInvert(&camera_intrinsics_options, x, y, &x, &y);
|
double x = co[0], y = co[1];
|
||||||
|
libmv_cameraIntrinsicsInvert(intrinsics, x, y, &x, &y);
|
||||||
|
libmv_cameraIntrinsicsDestroy(intrinsics);
|
||||||
|
|
||||||
r_co[0] = (float)x * camera->focal + camera->principal[0];
|
r_co[0] = (float)x * camera->focal + camera->principal[0];
|
||||||
r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy;
|
r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy;
|
||||||
|
@@ -39,11 +39,6 @@ extern "C" {
|
|||||||
static ThreadMutex s_compositorMutex;
|
static ThreadMutex s_compositorMutex;
|
||||||
static bool is_compositorMutex_init = false;
|
static bool is_compositorMutex_init = false;
|
||||||
|
|
||||||
static void intern_freeCompositorCaches()
|
|
||||||
{
|
|
||||||
deintializeDistortionCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rendering,
|
void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rendering,
|
||||||
const ColorManagedViewSettings *viewSettings,
|
const ColorManagedViewSettings *viewSettings,
|
||||||
const ColorManagedDisplaySettings *displaySettings,
|
const ColorManagedDisplaySettings *displaySettings,
|
||||||
@@ -104,20 +99,10 @@ void COM_execute(RenderData *rd, Scene *scene, bNodeTree *editingtree, int rende
|
|||||||
BLI_mutex_unlock(&s_compositorMutex);
|
BLI_mutex_unlock(&s_compositorMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void UNUSED_FUNCTION(COM_freeCaches)()
|
|
||||||
{
|
|
||||||
if (is_compositorMutex_init) {
|
|
||||||
BLI_mutex_lock(&s_compositorMutex);
|
|
||||||
intern_freeCompositorCaches();
|
|
||||||
BLI_mutex_unlock(&s_compositorMutex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void COM_deinitialize()
|
void COM_deinitialize()
|
||||||
{
|
{
|
||||||
if (is_compositorMutex_init) {
|
if (is_compositorMutex_init) {
|
||||||
BLI_mutex_lock(&s_compositorMutex);
|
BLI_mutex_lock(&s_compositorMutex);
|
||||||
intern_freeCompositorCaches();
|
|
||||||
WorkScheduler::deinitialize();
|
WorkScheduler::deinitialize();
|
||||||
is_compositorMutex_init = false;
|
is_compositorMutex_init = false;
|
||||||
BLI_mutex_unlock(&s_compositorMutex);
|
BLI_mutex_unlock(&s_compositorMutex);
|
||||||
|
@@ -15,9 +15,10 @@
|
|||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* Contributor:
|
* Contributor:
|
||||||
* Jeroen Bakker
|
* Jeroen Bakker
|
||||||
* Monique Dewanchand
|
* Monique Dewanchand
|
||||||
|
* Sergey Sharybin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "COM_MovieDistortionOperation.h"
|
#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()
|
MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperation()
|
||||||
{
|
{
|
||||||
this->addInputSocket(COM_DT_COLOR);
|
this->addInputSocket(COM_DT_COLOR);
|
||||||
@@ -47,40 +37,32 @@ MovieDistortionOperation::MovieDistortionOperation(bool distortion) : NodeOperat
|
|||||||
this->setResolutionInputSocketIndex(0);
|
this->setResolutionInputSocketIndex(0);
|
||||||
this->m_inputOperation = NULL;
|
this->m_inputOperation = NULL;
|
||||||
this->m_movieClip = NULL;
|
this->m_movieClip = NULL;
|
||||||
this->m_cache = NULL;
|
this->m_apply = distortion;
|
||||||
this->m_distortion = distortion;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MovieDistortionOperation::initExecution()
|
void MovieDistortionOperation::initExecution()
|
||||||
{
|
{
|
||||||
this->m_inputOperation = this->getInputSocketReader(0);
|
this->m_inputOperation = this->getInputSocketReader(0);
|
||||||
if (this->m_movieClip) {
|
if (this->m_movieClip) {
|
||||||
|
MovieTracking *tracking = &this->m_movieClip->tracking;
|
||||||
MovieClipUser clipUser = {0};
|
MovieClipUser clipUser = {0};
|
||||||
int calibration_width, calibration_height;
|
int calibration_width, calibration_height;
|
||||||
|
|
||||||
BKE_movieclip_user_set_frame(&clipUser, this->m_framenumber);
|
BKE_movieclip_user_set_frame(&clipUser, this->m_framenumber);
|
||||||
BKE_movieclip_get_size(this->m_movieClip, &clipUser, &calibration_width, &calibration_height);
|
BKE_movieclip_get_size(this->m_movieClip,
|
||||||
|
&clipUser,
|
||||||
for (unsigned int i = 0; i < s_cache.size(); i++) {
|
&calibration_width,
|
||||||
DistortionCache *c = (DistortionCache *)s_cache[i];
|
&calibration_height);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
float delta[2];
|
float delta[2];
|
||||||
rcti full_frame;
|
rcti full_frame;
|
||||||
full_frame.xmin = full_frame.ymin = 0;
|
full_frame.xmin = full_frame.ymin = 0;
|
||||||
full_frame.xmax = this->m_width;
|
full_frame.xmax = this->m_width;
|
||||||
full_frame.ymax = this->m_height;
|
full_frame.ymax = this->m_height;
|
||||||
BKE_tracking_max_distortion_delta_across_bound(
|
BKE_tracking_max_distortion_delta_across_bound(tracking,
|
||||||
&this->m_movieClip->tracking, &full_frame,
|
&full_frame,
|
||||||
!this->m_distortion, delta);
|
!this->m_apply,
|
||||||
|
delta);
|
||||||
|
|
||||||
/* 5 is just in case we didn't hit real max of distortion in
|
/* 5 is just in case we didn't hit real max of distortion in
|
||||||
* BKE_tracking_max_undistortion_delta_across_bound
|
* BKE_tracking_max_undistortion_delta_across_bound
|
||||||
@@ -88,17 +70,16 @@ void MovieDistortionOperation::initExecution()
|
|||||||
m_margin[0] = delta[0] + 5;
|
m_margin[0] = delta[0] + 5;
|
||||||
m_margin[1] = delta[1] + 5;
|
m_margin[1] = delta[1] + 5;
|
||||||
|
|
||||||
DistortionCache *newC = new DistortionCache(this->m_movieClip,
|
this->m_distortion = BKE_tracking_distortion_new(tracking,
|
||||||
this->m_width, this->m_height,
|
calibration_width,
|
||||||
calibration_width, calibration_height,
|
calibration_height);
|
||||||
this->m_distortion,
|
this->m_calibration_width = calibration_width;
|
||||||
this->m_margin);
|
this->m_calibration_height = calibration_height;
|
||||||
s_cache.push_back(newC);
|
this->m_pixel_aspect = tracking->camera.pixel_aspect;
|
||||||
this->m_cache = newC;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this->m_cache = NULL;
|
|
||||||
m_margin[0] = m_margin[1] = 0;
|
m_margin[0] = m_margin[1] = 0;
|
||||||
|
this->m_distortion = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,27 +87,39 @@ void MovieDistortionOperation::deinitExecution()
|
|||||||
{
|
{
|
||||||
this->m_inputOperation = NULL;
|
this->m_inputOperation = NULL;
|
||||||
this->m_movieClip = NULL;
|
this->m_movieClip = NULL;
|
||||||
while (s_cache.size() > COM_DISTORTIONCACHE_MAXSIZE) {
|
if (this->m_distortion != NULL) {
|
||||||
double minTime = PIL_check_seconds_timer();
|
BKE_tracking_distortion_free(this->m_distortion);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MovieDistortionOperation::executePixelSampled(float output[4],
|
||||||
void MovieDistortionOperation::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/)
|
float x,
|
||||||
|
float y,
|
||||||
|
PixelSampler /*sampler*/)
|
||||||
{
|
{
|
||||||
|
if (this->m_distortion != NULL) {
|
||||||
if (this->m_cache != NULL) {
|
/* float overscan = 0.0f; */
|
||||||
float u, v;
|
const float pixel_aspect = this->m_pixel_aspect;
|
||||||
this->m_cache->getUV(&this->m_movieClip->tracking, x, y, &u, &v);
|
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);
|
this->m_inputOperation->readSampled(output, u, v, COM_PS_BILINEAR);
|
||||||
}
|
}
|
||||||
else {
|
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;
|
rcti newInput;
|
||||||
newInput.xmin = input->xmin - m_margin[0];
|
newInput.xmin = input->xmin - m_margin[0];
|
||||||
newInput.ymin = input->ymin - m_margin[1];
|
newInput.ymin = input->ymin - m_margin[1];
|
||||||
newInput.xmax = input->xmax + m_margin[0];
|
newInput.xmax = input->xmax + m_margin[0];
|
||||||
newInput.ymax = input->ymax + m_margin[1];
|
newInput.ymax = input->ymax + m_margin[1];
|
||||||
return NodeOperation::determineDependingAreaOfInterest(&newInput, readOperation, output);
|
return NodeOperation::determineDependingAreaOfInterest(&newInput,
|
||||||
|
readOperation,
|
||||||
|
output);
|
||||||
}
|
}
|
||||||
|
@@ -15,9 +15,10 @@
|
|||||||
* along with this program; if not, write to the Free Software Foundation,
|
* along with this program; if not, write to the Free Software Foundation,
|
||||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*
|
*
|
||||||
* Contributor:
|
* Contributor:
|
||||||
* Jeroen Bakker
|
* Jeroen Bakker
|
||||||
* Monique Dewanchand
|
* Monique Dewanchand
|
||||||
|
* Sergey Sharybin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _COM_MovieDistortionOperation_h_
|
#ifndef _COM_MovieDistortionOperation_h_
|
||||||
@@ -29,145 +30,37 @@
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
# include "BKE_tracking.h"
|
# 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 {
|
class MovieDistortionOperation : public NodeOperation {
|
||||||
private:
|
private:
|
||||||
DistortionCache *m_cache;
|
|
||||||
SocketReader *m_inputOperation;
|
SocketReader *m_inputOperation;
|
||||||
MovieClip *m_movieClip;
|
MovieClip *m_movieClip;
|
||||||
int m_margin[2];
|
int m_margin[2];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool m_distortion;
|
bool m_apply;
|
||||||
int m_framenumber;
|
int m_framenumber;
|
||||||
|
|
||||||
|
struct MovieDistortion *m_distortion;
|
||||||
|
int m_calibration_width, m_calibration_height;
|
||||||
|
float m_pixel_aspect;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MovieDistortionOperation(bool distortion);
|
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 initExecution();
|
||||||
void deinitExecution();
|
void deinitExecution();
|
||||||
|
|
||||||
void setMovieClip(MovieClip *clip) { this->m_movieClip = clip; }
|
void setMovieClip(MovieClip *clip) { this->m_movieClip = clip; }
|
||||||
void setFramenumber(int framenumber) { this->m_framenumber = framenumber; }
|
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
|
#endif
|
||||||
|
Reference in New Issue
Block a user