Filter attachments to services
[melted] / src / modules / core / transition_region.c
index d24def9..aa7b660 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,41 @@ 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;
+}
+
+static void apply_filters( mlt_filter this, mlt_frame frame, int index )
+{
+       mlt_service service = mlt_filter_service( this );
+       mlt_properties properties = mlt_filter_properties( this );
+       int i;
+
+       if ( index == 0 || mlt_properties_get_int( properties, "_filter_private" ) == 0 )
+       {
+               mlt_filter filter = NULL;
+               for ( i = 0; ( filter = mlt_service_filter( service, i ) ) != NULL; i ++ )
+               {
+                       mlt_filter_process( filter, frame );
+                       apply_filters( filter, frame, 1 );
+               }
+       }
 }
 
 /** Do it :-).
@@ -245,6 +281,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 ];
 
@@ -265,7 +304,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 );
@@ -274,6 +314,11 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                        filter = mlt_properties_get_data( properties, id, NULL );
                }
 
+               // Allow filters to be attached to a region filter
+               filter = mlt_properties_get_data( properties, "_region_filter", NULL );
+               if ( filter != NULL )
+                       apply_filters( filter, b_frame, 0 );
+
                // Hmm - this is probably going to go wrong....
                mlt_frame_set_position( frame, position );
 
@@ -287,11 +332,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 )
                                {