]> git.sesse.net Git - mlt/blobdiff - src/modules/motion_est/filter_autotrack_rectangle.c
Add consumer-thread-create and consumer-thread-join events.
[mlt] / src / modules / motion_est / filter_autotrack_rectangle.c
index f7db4a68cc289de0416e28dfb5d39f165eef7acc..e6caff199b499973fd0121f570c20a50cfea2d12 100644 (file)
@@ -120,7 +120,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
        mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame);
 
        // Get the frame position
-       mlt_position position = mlt_frame_get_position( frame );
+       mlt_position position = mlt_filter_get_position( filter, frame );
 
        // Get the new image
        int error = mlt_frame_get_image( frame, image, format, width, height, 1 );
@@ -128,6 +128,8 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
        if( error != 0 )
                mlt_properties_debug( frame_properties, "error after mlt_frame_get_image() in autotrack_rectangle", stderr );
 
+       mlt_service_lock( MLT_FILTER_SERVICE( filter ) );
+
        // Get the geometry object
        mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL);
 
@@ -169,14 +171,45 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                boundry.f[3] = 1;
                boundry.f[4] = 1;
                mlt_geometry_insert(geometry, &boundry);
+               mlt_geometry_interpolate(geometry);
        }
 
-               if( mlt_properties_get_int( filter_properties, "debug" ) == 1 )
+       mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
+
+       if( mlt_properties_get_int( filter_properties, "debug" ) == 1 )
        {
                init_arrows( format, *width, *height );
                draw_rectangle_outline(*image, boundry.x, boundry.y, boundry.w, boundry.h, 100);
-       }        
+       }
 
+       if( mlt_properties_get_int( filter_properties, "_serialize" ) == 1 )
+       {
+               // Add the vector change to the list
+               mlt_geometry key_frames = mlt_properties_get_data( filter_properties, "motion_vector_list", NULL );
+               if ( !key_frames )
+               {
+                       key_frames = mlt_geometry_init();
+                       mlt_properties_set_data( filter_properties, "motion_vector_list", key_frames, 0,
+                                                (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise );
+                       if ( key_frames )
+                               mlt_geometry_set_length( key_frames, mlt_filter_get_length2( filter, frame ) );
+               }
+               if ( key_frames )
+               {
+                       struct mlt_geometry_item_s item;
+                       item.frame = (int) mlt_frame_get_position( frame );
+                       item.key = 1;
+                       item.x = boundry.x;
+                       item.y = boundry.y;
+                       item.w = boundry.w;
+                       item.h = boundry.h;
+                       item.mix = 0;
+                       item.f[0] = item.f[1] = item.f[2] = item.f[3] = 1;
+                       item.f[4] = 0;
+                       mlt_geometry_insert( key_frames, &item );
+               }
+       }
+       
        if( mlt_properties_get_int( filter_properties, "obscure" ) == 1 )
        {
                mlt_filter obscure = mlt_properties_get_data( filter_properties, "_obscure", NULL );
@@ -185,14 +218,14 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
 
                // Because filter_obscure needs to be rewritten to use mlt_geometry
                char geom[100];
-               sprintf( geom, "%d,%d:%dx%d", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h );
+               sprintf( geom, "%d/%d:%dx%d", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h );
                mlt_properties_set( MLT_FILTER_PROPERTIES( obscure ), "start", geom );
                mlt_properties_set( MLT_FILTER_PROPERTIES( obscure ), "end", geom );
        }
                
        if( mlt_properties_get_int( filter_properties, "collect" ) == 1 )
        {
-               printf( "%d,%d,%d,%d\n", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h );
+               fprintf( stderr, "%d,%d,%d,%d\n", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h );
                fflush( stdout );
        }
 
@@ -211,8 +244,10 @@ static int attach_boundry_to_frame( mlt_frame frame, uint8_t **image, mlt_image_
        mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame);
 
        // Get the frame position
-       mlt_position position = mlt_frame_get_position( frame );
+       mlt_position position = mlt_filter_get_position( filter, frame );
        
+       mlt_service_lock( MLT_FILTER_SERVICE( filter ) );
+
        // Get the geometry object
        mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL);
        if (geometry == NULL) {
@@ -228,10 +263,13 @@ static int attach_boundry_to_frame( mlt_frame frame, uint8_t **image, mlt_image_
                item.mix = 100;
 
                mlt_geometry_insert( geom, &item );
+               mlt_geometry_interpolate( geom );
                mlt_properties_set_data( filter_properties, "filter_geometry", geom, 0, (mlt_destructor)mlt_geometry_close, (mlt_serialiser)mlt_geometry_serialise );
                geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL);
        }
 
+       mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
+
        // Get the current geometry item
        mlt_geometry_item geometry_item = mlt_pool_alloc( sizeof( struct mlt_geometry_item_s ) );
        mlt_geometry_fetch(geometry, geometry_item, position);
@@ -264,15 +302,14 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
         /* modify the frame with the current geometry */
        mlt_frame_push_service( frame, this);
        mlt_frame_push_get_image( frame, attach_boundry_to_frame );
-
-
+       mlt_properties properties = MLT_FILTER_PROPERTIES( this );
 
        /* apply the motion estimation filter */
-       mlt_filter motion_est = mlt_properties_get_data( MLT_FILTER_PROPERTIES(this), "_motion_est", NULL ); 
+       mlt_filter motion_est = mlt_properties_get_data( properties, "_motion_est", NULL ); 
+       /* Pass motion_est properties */
+       mlt_properties_pass( MLT_FILTER_PROPERTIES( motion_est ), properties, "motion_est." );
        mlt_filter_process( motion_est, frame);
 
-
-
        /* calculate the new geometry based on the motion */
        mlt_frame_push_service( frame, this);
        mlt_frame_push_get_image( frame, filter_get_image );
@@ -281,12 +318,12 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
        /* visualize the motion vectors */
        if( mlt_properties_get_int( MLT_FILTER_PROPERTIES(this), "debug" ) == 1 )
        {
-               mlt_filter vismv = mlt_properties_get_data( MLT_FILTER_PROPERTIES(this), "_vismv", NULL );
+               mlt_filter vismv = mlt_properties_get_data( properties, "_vismv", NULL );
                if( vismv == NULL )
                {
                        mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) );
                        vismv = mlt_factory_filter( profile, "vismv", NULL );
-                       mlt_properties_set_data( MLT_FILTER_PROPERTIES(this), "_vismv", vismv, 0, (mlt_destructor)mlt_filter_close, NULL );
+                       mlt_properties_set_data( properties, "_vismv", vismv, 0, (mlt_destructor)mlt_filter_close, NULL );
                }
 
                mlt_filter_process( vismv, frame );
@@ -294,12 +331,12 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
 
        if( mlt_properties_get_int( MLT_FILTER_PROPERTIES(this), "obscure" ) == 1 )
        {
-               mlt_filter obscure = mlt_properties_get_data( MLT_FILTER_PROPERTIES(this), "_obscure", NULL );
+               mlt_filter obscure = mlt_properties_get_data( properties, "_obscure", NULL );
                if( obscure == NULL )
                {
                        mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) );
                        obscure = mlt_factory_filter( profile, "obscure", NULL );
-                       mlt_properties_set_data( MLT_FILTER_PROPERTIES(this), "_obscure", obscure, 0, (mlt_destructor)mlt_filter_close, NULL );
+                       mlt_properties_set_data( properties, "_obscure", obscure, 0, (mlt_destructor)mlt_filter_close, NULL );
                }
 
                mlt_filter_process( obscure, frame );
@@ -323,7 +360,7 @@ mlt_filter filter_autotrack_rectangle_init( mlt_profile profile, mlt_service_typ
                if( arg != NULL ) 
                        mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "geometry", arg );
                else
-                       mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "geometry", "100,100:100x100" );
+                       mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "geometry", "100/100:100x100" );
 
                // create an instance of the motion_est and obscure filter
                mlt_filter motion_est = mlt_factory_filter( profile, "motion_est", NULL );