From 4bcfca4adaa008e51ee23d6b0e02b3bf2eb9ed93 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Mon, 15 Aug 2011 22:28:45 -0700 Subject: [PATCH] Add mlt_geometry_interpolate. This removes re-interpolation on each call to mlt_geometry_insert() to make bulk invocations of that call faster. This also makes mlt_geometry_parse() faster. Also, this includes a fix to mlt_geometry_serialise() for a buffer overflow memory corruption. --- src/framework/mlt_geometry.c | 13 ++++--------- src/framework/mlt_geometry.h | 2 ++ src/mlt++/MltGeometry.cpp | 5 +++++ src/mlt++/MltGeometry.h | 1 + src/modules/core/transition_composite.c | 1 + src/modules/gtk2/producer_pango.c | 1 + src/modules/motion_est/filter_autotrack_rectangle.c | 2 ++ 7 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/framework/mlt_geometry.c b/src/framework/mlt_geometry.c index 6c28ceb9..65bb7802 100644 --- a/src/framework/mlt_geometry.c +++ b/src/framework/mlt_geometry.c @@ -75,7 +75,7 @@ static inline double linearstep( double start, double end, double position, int return start + position * o; } -static void mlt_geometry_virtual_refresh( mlt_geometry self ) +void mlt_geometry_interpolate( mlt_geometry self ) { geometry g = self->local; @@ -244,6 +244,7 @@ int mlt_geometry_parse( mlt_geometry self, char *data, int length, int nw, int n // Now insert into place mlt_geometry_insert( self, &item ); } + mlt_geometry_interpolate( self ); // Remove the tokeniser mlt_tokeniser_close( tokens ); @@ -505,9 +506,6 @@ int mlt_geometry_insert( mlt_geometry self, mlt_geometry_item item ) g->item->data.f[4] = 1; } - // Refresh all geometries - mlt_geometry_virtual_refresh( self ); - // TODO: Error checking return 0; } @@ -529,9 +527,6 @@ int mlt_geometry_remove( mlt_geometry self, int position ) if ( place != NULL && position == place->data.frame ) ret = mlt_geometry_drop( self, place ); - // Refresh all geometries - mlt_geometry_virtual_refresh( self ); - return ret; } @@ -571,7 +566,7 @@ int mlt_geometry_prev_key( mlt_geometry self, mlt_geometry_item item, int positi return place == NULL; } -#define ISINT(x) ( (x) == (int) (x) ) +#define ISINT(x) ( (x) == (int64_t) (x) ) #define PICKFMT(x) ( ISINT(x) ? "%.0f" : "%f" ) char *mlt_geometry_serialise_cut( mlt_geometry self, int in, int out ) @@ -658,7 +653,7 @@ char *mlt_geometry_serialise_cut( mlt_geometry self, int in, int out ) sprintf( temp + strlen( temp ), PICKFMT( item.mix ), item.mix ); } - if ( used + strlen( temp ) > size ) + if ( used + strlen( temp ) + 2 > size ) // +2 for ';' and NULL { size += 1000; ret = realloc( ret, size ); diff --git a/src/framework/mlt_geometry.h b/src/framework/mlt_geometry.h index 81201846..e753c67b 100644 --- a/src/framework/mlt_geometry.h +++ b/src/framework/mlt_geometry.h @@ -60,6 +60,8 @@ extern int mlt_geometry_fetch( mlt_geometry self, mlt_geometry_item item, float extern int mlt_geometry_insert( mlt_geometry self, mlt_geometry_item item ); /* Remove the key at the specified position */ extern int mlt_geometry_remove( mlt_geometry self, int position ); +/* Typically, re-interpolate after a series of insertions or removals. */ +extern void mlt_geometry_interpolate( mlt_geometry self ); /* Get the key at the position or the next following */ extern int mlt_geometry_next_key( mlt_geometry self, mlt_geometry_item item, int position ); extern int mlt_geometry_prev_key( mlt_geometry self, mlt_geometry_item item, int position ); diff --git a/src/mlt++/MltGeometry.cpp b/src/mlt++/MltGeometry.cpp index d0333fe4..7755bd86 100644 --- a/src/mlt++/MltGeometry.cpp +++ b/src/mlt++/MltGeometry.cpp @@ -66,6 +66,11 @@ int Geometry::remove( int position ) return mlt_geometry_remove( geometry, position ); } +void Geometry::interpolate( ) +{ + mlt_geometry_interpolate( geometry ); +} + // Get the key at the position or the next following int Geometry::next_key( GeometryItem &item, int position ) { diff --git a/src/mlt++/MltGeometry.h b/src/mlt++/MltGeometry.h index 7c90bd32..de788208 100644 --- a/src/mlt++/MltGeometry.h +++ b/src/mlt++/MltGeometry.h @@ -65,6 +65,7 @@ namespace Mlt int insert( GeometryItem *item ); // Remove the key at the specified position int remove( int position ); + void interpolate( ); // Get the key at the position or the next following int next_key( GeometryItem &item, int position ); int next_key( GeometryItem *item, int position ); diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index 43e6e982..1f5b6fa2 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -156,6 +156,7 @@ static mlt_geometry transition_parse_keys( mlt_transition this, int normalised_w item.frame = -1; if ( mlt_geometry_parse_item( geometry, &item, mlt_properties_get( properties, "end" ) ) == 0 ) mlt_geometry_insert( geometry, &item ); + mlt_geometry_interpolate( geometry ); } return geometry; diff --git a/src/modules/gtk2/producer_pango.c b/src/modules/gtk2/producer_pango.c index 5b6c3804..0988715d 100644 --- a/src/modules/gtk2/producer_pango.c +++ b/src/modules/gtk2/producer_pango.c @@ -174,6 +174,7 @@ mlt_producer producer_pango_init( const char *filename ) item.frame = atoi( name ); mlt_geometry_insert( key_frames, &item ); } + mlt_geometry_interpolate( key_frames ); } else { diff --git a/src/modules/motion_est/filter_autotrack_rectangle.c b/src/modules/motion_est/filter_autotrack_rectangle.c index b5b0022f..fc5e69be 100644 --- a/src/modules/motion_est/filter_autotrack_rectangle.c +++ b/src/modules/motion_est/filter_autotrack_rectangle.c @@ -171,6 +171,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format boundry.f[3] = 1; boundry.f[4] = 1; mlt_geometry_insert(geometry, &boundry); + mlt_geometry_interpolate(geometry); } mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); @@ -234,6 +235,7 @@ static int attach_boundry_to_frame( mlt_frame frame, uint8_t **image, mlt_image_ item.mix = 100; mlt_geometry_insert( geom, &item ); + mlt_geometry_interpolate( geom ); mlt_properties_set_data( filter_properties, "filter_geometry", geom, 0, (mlt_destructor)mlt_geometry_close, (mlt_serialiser)mlt_geometry_serialise ); geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL); } -- 2.39.2