]> git.sesse.net Git - mlt/commitdiff
First draft of event handling
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Thu, 2 Sep 2004 11:20:19 +0000 (11:20 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Thu, 2 Sep 2004 11:20:19 +0000 (11:20 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@403 d19143bc-622f-0410-bfdd-b5b2a6649095

12 files changed:
src/framework/Makefile
src/framework/mlt_events.c [new file with mode: 0644]
src/framework/mlt_events.h [new file with mode: 0644]
src/framework/mlt_playlist.c
src/framework/mlt_playlist.h
src/framework/mlt_producer.c
src/framework/mlt_properties.c
src/framework/mlt_properties.h
src/framework/mlt_property.c
src/framework/mlt_service.c
src/framework/mlt_types.h
src/modules/plus/transition_affine.c

index 047e4e8ccd57b0196f95e3d87a040c139b695eab..2f3e1e3919955c8a0ec97a8bcdaba11e4614b1fe 100644 (file)
@@ -6,6 +6,7 @@ OBJS = mlt_frame.o \
           mlt_deque.o \
           mlt_property.o \
           mlt_properties.o \
+          mlt_events.o \
           mlt_service.o \
           mlt_producer.o \
           mlt_multitrack.o \
@@ -27,6 +28,7 @@ INCS = mlt_consumer.h \
           mlt_multitrack.h \
           mlt_pool.h \
           mlt_properties.h \
+          mlt_events.h \
           mlt_repository.h \
           mlt_tractor.h \
           mlt_types.h \
diff --git a/src/framework/mlt_events.c b/src/framework/mlt_events.c
new file mode 100644 (file)
index 0000000..e42dabb
--- /dev/null
@@ -0,0 +1,353 @@
+/*
+ * mlt_events.h -- event handling 
+ * Copyright (C) 2004-2005 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "mlt_properties.h"
+#include "mlt_events.h"
+
+/** Memory leak checks.
+*/
+
+//#define _MLT_EVENT_CHECKS_
+
+#ifdef _MLT_EVENT_CHECKS_
+static int events_created = 0;
+static int events_destroyed = 0;
+#endif
+
+struct mlt_events_struct
+{
+       mlt_properties owner;
+       mlt_properties list;
+};
+
+typedef struct mlt_events_struct *mlt_events;
+
+struct mlt_event_struct
+{
+       mlt_events owner;
+       int ref_count;
+       int block_count;
+       mlt_listener listener;
+       void *service;
+};
+
+/** Increment the reference count on this event.
+*/
+
+void mlt_event_inc_ref( mlt_event this )
+{
+       if ( this != NULL && this->owner != NULL )
+               this->ref_count ++;
+}
+
+/** Increment the block count on this event.
+*/
+
+void mlt_event_block( mlt_event this )
+{
+       if ( this != NULL && this->owner != NULL )
+               this->block_count ++;
+}
+
+/** Decrement the block count on this event.
+*/
+
+void mlt_event_unblock( mlt_event this )
+{
+       if ( this != NULL && this->owner != NULL )
+               this->block_count --;
+}
+
+/** Close this event.
+*/
+
+void mlt_event_close( mlt_event this )
+{
+       if ( this != NULL && this->owner != NULL )
+       {
+               if ( -- this->ref_count == 1 )
+                       this->owner = NULL;
+               if ( this->ref_count <= 0 )
+               {
+#ifdef _MLT_EVENT_CHECKS_
+                       events_destroyed ++;
+                       fprintf( stderr, "Events created %d, destroyed %d\n", events_created, events_destroyed );
+#endif
+                       free( this );
+               }
+       }
+}
+
+/** Forward declaration to private functions.
+*/
+
+static mlt_events mlt_events_fetch( mlt_properties );
+static void mlt_events_store( mlt_properties, mlt_events );
+static void mlt_events_close( mlt_events );
+
+/** Initialise the events structure.
+*/
+
+void mlt_events_init( mlt_properties this )
+{
+       mlt_events events = mlt_events_fetch( this );
+       if ( events == NULL )
+       {
+               events = malloc( sizeof( struct mlt_events_struct ) );
+               events->list = mlt_properties_new( );
+               mlt_events_store( this, events );
+       }
+}
+
+/** Register an event and transmitter.
+*/
+
+int mlt_events_register( mlt_properties this, char *id, mlt_transmitter transmitter )
+{
+       int error = 1;
+       mlt_events events = mlt_events_fetch( this );
+       if ( events != NULL )
+       {
+               mlt_properties list = events->list;
+               char temp[ 128 ];
+               error = mlt_properties_set_data( list, id, transmitter, 0, NULL, NULL );
+               sprintf( temp, "list:%s", id );
+               if ( mlt_properties_get_data( list, temp, NULL ) == NULL )
+                       mlt_properties_set_data( list, temp, mlt_properties_new( ), 0, ( mlt_destructor )mlt_properties_close, NULL );
+       }
+       return error;
+}
+
+/** Fire an event.
+*/
+
+void mlt_events_fire( mlt_properties this, char *id, ... )
+{
+       mlt_events events = mlt_events_fetch( this );
+       if ( events != NULL )
+       {
+               int i = 0;
+               va_list alist;
+               void *args[ 10 ];
+               mlt_properties list = events->list;
+               mlt_properties listeners = NULL;
+               char temp[ 128 ];
+               mlt_transmitter transmitter = mlt_properties_get_data( list, id, NULL );
+               sprintf( temp, "list:%s", id );
+               listeners = mlt_properties_get_data( list, temp, NULL );
+
+               va_start( alist, id );
+               do
+                       args[ i ] = va_arg( alist, void * );
+               while( args[ i ++ ] != NULL );
+               va_end( alist );
+
+               if ( listeners != NULL )
+               {
+                       for ( i = 0; i < mlt_properties_count( listeners ); i ++ )
+                       {
+                               mlt_event event = mlt_properties_get_data_at( listeners, i, NULL );
+                               if ( event != NULL && event->owner != NULL && event->block_count == 0 )
+                               {
+                                       if ( transmitter != NULL )
+                                               transmitter( event->listener, event->owner, event->service, args );
+                                       else
+                                               event->listener( event->owner, event->service );
+                               }
+                       }
+               }
+       }
+}
+
+/** Register a listener.
+*/
+
+mlt_event mlt_events_listen( mlt_properties this, void *service, char *id, mlt_listener listener )
+{
+       mlt_event event = NULL;
+       mlt_events events = mlt_events_fetch( this );
+       if ( events != NULL )
+       {
+               mlt_properties list = events->list;
+               mlt_properties listeners = NULL;
+               char temp[ 128 ];
+               sprintf( temp, "list:%s", id );
+               listeners = mlt_properties_get_data( list, temp, NULL );
+               if ( listeners != NULL )
+               {
+                       int first_null = -1;
+                       int i = 0;
+                       for ( i = 0; event == NULL && i < mlt_properties_count( listeners ); i ++ )
+                       {
+                               mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL );
+                               if ( entry != NULL && entry->owner != NULL )
+                               {
+                                       if ( entry->service == service && entry->listener == listener )
+                                               event = entry;
+                               }
+                               else if ( ( entry == NULL || entry->owner == NULL ) && first_null == -1 )
+                               {
+                                       first_null = i;
+                               }
+                       }
+
+                       if ( event == NULL )
+                       {
+                               event = malloc( sizeof( struct mlt_event_struct ) );
+                               if ( event != NULL )
+                               {
+#ifdef _MLT_EVENT_CHECKS_
+                                       events_created ++;
+#endif
+                                       sprintf( temp, "%d", first_null == -1 ? mlt_properties_count( listeners ) : first_null );
+                                       event->owner = events;
+                                       event->ref_count = 0;
+                                       event->block_count = 0;
+                                       event->listener = listener;
+                                       event->service = service;
+                                       mlt_properties_set_data( listeners, temp, event, 0, ( mlt_destructor )mlt_event_close, NULL );
+                               }
+                       }
+
+                       if ( event != NULL )
+                               mlt_event_inc_ref( event );
+               }
+       }
+       return event;
+}
+
+/** Block all events for a given service.
+*/
+
+void mlt_events_block( mlt_properties this, void *service )
+{
+       mlt_events events = mlt_events_fetch( this );
+       if ( events != NULL )
+       {
+               int i = 0, j = 0;
+               mlt_properties list = events->list;
+               for ( j = 0; j < mlt_properties_count( list ); j ++ )
+               {
+                       char *temp = mlt_properties_get_name( list, j );
+                       if ( !strncmp( temp, "list:", 5 ) )
+                       {
+                               mlt_properties listeners = mlt_properties_get_data( list, temp, NULL );
+                               for ( i = 0; i < mlt_properties_count( listeners ); i ++ )
+                               {
+                                       mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL );
+                                       if ( entry != NULL && entry->service == service )
+                                               mlt_event_block( entry );
+                               }
+                       }
+               }
+       }
+}
+
+/** Unblock all events for a given service.
+*/
+
+void mlt_events_unblock( mlt_properties this, void *service )
+{
+       mlt_events events = mlt_events_fetch( this );
+       if ( events != NULL )
+       {
+               int i = 0, j = 0;
+               mlt_properties list = events->list;
+               for ( j = 0; j < mlt_properties_count( list ); j ++ )
+               {
+                       char *temp = mlt_properties_get_name( list, j );
+                       if ( !strncmp( temp, "list:", 5 ) )
+                       {
+                               mlt_properties listeners = mlt_properties_get_data( list, temp, NULL );
+                               for ( i = 0; i < mlt_properties_count( listeners ); i ++ )
+                               {
+                                       mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL );
+                                       if ( entry != NULL && entry->service == service )
+                                               mlt_event_unblock( entry );
+                               }
+                       }
+               }
+       }
+}
+
+/** Disconnect all events for a given service.
+*/
+
+void mlt_events_disconnect( mlt_properties this, void *service )
+{
+       mlt_events events = mlt_events_fetch( this );
+       if ( events != NULL )
+       {
+               int i = 0, j = 0;
+               mlt_properties list = events->list;
+               for ( j = 0; j < mlt_properties_count( list ); j ++ )
+               {
+                       char *temp = mlt_properties_get_name( list, j );
+                       if ( !strncmp( temp, "list:", 5 ) )
+                       {
+                               mlt_properties listeners = mlt_properties_get_data( list, temp, NULL );
+                               for ( i = 0; i < mlt_properties_count( listeners ); i ++ )
+                               {
+                                       mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL );
+                                       char *name = mlt_properties_get_name( listeners, i );
+                                       if ( entry != NULL && entry->service == service )
+                                               mlt_properties_set_data( listeners, name, NULL, 0, NULL, NULL );
+                               }
+                       }
+               }
+       }
+}
+
+/** Fetch the events object.
+*/
+
+static mlt_events mlt_events_fetch( mlt_properties this )
+{
+       mlt_events events = NULL;
+       if ( this != NULL )
+               events = mlt_properties_get_data( this, "_events", NULL );
+       return events;
+}
+
+/** Store the events object.
+*/
+
+static void mlt_events_store( mlt_properties this, mlt_events events )
+{
+       if ( this != NULL && events != NULL )
+               mlt_properties_set_data( this, "_events", events, 0, ( mlt_destructor )mlt_events_close, NULL );
+}
+
+/** Close the events object.
+*/
+
+static void mlt_events_close( mlt_events events )
+{
+       if ( events != NULL )
+       {
+               mlt_properties_close( events->list );
+               free( events );
+       }
+}
+
diff --git a/src/framework/mlt_events.h b/src/framework/mlt_events.h
new file mode 100644 (file)
index 0000000..b6639cd
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * mlt_events.h -- event handling 
+ * Copyright (C) 2004-2005 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _MLT_EVENTS_H_
+#define _MLT_EVENTS_H_
+
+#include "mlt_types.h"
+
+typedef void ( *mlt_transmitter )( );
+typedef void ( *mlt_listener )( );
+
+extern void mlt_events_init( mlt_properties self );
+extern int mlt_events_register( mlt_properties self, char *id, mlt_transmitter transmitter );
+extern void mlt_events_fire( mlt_properties self, char *id, ... );
+extern mlt_event mlt_events_listen( mlt_properties self, void *service, char *id, mlt_listener listener );
+extern void mlt_events_block( mlt_properties self, void *service );
+extern void mlt_events_unblock( mlt_properties self, void *service );
+extern void mlt_events_disconnect( mlt_properties self, void *service );
+
+extern void mlt_event_inc_ref( mlt_event self );
+extern void mlt_event_block( mlt_event self );
+extern void mlt_event_unblock( mlt_event self );
+extern void mlt_event_close( mlt_event self );
+
+#endif
+
index 0e017cebdc99a2dfef17b777d629bb8657a07e2a..be707f6c27aa33e35eea7d231c4831246994008e 100644 (file)
@@ -36,6 +36,7 @@ typedef struct
        mlt_position frame_in;
        mlt_position frame_out;
        mlt_position frame_count;
+       mlt_event event;
 }
 playlist_entry;
 
@@ -129,10 +130,12 @@ mlt_properties mlt_playlist_properties( mlt_playlist this )
 
 static int mlt_playlist_virtual_refresh( mlt_playlist this )
 {
-       int i = 0;
+       // Obtain the properties
+       mlt_properties properties = mlt_playlist_properties( this );
 
        // Get the fps of the first producer
-       double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "first_fps" );
+       double fps = mlt_properties_get_double( properties, "first_fps" );
+       int i = 0;
        mlt_position frame_count = 0;
 
        for ( i = 0; i < this->count; i ++ )
@@ -160,19 +163,31 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
        }
 
        // Refresh all properties
-       mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", fps );
-       mlt_properties_set_double( mlt_playlist_properties( this ), "fps", fps == 0 ? 25 : fps );
-       mlt_properties_set_position( mlt_playlist_properties( this ), "length", frame_count );
-       mlt_properties_set_position( mlt_playlist_properties( this ), "out", frame_count - 1 );
+       mlt_properties_set_double( properties, "first_fps", fps );
+       mlt_properties_set_double( properties, "fps", fps == 0 ? 25 : fps );
+       mlt_events_block( properties, properties );
+       mlt_properties_set_position( properties, "length", frame_count );
+       mlt_events_unblock( properties, properties );
+       mlt_properties_set_position( properties, "out", frame_count - 1 );
 
        return 0;
 }
 
+/** Listener for producers on the playlist.
+*/
+
+static void mlt_playlist_listener( mlt_producer producer, mlt_playlist this )
+{
+       mlt_playlist_virtual_refresh( this );
+}
+
 /** Append to the virtual playlist.
 */
 
 static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_position in, mlt_position out )
 {
+       mlt_properties properties = mlt_producer_properties( producer );
+
        // Check that we have room
        if ( this->count >= this->size )
        {
@@ -187,14 +202,15 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer
        this->list[ this->count ]->frame_in = in;
        this->list[ this->count ]->frame_out = out;
        this->list[ this->count ]->frame_count = out - in + 1;
+       this->list[ this->count ]->event = mlt_events_listen( properties, this, "producer-changed", ( mlt_listener )mlt_playlist_listener );
 
-       mlt_properties_set( mlt_producer_properties( producer ), "eof", "pause" );
+       mlt_properties_set( properties, "eof", "pause" );
 
        mlt_producer_set_speed( producer, 0 );
 
        this->count ++;
 
-       mlt_properties_inc_ref( mlt_producer_properties( producer ) );
+       mlt_properties_inc_ref( properties );
 
        return mlt_playlist_virtual_refresh( this );
 }
@@ -306,7 +322,7 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
        }
 
        // Seek in real producer to relative position
-       if ( i < this->count )
+       if ( i < this->count && this->list[ i ]->frame_out != position )
        {
                // Update the frame_count for the changed clip (hmmm)
                this->list[ i ]->frame_out = position;
@@ -417,6 +433,7 @@ int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info,
                info->frame_count = this->list[ index ]->frame_count;
                info->length = mlt_producer_get_length( producer );
                info->fps = mlt_producer_get_fps( producer );
+               info->event = this->list[ index ]->event;
        }
 
        // Determine the consuming filter service
@@ -445,7 +462,10 @@ int mlt_playlist_clear( mlt_playlist this )
 {
        int i;
        for ( i = 0; i < this->count; i ++ )
+       {
+               mlt_event_close( this->list[ i ]->event );
                mlt_producer_close( this->list[ i ]->producer );
+       }
        this->count = 0;
        mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", 0 );
        return mlt_playlist_virtual_refresh( this );
@@ -487,10 +507,14 @@ int mlt_playlist_blank( mlt_playlist this, mlt_position length )
 int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_position in, mlt_position out )
 {
        // Append to end
+       mlt_events_block( mlt_playlist_properties( this ), this );
        mlt_playlist_append_io( this, producer, in, out );
 
        // Move to the position specified
-       return mlt_playlist_move( this, this->count - 1, where );
+       mlt_playlist_move( this, this->count - 1, where );
+       mlt_events_unblock( mlt_playlist_properties( this ), this );
+
+       return mlt_playlist_virtual_refresh( this );
 }
 
 /** Remove an entry in the playlist.
@@ -520,6 +544,7 @@ int mlt_playlist_remove( mlt_playlist this, int where )
                mlt_playlist_get_clip_info( this, &where_info, where );
 
                // Close the producer associated to the clip info
+               mlt_event_close( where_info.event );
                mlt_producer_close( where_info.producer );
 
                // Reorganise the list
@@ -534,6 +559,9 @@ int mlt_playlist_remove( mlt_playlist this, int where )
                        mlt_producer_seek( mlt_playlist_producer( this ), position - where_info.frame_count );
                else if ( this->count == 0 )
                        mlt_producer_seek( mlt_playlist_producer( this ), 0 );
+
+               // Refresh the playlist
+               mlt_playlist_virtual_refresh( this );
        }
 
        return 0;
@@ -591,6 +619,7 @@ int mlt_playlist_move( mlt_playlist this, int src, int dest )
 
                mlt_playlist_get_clip_info( this, &current_info, current );
                mlt_producer_seek( mlt_playlist_producer( this ), current_info.start + position );
+               mlt_playlist_virtual_refresh( this );
        }
 
        return 0;
@@ -640,7 +669,9 @@ int mlt_playlist_split( mlt_playlist this, int clip, mlt_position position )
                {
                        int in = entry->frame_in;
                        int out = entry->frame_out;
+                       mlt_events_block( mlt_playlist_properties( this ), this );
                        mlt_playlist_resize_clip( this, clip, in, in + position );
+                       mlt_events_unblock( mlt_playlist_properties( this ), this );
                        mlt_playlist_insert( this, entry->producer, clip + 1, in + position + 1, out );
                }
                else
@@ -661,6 +692,7 @@ int mlt_playlist_join( mlt_playlist this, int clip, int count, int merge )
        {
                int i = clip;
                mlt_playlist new_clip = mlt_playlist_init( );
+               mlt_events_block( mlt_playlist_properties( this ), this );
                if ( clip + count >= this->count )
                        count = this->count - clip;
                for ( i = 0; i <= count; i ++ )
@@ -669,6 +701,7 @@ int mlt_playlist_join( mlt_playlist this, int clip, int count, int merge )
                        mlt_playlist_append_io( new_clip, entry->producer, entry->frame_in, entry->frame_out );
                        mlt_playlist_remove( this, clip );
                }
+               mlt_events_unblock( mlt_playlist_properties( this ), this );
                mlt_playlist_insert( this, mlt_playlist_producer( new_clip ), clip, 0, -1 );
                mlt_playlist_close( new_clip );
        }
@@ -721,13 +754,14 @@ void mlt_playlist_close( mlt_playlist this )
        {
                int i = 0;
                this->parent.close = NULL;
-               mlt_producer_close( &this->parent );
-               mlt_producer_close( &this->blank );
                for ( i = 0; i < this->count; i ++ )
                {
+                       mlt_event_close( this->list[ i ]->event );
                        mlt_producer_close( this->list[ i ]->producer );
                        free( this->list[ i ] );
                }
+               mlt_producer_close( &this->blank );
+               mlt_producer_close( &this->parent );
                free( this->list );
                free( this );
        }
index bfa61c03a92d8394506e95ccf55b7b1008b33ba8..1566b1a89f9acbcab64f23a1d937e0f8af3b3052 100644 (file)
@@ -38,6 +38,7 @@ typedef struct
        mlt_position frame_count;
        mlt_position length;
        float fps;
+       mlt_event event;
 }
 mlt_playlist_clip_info;
 
index c07b2b2f8c30c51b026cc738f057719cbd3f7757..4fda305526c0d8a056de87431d23b0a00dd82f19 100644 (file)
@@ -31,6 +31,7 @@
 */
 
 static int producer_get_frame( mlt_service this, mlt_frame_ptr frame, int index );
+static void mlt_producer_property_changed( mlt_service owner, mlt_producer this, char *name );
 
 /** Constructor
 */
@@ -91,12 +92,24 @@ int mlt_producer_init( mlt_producer this, void *child )
 
                        // Override service get_frame
                        parent->get_frame = producer_get_frame;
+
+                       mlt_events_listen( properties, this, "property-changed", ( mlt_listener )mlt_producer_property_changed );
+                       mlt_events_register( properties, "producer-changed", NULL );
                }
        }
 
        return error;
 }
 
+/** Listener for property changes.
+*/
+
+static void mlt_producer_property_changed( mlt_service owner, mlt_producer this, char *name )
+{
+       if ( !strcmp( name, "in" ) || !strcmp( name, "out" ) || !strcmp( name, "length" ) )
+               mlt_events_fire( mlt_producer_properties( this ), "producer-changed", NULL );
+}
+
 /** Create a new producer.
 */
 
@@ -201,6 +214,8 @@ double mlt_producer_get_fps( mlt_producer this )
 
 int mlt_producer_set_in_and_out( mlt_producer this, mlt_position in, mlt_position out )
 {
+       mlt_properties properties = mlt_producer_properties( this );
+
        // Correct ins and outs if necessary
        if ( in < 0 )
                in = 0;
@@ -221,8 +236,11 @@ int mlt_producer_set_in_and_out( mlt_producer this, mlt_position in, mlt_positio
        }
 
        // Set the values
-       mlt_properties_set_position( mlt_producer_properties( this ), "in", in );
-       mlt_properties_set_position( mlt_producer_properties( this ), "out", out );
+       mlt_events_block( properties, properties );
+       mlt_properties_set_position( properties, "in", in );
+       mlt_properties_set_position( properties, "out", out );
+       mlt_events_unblock( properties, properties );
+       mlt_events_fire( properties, "producer-changed", NULL );
 
        return 0;
 }
index 189f8affac439b041b8961c9bf1b25a34ec274e2..1d13714634b051a3e815981dd76650378de08452 100644 (file)
@@ -373,6 +373,8 @@ int mlt_properties_set( mlt_properties this, char *name, char *value )
                mlt_properties_do_mirror( this, name );
        }
 
+       mlt_events_fire( this, "property-changed", name, NULL );
+
        return error;
 }
 
@@ -500,6 +502,8 @@ int mlt_properties_set_int( mlt_properties this, char *name, int value )
                mlt_properties_do_mirror( this, name );
        }
 
+       mlt_events_fire( this, "property-changed", name, NULL );
+
        return error;
 }
 
@@ -529,6 +533,8 @@ int mlt_properties_set_double( mlt_properties this, char *name, double value )
                mlt_properties_do_mirror( this, name );
        }
 
+       mlt_events_fire( this, "property-changed", name, NULL );
+
        return error;
 }
 
@@ -558,6 +564,8 @@ int mlt_properties_set_position( mlt_properties this, char *name, mlt_position v
                mlt_properties_do_mirror( this, name );
        }
 
+       mlt_events_fire( this, "property-changed", name, NULL );
+
        return error;
 }
 
@@ -584,6 +592,8 @@ int mlt_properties_set_data( mlt_properties this, char *name, void *value, int l
        if ( property != NULL )
                error = mlt_property_set_data( property, value, length, destroy, serialise );
 
+       mlt_events_fire( this, "property-changed", name, NULL );
+
        return error;
 }
 
index c57208e5cbb99d2aed3735b9e1b44285e9becb32..a331029ec53d8182304624cc6fb66a5d324928d2 100644 (file)
@@ -22,6 +22,7 @@
 #define _MLT_PROPERTIES_H_
 
 #include "mlt_types.h"
+#include "mlt_events.h"
 #include <stdio.h>
 
 /** The properties base class defines the basic property propagation and
index f3613ce20cca713908d71e0133102bdbf55783b9..1a458d86df47399769a3d63116551185619f17fd 100644 (file)
@@ -116,7 +116,7 @@ int mlt_property_set_string( mlt_property this, char *value )
        this->types = mlt_prop_string;
        if ( value != NULL )
                this->prop_string = strdup( value );
-       return this->prop_string != NULL;
+       return this->prop_string == NULL;
 }
 
 /** Set an int64 on this property.
index 7a66a577e417b40224d71bd2ce121080a9ddb26e..6df363064cebcd5534d3c38c35bd2fc9002ef665 100644 (file)
@@ -53,6 +53,7 @@ mlt_service_base;
 static void mlt_service_disconnect( mlt_service this );
 static void mlt_service_connect( mlt_service this, mlt_service that );
 static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int index );
+static void mlt_service_property_changed( mlt_listener, mlt_properties owner, mlt_service this, void **args );
 
 /** Constructor
 */
@@ -79,11 +80,20 @@ int mlt_service_init( mlt_service this, void *child )
        {
                this->parent.close = ( mlt_destructor )mlt_service_close;
                this->parent.close_object = this;
+
+               mlt_events_init( &this->parent );
+               mlt_events_register( &this->parent, "property-changed", ( mlt_transmitter )mlt_service_property_changed );
        }
 
        return error;
 }
 
+static void mlt_service_property_changed( mlt_listener listener, mlt_properties owner, mlt_service this, void **args )
+{
+       if ( listener != NULL )
+               listener( owner, this, ( char * )args[ 0 ] );
+}
+
 /** Connect a producer service.
        Returns: > 0 warning, == 0 success, < 0 serious error
                         1 = this service does not accept input
index 284c35bc5ca8d0b0587e1d11f45c0caad191adba..5954f5fcb47d4dd08ad2dec0043768ed0e914dc2 100644 (file)
@@ -53,6 +53,7 @@ mlt_whence;
 typedef int32_t mlt_position;
 typedef struct mlt_frame_s *mlt_frame, **mlt_frame_ptr;
 typedef struct mlt_properties_s *mlt_properties;
+typedef struct mlt_event_struct *mlt_event;
 typedef struct mlt_service_s *mlt_service;
 typedef struct mlt_producer_s *mlt_producer;
 typedef struct mlt_manager_s *mlt_manager;
index b6a53f7a664b373b8566d295b6c5853a6fdbddaf..f95b1483955438455715b42a58ba5a58623d5df2 100644 (file)
@@ -554,6 +554,9 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
                float sw, sh;
 
                // Get values from the transition
+               float fix_rotate_x = mlt_properties_get_double( properties, "fix_rotate_x" );
+               float fix_rotate_y = mlt_properties_get_double( properties, "fix_rotate_y" );
+               float fix_rotate_z = mlt_properties_get_double( properties, "fix_rotate_z" );
                float rotate_x = mlt_properties_get_double( properties, "rotate_x" );
                float rotate_y = mlt_properties_get_double( properties, "rotate_y" );
                float rotate_z = mlt_properties_get_double( properties, "rotate_z" );
@@ -588,9 +591,9 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
 
                affine_t affine;
                affine_init( affine.matrix );
-               affine_rotate( affine.matrix, rotate_x * ( position - in ) );
-               affine_rotate_y( affine.matrix, rotate_y * ( position - in ) );
-               affine_rotate_z( affine.matrix, rotate_z * ( position - in ) );
+               affine_rotate( affine.matrix, fix_rotate_x + rotate_x * ( position - in ) );
+               affine_rotate_y( affine.matrix, fix_rotate_y + rotate_y * ( position - in ) );
+               affine_rotate_z( affine.matrix, fix_rotate_z + rotate_z * ( position - in ) );
                affine_shear( affine.matrix, 
                                          fix_shear_x + shear_x * ( position - in ), 
                                          fix_shear_y + shear_y * ( position - in ),