#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)
{
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;
// 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;
}
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);
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;
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