#include <locale.h>
#include <pthread.h>
#include <float.h>
+#include <math.h>
/** Bit pattern used internally to indicated representations available.
}
free( copy );
- return fps * ( (hours * 3600) + (minutes * 60) + seconds ) + 0.5;
+ return lrint( fps * ( (hours * 3600) + (minutes * 60) + seconds ) );
}
/** Parse a SMPTE timecode string.
}
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.
#endif
else
result = strtod( value, &end );
- if ( *end && end[0] == '%' )
+ if ( end && end[0] == '%' )
result /= 100.0;
return result;
}
{
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 )
{
{
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 )
{
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 );
}
}
-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 ) )
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 ) )
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
* \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;
* \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;
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 );
temp = strtod( value, &p );
if ( p != value )
{
+ if ( p[0] == '%' )
+ temp /= 100.0;
if ( *p ) p ++;
switch( count )
{
}
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;
+}