]> git.sesse.net Git - mlt/blobdiff - src/framework/mlt_property.c
Add mlt_properties_get_animation(); it might come in handy.
[mlt] / src / framework / mlt_property.c
index e86f2f1c1e332a081f15e2d89b478cecacb17f48..5a2ac5ca520866c7644ccd1e32f032e2c3830bdd 100644 (file)
@@ -35,6 +35,7 @@
 #include <locale.h>
 #include <pthread.h>
 #include <float.h>
+#include <math.h>
 
 
 /** Bit pattern used internally to indicated representations available.
@@ -305,7 +306,7 @@ static int time_clock_to_frames( const char *s, double fps, locale_t locale )
        }
        free( copy );
 
-       return fps * ( (hours * 3600) + (minutes * 60) + seconds ) + 0.5;
+       return lrint( fps * ( (hours * 3600) + (minutes * 60) + seconds ) );
 }
 
 /** Parse a SMPTE timecode string.
@@ -351,7 +352,7 @@ static int time_code_to_frames( const char *s, double fps )
        }
        free( copy );
 
-       return frames + ( fps * ( (hours * 3600) + (minutes * 60) + seconds ) + 0.5 );
+       return lrint( fps * ( (hours * 3600) + (minutes * 60) + seconds ) + frames );
 }
 
 /** Convert a string to an integer.
@@ -463,7 +464,7 @@ static double mlt_property_atof( const char *value, double fps, locale_t locale
 #endif
                else
                        result = strtod( value, &end );
-               if ( *end && end[0] == '%' )
+               if ( end && end[0] == '%' )
                        result /= 100.0;
                return result;
        }
@@ -591,7 +592,7 @@ char *mlt_property_get_string( mlt_property self )
                {
                        self->types |= mlt_prop_string;
                        self->prop_string = malloc( 32 );
-                       sprintf( self->prop_string, "%f", self->prop_double );
+                       sprintf( self->prop_string, "%g", self->prop_double );
                }
                else if ( self->types & mlt_prop_position )
                {
@@ -667,7 +668,7 @@ char *mlt_property_get_string_l( mlt_property self, locale_t locale )
                {
                        self->types |= mlt_prop_string;
                        self->prop_string = malloc( 32 );
-                       sprintf( self->prop_string, "%f", self->prop_double );
+                       sprintf( self->prop_string, "%g", self->prop_double );
                }
                else if ( self->types & mlt_prop_position )
                {
@@ -1000,66 +1001,42 @@ int mlt_property_interpolate( mlt_property self, mlt_property p[],
                        mlt_rect value = { DBL_MIN, DBL_MIN, DBL_MIN, DBL_MIN, DBL_MIN };
                        if ( interp == mlt_keyframe_linear )
                        {
-                               int i = 5;
                                mlt_rect points[2];
                                mlt_rect zero = {0, 0, 0, 0, 0};
                                points[0] = p[1]? mlt_property_get_rect( p[1], locale ) : zero;
-                               points[1] = p[2]? mlt_property_get_rect( p[2], locale ) : zero;
-                               while ( i-- ) switch ( i )
+                               if ( p[2] )
                                {
-                                       case 0: value.x = p[2]?
-                                                       linear_interpolate( points[0].x, points[1].x, progress ):
-                                                       points[0].x;
-                                               break;
-                                       case 1: value.y = p[2]?
-                                                       linear_interpolate( points[0].y, points[1].y, progress ):
-                                                       points[0].y;
-                                               break;
-                                       case 2: value.w = p[2]?
-                                                       linear_interpolate( points[0].w, points[1].w, progress ):
-                                                       points[0].w;
-                                               break;
-                                       case 3: value.h = p[2]?
-                                                       linear_interpolate( points[0].h, points[1].h, progress ):
-                                                       points[0].h;
-                                               break;
-                                       case 4: value.o = p[2]?
-                                                       linear_interpolate( points[0].o, points[1].o, progress ):
-                                                       points[0].o;
-                                               break;
+                                       points[1] = mlt_property_get_rect( p[2], locale );
+                                       value.x = linear_interpolate( points[0].x, points[1].x, progress );
+                                       value.y = linear_interpolate( points[0].y, points[1].y, progress );
+                                       value.w = linear_interpolate( points[0].w, points[1].w, progress );
+                                       value.h = linear_interpolate( points[0].h, points[1].h, progress );
+                                       value.o = linear_interpolate( points[0].o, points[1].o, progress );
+                               }
+                               else
+                               {
+                                       value = points[0];
                                }
                        }
                        else if ( interp == mlt_keyframe_smooth )
                        {
-                               int i = 5;
                                mlt_rect points[4];
                                mlt_rect zero = {0, 0, 0, 0, 0};
-                               points[0] = p[0]? mlt_property_get_rect( p[0], locale ) : zero;
                                points[1] = p[1]? mlt_property_get_rect( p[1], locale ) : zero;
-                               points[2] = p[2]? mlt_property_get_rect( p[2], locale ) : zero;
-                               points[3] = p[3]? mlt_property_get_rect( p[3], locale ) : zero;
-                               while ( i-- ) switch ( i )
+                               if ( p[2] )
+                               {
+                                       points[0] = p[0]? mlt_property_get_rect( p[0], locale ) : zero;
+                                       points[2] = p[2]? mlt_property_get_rect( p[2], locale ) : zero;
+                                       points[3] = p[3]? mlt_property_get_rect( p[3], locale ) : zero;
+                                       value.x = catmull_rom_interpolate( points[0].x, points[1].x, points[2].x, points[3].x, progress );
+                                       value.y = catmull_rom_interpolate( points[0].y, points[1].y, points[2].y, points[3].y, progress );
+                                       value.w = catmull_rom_interpolate( points[0].w, points[1].w, points[2].w, points[3].w, progress );
+                                       value.h = catmull_rom_interpolate( points[0].h, points[1].h, points[2].h, points[3].h, progress );
+                                       value.o = catmull_rom_interpolate( points[0].o, points[1].o, points[2].o, points[3].o, progress );
+                               }
+                               else
                                {
-                                       case 0: value.x = p[2]?
-                                                       catmull_rom_interpolate( points[0].x, points[1].x, points[2].x, points[3].x, progress ):
-                                                       points[1].x;
-                                               break;
-                                       case 1: value.y = p[2]?
-                                                       catmull_rom_interpolate( points[0].y, points[1].y, points[2].y, points[3].y, progress ):
-                                                       points[1].y;
-                                               break;
-                                       case 2: value.w = p[2]?
-                                                       catmull_rom_interpolate( points[0].w, points[1].w, points[2].w, points[3].w, progress ):
-                                                       points[1].w;
-                                               break;
-                                       case 3: value.h = p[2]?
-                                                       catmull_rom_interpolate( points[0].h, points[1].h, points[2].h, points[3].h, progress ):
-                                                       points[1].h;
-                                               break;
-                                       case 4: value.o = p[2]?
-                                                       catmull_rom_interpolate( points[0].o, points[1].o, points[2].o, points[3].o, progress ):
-                                                       points[1].o;
-                                               break;
+                                       value = points[1];
                                }
                        }
                        error = mlt_property_set_rect( self, value );
@@ -1116,7 +1093,7 @@ static void refresh_animation( mlt_property self, double fps, locale_t locale, i
        }
 }
 
-double mlt_property_get_double_pos( mlt_property self, double fps, locale_t locale, int position, int length )
+double mlt_property_anim_get_double( mlt_property self, double fps, locale_t locale, int position, int length )
 {
        double result;
        if ( self->animation || ( ( self->types & mlt_prop_string ) && self->prop_string ) )
@@ -1137,7 +1114,7 @@ double mlt_property_get_double_pos( mlt_property self, double fps, locale_t loca
        return result;
 }
 
-int mlt_property_get_int_pos( mlt_property self, double fps, locale_t locale, int position, int length )
+int mlt_property_anim_get_int( mlt_property self, double fps, locale_t locale, int position, int length )
 {
        int result;
        if ( self->animation || ( ( self->types & mlt_prop_string ) && self->prop_string ) )
@@ -1158,6 +1135,37 @@ int mlt_property_get_int_pos( mlt_property self, double fps, locale_t locale, in
        return result;
 }
 
+char* mlt_property_anim_get_string( mlt_property self, double fps, locale_t locale, int position, int length )
+{
+       char *result;
+       if ( self->animation || ( ( self->types & mlt_prop_string ) && self->prop_string ) )
+       {
+               struct mlt_animation_item_s item;
+               item.property = mlt_property_init();
+
+               if ( !self->animation )
+                       refresh_animation( self, fps, locale, length );
+               mlt_animation_get_item( self->animation, &item, position );
+
+               pthread_mutex_lock( &self->mutex );
+               if ( self->prop_string )
+                       free( self->prop_string );
+               self->prop_string = mlt_property_get_string_l( item.property, locale );
+               if ( self->prop_string )
+                       self->prop_string = strdup( self->prop_string );
+               self->types |= mlt_prop_string;
+               pthread_mutex_unlock( &self->mutex );
+
+               result = self->prop_string;
+               mlt_property_close( item.property );
+       }
+       else
+       {
+               result = mlt_property_get_string_l( self, locale );
+       }
+       return result;
+}
+
 /** Set a property animation keyframe to a real number.
  *
  * \public \memberof mlt_property_s
@@ -1166,8 +1174,8 @@ int mlt_property_get_int_pos( mlt_property self, double fps, locale_t locale, in
  * \return false if successful, true to indicate error
  */
 
-int mlt_property_set_double_pos( mlt_property self, double value, double fps, locale_t locale,
-       mlt_keyframe_type keyframe_type, int position, int length )
+int mlt_property_anim_set_double( mlt_property self, double value, double fps, locale_t locale,
+       int position, int length, mlt_keyframe_type keyframe_type )
 {
        int result;
        struct mlt_animation_item_s item;
@@ -1193,8 +1201,8 @@ int mlt_property_set_double_pos( mlt_property self, double value, double fps, lo
  * \return false if successful, true to indicate error
  */
 
-int mlt_property_set_int_pos( mlt_property self, int value, double fps, locale_t locale,
-       mlt_keyframe_type keyframe_type, int position, int length )
+int mlt_property_anim_set_int( mlt_property self, int value, double fps, locale_t locale,
+       int position, int length, mlt_keyframe_type keyframe_type )
 {
        int result;
        struct mlt_animation_item_s item;
@@ -1212,6 +1220,24 @@ int mlt_property_set_int_pos( mlt_property self, int value, double fps, locale_t
        return result;
 }
 
+int mlt_property_anim_set_string( mlt_property self, const char *value, double fps, locale_t locale, int position, int length )
+{
+       int result;
+       struct mlt_animation_item_s item;
+
+       item.property = mlt_property_init();
+       item.frame = position;
+       item.keyframe_type = mlt_keyframe_discrete;
+       mlt_property_set_string( item.property, value );
+
+       refresh_animation( self, fps, locale, length );
+       result = mlt_animation_insert( self->animation, &item );
+       mlt_animation_interpolate( self->animation );
+       mlt_property_close( item.property );
+
+       return result;
+}
+
 static char* serialise_mlt_rect( mlt_rect *rect, int length )
 {
        char* result = calloc( 1, 100 );
@@ -1289,6 +1315,8 @@ mlt_rect mlt_property_get_rect( mlt_property self, locale_t locale )
                                temp = strtod( value, &p );
                        if ( p != value )
                        {
+                               if ( p[0] == '%' )
+                                       temp /= 100.0;
                                if ( *p ) p ++;
                                switch( count )
                                {
@@ -1309,3 +1337,57 @@ mlt_rect mlt_property_get_rect( mlt_property self, locale_t locale )
        }
        return rect;
 }
+
+/** Set a property animation keyframe to a rectangle.
+ *
+ * \public \memberof mlt_property_s
+ * \param self a property
+ * \param value a rectangle
+ * \return false if successful, true to indicate error
+ */
+
+int mlt_property_anim_set_rect( mlt_property self, mlt_rect value, double fps, locale_t locale,
+       int position, int length, mlt_keyframe_type keyframe_type )
+{
+       int result;
+       struct mlt_animation_item_s item;
+
+       item.property = mlt_property_init();
+       item.frame = position;
+       item.keyframe_type = keyframe_type;
+       mlt_property_set_rect( item.property, value );
+
+       refresh_animation( self, fps, locale, length );
+       result = mlt_animation_insert( self->animation, &item );
+       mlt_animation_interpolate( self->animation );
+       mlt_property_close( item.property );
+
+       return result;
+}
+
+mlt_rect mlt_property_anim_get_rect( mlt_property self, double fps, locale_t locale, int position, int length )
+{
+       mlt_rect result;
+       if ( self->animation || ( ( self->types & mlt_prop_string ) && self->prop_string ) )
+       {
+               struct mlt_animation_item_s item;
+               item.property = mlt_property_init();
+               item.property->types = mlt_prop_rect;
+
+               refresh_animation( self, fps, locale, length );
+               mlt_animation_get_item( self->animation, &item, position );
+               result = mlt_property_get_rect( item.property, locale );
+
+               mlt_property_close( item.property );
+       }
+       else
+       {
+               result = mlt_property_get_rect( self, locale );
+       }
+       return result;
+}
+
+mlt_animation mlt_property_get_animation( mlt_property self )
+{
+       return self->animation;
+}