+/** Convert the profile into properties on the consumer.
+ *
+ * \private \memberof mlt_consumer_s
+ * \param self a consumer
+ * \param profile a profile
+ * \param properties a properties list (typically, the consumer's)
+ */
+
+static void apply_profile_properties( mlt_consumer self, mlt_profile profile, mlt_properties properties )
+{
+ consumer_private *priv = self->local;
+ mlt_event_block( priv->event_listener );
+ mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) );
+ mlt_properties_set_int( properties, "frame_rate_num", profile->frame_rate_num );
+ mlt_properties_set_int( properties, "frame_rate_den", profile->frame_rate_den );
+ mlt_properties_set_int( properties, "width", profile->width );
+ mlt_properties_set_int( properties, "height", profile->height );
+ mlt_properties_set_int( properties, "progressive", profile->progressive );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
+ mlt_properties_set_int( properties, "sample_aspect_num", profile->sample_aspect_num );
+ mlt_properties_set_int( properties, "sample_aspect_den", profile->sample_aspect_den );
+ mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile ) );
+ mlt_properties_set_int( properties, "display_aspect_num", profile->display_aspect_num );
+ mlt_properties_set_int( properties, "display_aspect_num", profile->display_aspect_num );
+ mlt_properties_set_int( properties, "colorspace", profile->colorspace );
+ mlt_event_unblock( priv->event_listener );
+}
+
+/** The property-changed event listener
+ *
+ * \private \memberof mlt_consumer_s
+ * \param owner the events object
+ * \param self the consumer
+ * \param name the name of the property that changed
+ */
+
+static void mlt_consumer_property_changed( mlt_properties owner, mlt_consumer self, char *name )
+{
+ if ( !strcmp( name, "mlt_profile" ) )
+ {
+ // Get the properies
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+
+ // Get the current profile
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+
+ // Load the new profile
+ mlt_profile new_profile = mlt_profile_init( mlt_properties_get( properties, name ) );
+
+ if ( new_profile )
+ {
+ // Copy the profile
+ if ( profile != NULL )
+ {
+ free( profile->description );
+ memcpy( profile, new_profile, sizeof( struct mlt_profile_s ) );
+ profile->description = strdup( new_profile->description );
+ }
+ else
+ {
+ profile = new_profile;
+ }
+
+ // Apply to properties
+ apply_profile_properties( self, profile, properties );
+ mlt_profile_close( new_profile );
+ }
+ }
+ else if ( !strcmp( name, "frame_rate_num" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ {
+ profile->frame_rate_num = mlt_properties_get_int( properties, "frame_rate_num" );
+ mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) );
+ }
+ }
+ else if ( !strcmp( name, "frame_rate_den" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ {
+ profile->frame_rate_den = mlt_properties_get_int( properties, "frame_rate_den" );
+ mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) );
+ }
+ }
+ else if ( !strcmp( name, "width" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ profile->width = mlt_properties_get_int( properties, "width" );
+ }
+ else if ( !strcmp( name, "height" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ profile->height = mlt_properties_get_int( properties, "height" );
+ }
+ else if ( !strcmp( name, "progressive" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ profile->progressive = mlt_properties_get_int( properties, "progressive" );
+ }
+ else if ( !strcmp( name, "sample_aspect_num" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ {
+ profile->sample_aspect_num = mlt_properties_get_int( properties, "sample_aspect_num" );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
+ }
+ }
+ else if ( !strcmp( name, "sample_aspect_den" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ {
+ profile->sample_aspect_den = mlt_properties_get_int( properties, "sample_aspect_den" );
+ mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile ) );
+ }
+ }
+ else if ( !strcmp( name, "display_aspect_num" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ {
+ profile->display_aspect_num = mlt_properties_get_int( properties, "display_aspect_num" );
+ mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile ) );
+ }
+ }
+ else if ( !strcmp( name, "display_aspect_den" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ {
+ profile->display_aspect_den = mlt_properties_get_int( properties, "display_aspect_den" );
+ mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile ) );
+ }
+ }
+ else if ( !strcmp( name, "colorspace" ) )
+ {
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
+ mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
+ if ( profile )
+ profile->colorspace = mlt_properties_get_int( properties, "colorspace" );
+ }
+}
+
+/** The transmitter for the consumer-frame-show event
+ *
+ * Invokes the listener.
+ *
+ * \private \memberof mlt_consumer_s
+ * \param listener a function pointer that will be invoked
+ * \param owner the events object that will be passed to \p listener
+ * \param self a service that will be passed to \p listener
+ * \param args an array of pointers - the first entry is passed as a frame to \p listener
+ */
+
+static void mlt_consumer_frame_show( mlt_listener listener, mlt_properties owner, mlt_service self, void **args )