Flexible and animated shapes
[melted] / src / modules / core / transition_region.c
index 4e2eb11..e8391c5 100644 (file)
@@ -91,6 +91,8 @@ static int create_instance( mlt_transition this, char *name, char *value, int co
 
 static uint8_t *filter_get_alpha_mask( mlt_frame this )
 {
+       uint8_t *alpha = NULL;
+
        // Obtain properties of frame
        mlt_properties properties = mlt_frame_properties( this );
 
@@ -107,7 +109,24 @@ static uint8_t *filter_get_alpha_mask( mlt_frame this )
        mlt_properties_set( mlt_frame_properties( shape_frame ), "distort", "true" );
        mlt_frame_get_image( shape_frame, &image, &format, &region_width, &region_height, 0 );
 
-       return mlt_frame_get_alpha_mask( shape_frame );
+       alpha = mlt_frame_get_alpha_mask( shape_frame );
+
+       // Generate from the Y component of the image if no alpha available
+       if ( alpha == NULL )
+       {
+               int size = region_width * region_height;
+               uint8_t *p = mlt_pool_alloc( size );
+               alpha = p;
+               while ( size -- )
+               {
+                       *p ++ = *image ++;
+                       image ++;
+               }
+               mlt_properties_set_data( mlt_frame_properties( shape_frame ), "alpha", alpha, 
+                                                                region_width * region_height, mlt_pool_release, NULL );
+       }
+
+       return alpha;
 }
 
 /** Do it :-).
@@ -118,12 +137,12 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
        // Error we will return
        int error = 0;
 
-       // Get the watermark transition object
-       mlt_transition this = mlt_frame_pop_service( frame );
-
        // We will get the 'b frame' from the frame stack
        mlt_frame b_frame = mlt_frame_pop_frame( frame );
 
+       // Get the watermark transition object
+       mlt_transition this = mlt_frame_pop_service( frame );
+
        // Get the properties of the transition
        mlt_properties properties = mlt_transition_properties( this );
 
@@ -162,6 +181,12 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                        mlt_properties_set_data( properties, "composite", composite, 0, ( mlt_destructor )mlt_transition_close, NULL );
                }
        }
+       else
+       {
+               // Pass all current properties down
+               mlt_properties composite_properties = mlt_transition_properties( composite );
+               mlt_properties_pass( composite_properties, properties, "composite." );
+       }
 
        // Create filters
        if ( filter == NULL )
@@ -190,6 +215,45 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                        }
                }
        }
+       else
+       {
+               // Pass all properties down
+               mlt_filter temp = NULL;
+
+               // Loop Variable
+               int i = 0;
+
+               // Number of filters found
+               int count = 0;
+
+               // Loop for all properties
+               for ( i = 0; i < mlt_properties_count( properties ); i ++ )
+               {
+                       // Get the name of this property
+                       char *name = mlt_properties_get_name( properties, i );
+
+                       // If the name does not contain a . and matches filter
+                       if ( strchr( name, '.' ) == NULL && !strncmp( name, "filter", 6 ) )
+                       {
+                               // Strings to hold the id and pass down key
+                               char id[ 256 ];
+                               char key[ 256 ];
+
+                               // Construct id and key
+                               sprintf( id, "_filter_%d", count );
+                               sprintf( key, "%s.", name );
+
+                               // Get the filter
+                               temp = mlt_properties_get_data( properties, id, NULL );
+
+                               if ( temp != NULL )
+                               {
+                                       mlt_properties_pass( mlt_filter_properties( temp ), properties, key );
+                                       count ++;
+                               }
+                       }
+               }
+       }
 
        // Get the image
        error = mlt_frame_get_image( frame, image, format, width, height, 1 );
@@ -200,6 +264,9 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                // Get the resource of this filter (could be a shape [rectangle/circle] or an alpha provider of choice
                char *resource =  mlt_properties_get( properties, "resource" );
 
+               // Get the old resource in case it's changed
+               char *old_resource =  mlt_properties_get( properties, "_old_resource" );
+
                // String to hold the filter to query on
                char id[ 256 ];
 
@@ -220,7 +287,8 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                while ( filter != NULL )
                {
                        // Stack this filter
-                       mlt_filter_process( filter, b_frame );
+                       if ( mlt_properties_get_int( mlt_filter_properties( filter ), "off" ) == 0 )
+                               mlt_filter_process( filter, b_frame );
 
                        // Generate the key for the next
                        sprintf( id, "_filter_%d", ++ i );
@@ -242,11 +310,14 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                        mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL );
 
                        // If We have no producer then create one
-                       if ( producer == NULL )
+                       if ( producer == NULL || ( old_resource != NULL && strcmp( resource, old_resource ) ) )
                        {
                                // Get the factory producer service
                                char *factory = mlt_properties_get( properties, "factory" );
 
+                               // Store the old resource
+                               mlt_properties_set( properties, "_old_resource", resource );
+
                                // Special case circle resource
                                if ( strcmp( resource, "circle" ) == 0 )
                                {
@@ -322,12 +393,12 @@ static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt
        // Push the transition on to the frame
        mlt_frame_push_service( a_frame, this );
 
-       // Push the transition method
-       mlt_frame_push_get_image( a_frame, transition_get_image );
-
        // Push the b_frame on to the stack
        mlt_frame_push_frame( a_frame, b_frame );
 
+       // Push the transition method
+       mlt_frame_push_get_image( a_frame, transition_get_image );
+
        // Return the frame
        return a_frame;
 }