some bugfixes, filter_shape producer, pixbuf takes svg xml, fezzik can take a service...
[melted] / src / modules / core / filter_region.c
index d45d621..8e11f37 100644 (file)
@@ -85,6 +85,15 @@ static int create_instance( mlt_filter this, char *name, char *value, int count
        return error;
 }
 
+static uint8_t *filter_get_alpha_mask( mlt_frame this )
+{
+       // Obtain properties of frame
+       mlt_properties properties = mlt_frame_properties( this );
+
+       // Return the alpha mask
+       return mlt_properties_get_data( properties, "alpha", NULL );
+}
+
 /** Do it :-).
 */
 
@@ -188,11 +197,98 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
                // Get the b frame and process with composite if successful
                mlt_transition_process( composite, frame, b_frame );
 
-               // Get the image
-               error = mlt_frame_get_image( frame, image, format, width, height, 0 );
+               // See if we have a shape producer
+               // Copy the alpha mask from the shape frame to the b_frame
+               char *resource =  mlt_properties_get( properties, "resource" );
+
+               if ( strcmp( resource, "rectangle" ) != 0 )
+               {
+                       if ( strcmp( resource, "circle" ) == 0 )
+                       {
+                               resource = strdup( "pixbuf" );
+                               mlt_properties_set( properties, "producer.resource", "<svg width='100' height='100'><circle cx='50' cy='50' r='50' fill='black'/></svg>" );
+                       }
+
+                       // Get the producer from the filter
+                       mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL );
+
+                       if ( producer == NULL )
+                       {
+                               // Get the factory producer service
+                               char *factory = mlt_properties_get( properties, "factory" );
+
+                               // Create the producer
+                               producer = mlt_factory_producer( factory, resource );
 
-               // Close the b frame
-               mlt_frame_close( b_frame );
+                               // If we have one
+                               if ( producer != NULL )
+                               {
+                                       // Get the producer properties
+                                       mlt_properties producer_properties = mlt_producer_properties( producer );
+
+                                       // Ensure that we loop
+                                       mlt_properties_set( producer_properties, "eof", "loop" );
+
+                                       // Now pass all producer. properties on the filter down
+                                       mlt_properties_pass( producer_properties, properties, "producer." );
+
+                                       // Register the producer for reuse/destruction
+                                       mlt_properties_set_data( properties, "producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL );
+                               }
+                       }
+
+                       if ( producer != NULL )
+                       {
+                               // We will get the alpha frame from the producer
+                               mlt_frame shape_frame = NULL;
+
+                               // Get the unique id of the filter (used to reacquire the producer position)
+                               char *name = mlt_properties_get( properties, "_unique_id" );
+
+                               // Get the original producer position
+                               mlt_position position = mlt_properties_get_position( mlt_frame_properties( frame ), name );
+
+                               // Make sure the producer is in the correct position
+                               mlt_producer_seek( producer, position );
+
+                               // Get the shape frame
+                               if ( mlt_service_get_frame( mlt_producer_service( producer ), &shape_frame, 0 ) == 0 )
+                               {
+                                       int region_width = mlt_properties_get_int( mlt_frame_properties( b_frame ), "width" );
+                                       int region_height = mlt_properties_get_int( mlt_frame_properties( b_frame ), "height" );
+                                       
+                                       // Get the shape image to trigger alpha creation
+                                       mlt_properties_set( mlt_frame_properties( shape_frame ), "distort", "true" );
+                                       error = mlt_frame_get_image( shape_frame, image, format, &region_width, &region_height, 1 );
+
+                                       // Only override any existing b_frame alpha if the shape has an alpha
+                                       if ( mlt_frame_get_alpha_mask( shape_frame ) != NULL )
+                                       {
+                                               // Set the b_frame alpha from the shape frame
+                                               mlt_properties_set_data( mlt_frame_properties( b_frame ), "alpha", mlt_frame_get_alpha_mask( shape_frame ), 0 , NULL, NULL );
+                                               b_frame->get_alpha_mask = filter_get_alpha_mask;
+                                       }
+                                       
+                                       // Get the image
+                                       error = mlt_frame_get_image( frame, image, format, width, height, 0 );
+
+                                       // Close the b frame
+                                       mlt_frame_close( b_frame );
+                                       b_frame = NULL;
+
+                                       // Close the shape frame
+                                       mlt_frame_close( shape_frame );
+                               }
+                       }
+               }
+               if ( b_frame != NULL )
+               {
+                       // Get the image
+                       error = mlt_frame_get_image( frame, image, format, width, height, 0 );
+
+                       // Close the b frame
+                       mlt_frame_close( b_frame );
+               }
        }
 
        return error;
@@ -230,6 +326,8 @@ mlt_filter filter_region_init( void *arg )
                // Assign the filter process method
                this->process = filter_process;
 
+               mlt_properties_set( properties, "factory", "fezzik" );
+               
                // Resource defines the shape of the region
                mlt_properties_set( properties, "resource", arg == NULL ? "rectangle" : arg );
        }