mlt_repository.[hc]:
[melted] / src / modules / motion_est / filter_autotrack_rectangle.c
index 87d36dd..0d526e4 100644 (file)
@@ -40,7 +40,9 @@ void caculate_motion( struct motion_vector_s *vectors,
                      int macroblock_width,
                      int macroblock_height,
                      int mv_buffer_width,
-                     int method )
+                     int method,
+                     int width,
+                     int height )
 {
 
 
@@ -90,6 +92,18 @@ void caculate_motion( struct motion_vector_s *vectors,
 
        boundry->x -= (double)average2_x / (double)n;
        boundry->y -= (double)average2_y / (double)n;
+
+       if ( boundry->x < 0 )
+               boundry->x = 0;
+
+       if ( boundry->y < 0 )
+               boundry->y = 0;
+
+       if ( boundry->x + boundry->w > width )
+               boundry->x = width - boundry->w;
+
+       if ( boundry->y + boundry->h > height )
+               boundry->y = height - boundry->h;
 }
 
 // Image stack(able) method
@@ -115,7 +129,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                mlt_properties_debug( frame_properties, "error after mlt_frame_get_image() in autotrack_rectangle", stderr );
 
        // Get the geometry object
-       mlt_geometry geometry = mlt_properties_get_data(filter_properties, "geometry", NULL);
+       mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL);
 
        // Get the current geometry item
        struct mlt_geometry_item_s boundry;
@@ -136,7 +150,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                int macroblock_width = mlt_properties_get_int( frame_properties, "motion_est.macroblock_width" );
                int mv_buffer_width = *width / macroblock_width;
 
-               caculate_motion( vectors, &boundry, macroblock_width, macroblock_height, mv_buffer_width, method );
+               caculate_motion( vectors, &boundry, macroblock_width, macroblock_height, mv_buffer_width, method, *width, *height );
 
 
                // Make the geometry object a real boy
@@ -155,6 +169,25 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                draw_rectangle_outline(*image, boundry.x, boundry.y, boundry.w, boundry.h, 100);
        }        
 
+       if( mlt_properties_get_int( filter_properties, "obscure" ) == 1 )
+       {
+               mlt_filter obscure = mlt_properties_get_data( filter_properties, "_obscure", NULL );
+
+               mlt_properties_pass_list( MLT_FILTER_PROPERTIES(obscure), filter_properties, "in, out");
+
+               // 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 );
+               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 );
+               fflush( stdout );
+       }
+
        return error;
 }
 
@@ -171,9 +204,25 @@ static int attach_boundry_to_frame( mlt_frame frame, uint8_t **image, mlt_image_
 
        // Get the frame position
        mlt_position position = mlt_frame_get_position( frame );
-
+       
        // Get the geometry object
-       mlt_geometry geometry = mlt_properties_get_data(filter_properties, "geometry", NULL);
+       mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL);
+       if (geometry == NULL) {
+               mlt_geometry geom = mlt_geometry_init();
+               char *arg = mlt_properties_get(filter_properties, "geometry");
+
+               // Initialize with the supplied geometry
+               struct mlt_geometry_item_s item;
+               mlt_geometry_parse_item( geom, &item, arg  );
+
+               item.frame = 0;
+               item.key = 1;
+               item.mix = 100;
+
+               mlt_geometry_insert( geom, &item );
+               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);
+       }
 
        // Get the current geometry item
        mlt_geometry_item geometry_item = mlt_pool_alloc( sizeof( struct mlt_geometry_item_s ) );
@@ -217,14 +266,28 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
        if( mlt_properties_get_int( MLT_FILTER_PROPERTIES(this), "debug" ) == 1 )
        {
                mlt_filter vismv = mlt_properties_get_data( MLT_FILTER_PROPERTIES(this), "_vismv", NULL );
-               if( vismv == NULL ) {
-                       vismv = mlt_factory_filter( "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_filter_process( vismv, 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 );
+               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_filter_process( obscure, frame );
+       }
 
        return frame;
 }
@@ -233,36 +296,21 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
 */
 
 
-mlt_filter filter_autotrack_rectangle_init( char *arg )
+mlt_filter filter_autotrack_rectangle_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
 {
        mlt_filter this = mlt_filter_new( );
        if ( this != NULL )
        {
                this->process = filter_process;
 
+               // Initialize with the supplied geometry if ther is one
+               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_geometry geometry = mlt_geometry_init();
-
-               // Initialize with the supplied geometry
-               if( arg != NULL ) {
-
-                       struct mlt_geometry_item_s item;
-
-                       mlt_geometry_parse_item( geometry, &item, arg  );
-
-                       item.frame = 0;
-                       item.key = 1;
-                       item.mix = 100;
-
-                       mlt_geometry_insert( geometry, &item );
-
-               }
-
-               // ... and attach it to the frame
-               mlt_properties_set_data( MLT_FILTER_PROPERTIES(this), "geometry", geometry, 0, (mlt_destructor)mlt_geometry_close, (mlt_serialiser)mlt_geometry_serialise );
-
-               // create an instance of the motion_est filter
-               mlt_filter motion_est = mlt_factory_filter("motion_est", NULL);
+               // create an instance of the motion_est and obscure filter
+               mlt_filter motion_est = mlt_factory_filter( profile, "motion_est", NULL );
                if( motion_est != NULL )
                        mlt_properties_set_data( MLT_FILTER_PROPERTIES(this), "_motion_est", motion_est, 0, (mlt_destructor)mlt_filter_close, NULL );
                else {