+ else if (!*resource)
+ {
+ luma_bitmap = NULL;
+ mlt_properties_set( properties, "_resource", NULL );
+ mlt_properties_set_data( properties, "bitmap", luma_bitmap, 0, mlt_pool_release, NULL );
+ }
+ else
+ {
+ // Get the factory producer service
+ char *factory = mlt_properties_get( properties, "factory" );
+
+ // Create the producer
+ mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) );
+ mlt_producer producer = mlt_factory_producer( profile, factory, resource );
+
+ // 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 transition down
+ mlt_properties_pass( producer_properties, properties, "producer." );
+
+ // We will get the alpha frame from the producer
+ mlt_frame luma_frame = NULL;
+
+ // Get the luma frame
+ if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &luma_frame, 0 ) == 0 )
+ {
+ uint8_t *luma_image = NULL;
+ mlt_image_format luma_format = mlt_image_yuv422;
+
+ // Get image from the luma producer
+ mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "nearest" );
+ mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 );
+
+ // Generate the luma map
+ if ( luma_image != NULL )
+ luma_read_yuv422( luma_image, &luma_bitmap, luma_width, luma_height );
+
+ // Set the transition properties
+ mlt_properties_set_int( properties, "width", luma_width );
+ mlt_properties_set_int( properties, "height", luma_height );
+ mlt_properties_set( properties, "_resource", orig_resource);
+ mlt_properties_set_data( properties, "bitmap", luma_bitmap, luma_width * luma_height * 2, mlt_pool_release, NULL );
+
+ // Cleanup the luma frame
+ mlt_frame_close( luma_frame );
+ }
+
+ // Cleanup the luma producer
+ mlt_producer_close( producer );
+ }
+ }
+ }
+
+ // Arbitrary composite defaults
+ float mix = mlt_transition_get_progress( transition, a_frame );
+ float frame_delta = mlt_transition_get_progress_delta( transition, a_frame );
+ float luma_softness = mlt_properties_get_double( properties, "softness" );
+ int progressive =
+ mlt_properties_get_int( a_props, "consumer_deinterlace" ) ||
+ mlt_properties_get_int( properties, "progressive" ) ||
+ mlt_properties_get_int( b_props, "luma.progressive" );
+ int top_field_first = mlt_properties_get_int( b_props, "top_field_first" );
+ int reverse = mlt_properties_get_int( properties, "reverse" );
+ int invert = mlt_properties_get_int( properties, "invert" );
+
+ // Honour the reverse here
+ if ( mix >= 1.0 )
+ mix -= floor( mix );
+
+ if ( mlt_properties_get( properties, "fixed" ) )
+ mix = mlt_properties_get_double( properties, "fixed" );
+
+ if ( luma_width > 0 && luma_height > 0 && luma_bitmap != NULL )
+ {
+ reverse = invert ? !reverse : reverse;
+ mix = reverse ? 1 - mix : mix;
+ frame_delta *= reverse ? -1.0 : 1.0;
+ // Composite the frames using a luma map
+ luma_composite( !invert ? a_frame : b_frame, !invert ? b_frame : a_frame, luma_width, luma_height, luma_bitmap, mix, frame_delta,
+ luma_softness, progressive ? -1 : top_field_first, width, height );