]> git.sesse.net Git - mlt/blobdiff - src/modules/vid.stab/filter_deshake.cpp
Updates to vid.stab module.
[mlt] / src / modules / vid.stab / filter_deshake.cpp
index c643a87766677f6e827ebfed1d40ab3310ab6e5b..1432db0dde44063ed448432c3fabffae9b458e6f 100644 (file)
@@ -29,60 +29,83 @@ extern "C"
 #include <string.h>
 #include <assert.h>
 
-#define FILTER_NAME "vid.stab.deshake"
-
 typedef struct _deshake_data
 {
        bool initialized;
        VSMotionDetect md;
        VSTransformData td;
        VSSlidingAvgTrans avg;
-
+       VSMotionDetectConfig mconf;
+       VSTransformConfig tconf;
        mlt_position lastFrame;
 } DeshakeData;
 
-int init_deshake(DeshakeData *data, mlt_properties properties,
-               VSPixelFormat vs_format, int *width, int *height, char* interps)
+static void get_config( VSTransformConfig* tconf, VSMotionDetectConfig* mconf, mlt_filter filter, mlt_frame frame )
+{
+       mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+       const char* filterName = mlt_properties_get( properties, "mlt_service" );
+
+       memset( mconf, 0, sizeof(VSMotionDetectConfig) );
+       *mconf = vsMotionDetectGetDefaultConfig( filterName );
+       mconf->shakiness = mlt_properties_get_int( properties, "shakiness" );
+       mconf->accuracy = mlt_properties_get_int(properties, "accuracy");
+       mconf->stepSize = mlt_properties_get_int(properties, "stepsize");
+       mconf->contrastThreshold = mlt_properties_get_double(properties, "mincontrast");
+
+       memset( tconf, 0, sizeof(VSTransformConfig) );
+       *tconf = vsTransformGetDefaultConfig( filterName );
+       tconf->smoothing = mlt_properties_get_int(properties, "smoothing");
+       tconf->maxShift = mlt_properties_get_int(properties, "maxshift");
+       tconf->maxAngle = mlt_properties_get_double(properties, "maxangle");
+       tconf->crop = (VSBorderType) mlt_properties_get_int(properties, "crop");
+       tconf->zoom = mlt_properties_get_int(properties, "zoom");
+       tconf->optZoom = mlt_properties_get_int(properties, "optzoom");
+       tconf->zoomSpeed = mlt_properties_get_double(properties, "zoomspeed");
+       tconf->relative = 1;
+
+       // by default a bicubic interpolation is selected
+       const char *interps = mlt_properties_get( MLT_FRAME_PROPERTIES( frame ), "rescale.interp" );
+       tconf->interpolType = VS_BiCubic;
+       if ( strcmp( interps, "nearest" ) == 0 || strcmp( interps, "neighbor" ) == 0 )
+               tconf->interpolType = VS_Zero;
+       else if ( strcmp( interps, "tiles" ) == 0 || strcmp( interps, "fast_bilinear" ) == 0 )
+               tconf->interpolType = VS_Linear;
+       else if ( strcmp( interps, "bilinear" ) == 0 )
+               tconf->interpolType = VS_BiLinear;
+}
+
+static int check_config( mlt_filter filter, mlt_frame frame )
+{
+       DeshakeData *data = static_cast<DeshakeData*>( filter->child );
+       VSTransformConfig new_tconf;
+       VSMotionDetectConfig new_mconf;
+
+       get_config( &new_tconf, &new_mconf, filter, frame );
+
+       if( compare_transform_config( &data->tconf, &new_tconf ) ||
+               compare_motion_config( &data->mconf, &new_mconf ) )
+       {
+               return 1;
+       }
+
+       return 0;
+}
+
+static void init_deshake( DeshakeData *data, mlt_filter filter, mlt_frame frame,
+               VSPixelFormat vs_format, int *width, int *height )
 {
        VSFrameInfo fiIn, fiOut;
-       vsFrameInfoInit(&fiIn, *width, *height, vs_format);
-       vsFrameInfoInit(&fiOut, *width, *height, vs_format);
-
-       VSMotionDetectConfig conf = vsMotionDetectGetDefaultConfig(FILTER_NAME);
-       conf.shakiness = mlt_properties_get_int(properties, "shakiness");
-       conf.accuracy = mlt_properties_get_int(properties, "accuracy");
-       conf.stepSize = mlt_properties_get_int(properties, "stepsize");
-       conf.algo = mlt_properties_get_int(properties, "algo");
-       conf.contrastThreshold = mlt_properties_get_double(properties, "mincontrast");
-       conf.show = 0;
-
-       vsMotionDetectInit(&data->md, &conf, &fiIn);
-
-       VSTransformConfig tdconf = vsTransformGetDefaultConfig(FILTER_NAME);
-       tdconf.smoothing = mlt_properties_get_int(properties, "smoothing");
-       tdconf.maxShift = mlt_properties_get_int(properties, "maxshift");
-       tdconf.maxAngle = mlt_properties_get_double(properties, "maxangle");
-       tdconf.crop = (VSBorderType) mlt_properties_get_int(properties, "crop");
-       tdconf.zoom = mlt_properties_get_int(properties, "zoom");
-       tdconf.optZoom = mlt_properties_get_int(properties, "optzoom");
-       tdconf.zoomSpeed = mlt_properties_get_double(properties, "zoomspeed");
-       tdconf.relative = 1;
-       tdconf.invert = 0;
-
-       // by default a bilinear interpolation is selected
-       tdconf.interpolType = VS_BiLinear;
-       if (strcmp(interps, "nearest") == 0 || strcmp(interps, "neighbor") == 0)
-               tdconf.interpolType = VS_Zero;
-       else if (strcmp(interps, "tiles") == 0 || strcmp(interps, "fast_bilinear") == 0)
-               tdconf.interpolType = VS_Linear;
-
-       vsTransformDataInit(&data->td, &tdconf, &fiIn, &fiOut);
+
+       vsFrameInfoInit( &fiIn, *width, *height, vs_format );
+       vsFrameInfoInit( &fiOut, *width, *height, vs_format );
+       get_config( &data->tconf, &data->mconf, filter, frame );
+       vsMotionDetectInit( &data->md, &data->mconf, &fiIn );
+       vsTransformDataInit(&data->td, &data->tconf, &fiIn, &fiOut);
 
        data->avg.initialized = 0;
-       return 0;
 }
 
-void clear_deshake(DeshakeData *data)
+static void clear_deshake(DeshakeData *data)
 {
        if (data->initialized)
        {
@@ -95,7 +118,6 @@ static int get_image(mlt_frame frame, uint8_t **image, mlt_image_format *format,
                int *width, int *height, int writable)
 {
        mlt_filter filter = (mlt_filter) mlt_frame_pop_service(frame);
-       mlt_properties properties = MLT_FILTER_PROPERTIES(filter);
        uint8_t* vs_image = NULL;
        VSPixelFormat vs_format = PF_NONE;
 
@@ -118,27 +140,19 @@ static int get_image(mlt_frame frame, uint8_t **image, mlt_image_format *format,
                // Service locks are for concurrency control
                mlt_service_lock(MLT_FILTER_SERVICE(filter));
 
-               // Handle signal from app to re-init data
-               if (mlt_properties_get_int(properties, "refresh"))
-               {
-                       mlt_properties_set(properties, "refresh", NULL);
-                       clear_deshake(data);
-                       data->initialized = false;
-               }
-
                // clear deshake data, when seeking or dropping frames
-               mlt_position pos = mlt_filter_get_position(filter, frame);
-               if(pos != data->lastFrame+1) {
-                       clear_deshake(data);
+               mlt_position pos = mlt_filter_get_position( filter, frame );
+               if( pos != data->lastFrame + 1 ||
+                       check_config( filter, frame) == 1 )
+               {
+                       clear_deshake( data );
                        data->initialized = false;
                }
                data->lastFrame = pos;
 
-               if (!data->initialized)
+               if ( !data->initialized )
                {
-                       char *interps = mlt_properties_get(MLT_FRAME_PROPERTIES(frame), "rescale.interp");
-                       init_deshake(data, properties, vs_format, width, height,
-                                       interps);
+                       init_deshake( data, filter, frame, vs_format, width, height );
                        data->initialized = true;
                }
 
@@ -151,7 +165,8 @@ static int get_image(mlt_frame frame, uint8_t **image, mlt_image_format *format,
                vsFrameFillFromBuffer(&vsFrame, vs_image, &md->fi);
                vsMotionDetection(md, &localmotions, &vsFrame);
 
-               motion = vsSimpleMotionsToTransform(md->fi, FILTER_NAME, &localmotions);
+               const char* filterName = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "mlt_service" );
+               motion = vsSimpleMotionsToTransform(md->fi, filterName, &localmotions);
                vs_vector_del(&localmotions);
 
                vsTransformPrepare(td, &vsFrame, &vsFrame);
@@ -194,8 +209,7 @@ static void close_filter(mlt_filter filter)
 extern "C"
 {
 
-mlt_filter filter_deshake_init(mlt_profile profile, mlt_service_type type,
-               const char *id, char *arg)
+mlt_filter filter_deshake_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
 {
        mlt_filter filter = NULL;
 
@@ -213,7 +227,6 @@ mlt_filter filter_deshake_init(mlt_profile profile, mlt_service_type type,
                mlt_properties_set(properties, "shakiness", "4");
                mlt_properties_set(properties, "accuracy", "4");
                mlt_properties_set(properties, "stepsize", "6");
-               mlt_properties_set(properties, "algo", "1");
                mlt_properties_set(properties, "mincontrast", "0.3");
 
                //properties for transform