From 909d149697331a560edb1924f58fc58c5a25aaea Mon Sep 17 00:00:00 2001 From: lilo_booter Date: Thu, 2 Sep 2004 11:20:19 +0000 Subject: [PATCH] First draft of event handling git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@403 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/framework/Makefile | 2 + src/framework/mlt_events.c | 353 ++++++++++++++++++++++++++++++++++ src/framework/mlt_events.h | 43 ++++ src/framework/mlt_playlist.c | 58 +++++-- src/framework/mlt_playlist.h | 1 + src/framework/mlt_producer.c | 22 ++- src/framework/mlt_properties.c | 10 + src/framework/mlt_properties.h | 1 + src/framework/mlt_property.c | 2 +- src/framework/mlt_service.c | 10 + src/framework/mlt_types.h | 1 + src/modules/plus/transition_affine.c | 9 +- 12 files changed, 494 insertions(+), 18 deletions(-) create mode 100644 src/framework/mlt_events.c create mode 100644 src/framework/mlt_events.h diff --git a/src/framework/Makefile b/src/framework/Makefile index 047e4e8..2f3e1e3 100644 --- a/src/framework/Makefile +++ b/src/framework/Makefile @@ -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 index 0000000..e42dabb --- /dev/null +++ b/src/framework/mlt_events.c @@ -0,0 +1,353 @@ +/* + * mlt_events.h -- event handling + * Copyright (C) 2004-2005 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * 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 +#include +#include + +#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 index 0000000..b6639cd --- /dev/null +++ b/src/framework/mlt_events.h @@ -0,0 +1,43 @@ +/* + * mlt_events.h -- event handling + * Copyright (C) 2004-2005 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * 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 + diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c index 0e017ce..be707f6 100644 --- a/src/framework/mlt_playlist.c +++ b/src/framework/mlt_playlist.c @@ -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, ¤t_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 ); } diff --git a/src/framework/mlt_playlist.h b/src/framework/mlt_playlist.h index bfa61c0..1566b1a 100644 --- a/src/framework/mlt_playlist.h +++ b/src/framework/mlt_playlist.h @@ -38,6 +38,7 @@ typedef struct mlt_position frame_count; mlt_position length; float fps; + mlt_event event; } mlt_playlist_clip_info; diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index c07b2b2..4fda305 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -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; } diff --git a/src/framework/mlt_properties.c b/src/framework/mlt_properties.c index 189f8af..1d13714 100644 --- a/src/framework/mlt_properties.c +++ b/src/framework/mlt_properties.c @@ -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; } diff --git a/src/framework/mlt_properties.h b/src/framework/mlt_properties.h index c57208e..a331029 100644 --- a/src/framework/mlt_properties.h +++ b/src/framework/mlt_properties.h @@ -22,6 +22,7 @@ #define _MLT_PROPERTIES_H_ #include "mlt_types.h" +#include "mlt_events.h" #include /** The properties base class defines the basic property propagation and diff --git a/src/framework/mlt_property.c b/src/framework/mlt_property.c index f3613ce..1a458d8 100644 --- a/src/framework/mlt_property.c +++ b/src/framework/mlt_property.c @@ -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. diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c index 7a66a57..6df3630 100644 --- a/src/framework/mlt_service.c +++ b/src/framework/mlt_service.c @@ -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 diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index 284c35b..5954f5f 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -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; diff --git a/src/modules/plus/transition_affine.c b/src/modules/plus/transition_affine.c index b6a53f7..f95b148 100644 --- a/src/modules/plus/transition_affine.c +++ b/src/modules/plus/transition_affine.c @@ -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 ), -- 1.7.4.4