X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fframework%2Fmlt_property.c;h=4b5f4cc38b7fbb454545bb4aa6e7afcb0940f417;hb=3181f81620bdd95bec5555f70fbb344a7cfaed5b;hp=bbc02ee0d7c49940dcea22bbdbf7e15a34fb2104;hpb=56f7b2f2499ae1cfe0417a09d89e652badfc7bb2;p=mlt diff --git a/src/framework/mlt_property.c b/src/framework/mlt_property.c index bbc02ee0..4b5f4cc3 100644 --- a/src/framework/mlt_property.c +++ b/src/framework/mlt_property.c @@ -3,8 +3,9 @@ * \brief Property class definition * \see mlt_property_s * - * Copyright (C) 2003-2009 Ushodaya Enterprises Limited + * Copyright (C) 2003-2013 Ushodaya Enterprises Limited * \author Charles Yates + * \author Dan Dennedy * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,6 +36,7 @@ #include #include #include +#include /** Bit pattern used internally to indicated representations available. @@ -305,7 +307,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 +353,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. @@ -460,8 +462,8 @@ static double mlt_property_atof( const char *value, double fps, locale_t locale #if defined(__GLIBC__) || defined(__DARWIN__) if ( locale ) result = strtod_l( value, &end, locale ); + else #endif - else result = strtod( value, &end ); if ( end && end[0] == '%' ) result /= 100.0; @@ -772,10 +774,10 @@ void mlt_property_pass( mlt_property self, mlt_property that ) self->destructor = free; self->serialiser = that->serialiser; } - else if ( self->types & mlt_prop_data && self->serialiser != NULL ) + else if ( self->types & mlt_prop_data && that->serialiser != NULL ) { self->types = mlt_prop_string; - self->prop_string = self->serialiser( self->data, self->length ); + self->prop_string = that->serialiser( that->data, that->length ); } pthread_mutex_unlock( &self->mutex ); } @@ -947,6 +949,14 @@ char *mlt_property_get_time( mlt_property self, mlt_time_format format, double f return self->prop_string; } +/** Determine if the property holds a numeric or numeric string value. + * + * \private \memberof mlt_property_s + * \param self a property + * \param locale the locale to use for string evaluation + * \return true if it is numeric + */ + static int is_property_numeric( mlt_property self, locale_t locale ) { int result = ( self->types & mlt_prop_int ) || @@ -971,13 +981,23 @@ static int is_property_numeric( mlt_property self, locale_t locale ) return result; } +/** A linear interpolation function for animation. + * + * \private \memberof mlt_property_s + */ + static inline double linear_interpolate( double y1, double y2, double t ) { return y1 + ( y2 - y1 ) * t; } -// For non-closed curves, you need to also supply the tangent vector at the first and last control point. -// This is commonly done: T(P[0]) = P[1] - P[0] and T(P[n]) = P[n] - P[n-1]. +/** A smooth spline interpolation for animation. + * + * For non-closed curves, you need to also supply the tangent vector at the first and last control point. + * This is commonly done: T(P[0]) = P[1] - P[0] and T(P[n]) = P[n] - P[n-1]. + * \private \memberof mlt_property_s + */ + static inline double catmull_rom_interpolate( double y0, double y1, double y2, double y3, double t ) { double t2 = t * t; @@ -988,6 +1008,20 @@ static inline double catmull_rom_interpolate( double y0, double y1, double y2, d return a0 * t * t2 + a1 * t2 + a2 * t + a3; } +/** Interpolate a new property value given a set of other properties. + * + * \public \memberof mlt_property_s + * \param self the property onto which to set the computed value + * \param p an array of at least 1 value in p[1] if \p interp is discrete, + * 2 values in p[1] and p[2] if \p interp is linear, or + * 4 values in p[0] - p[3] if \p interp is smooth + * \param progress a ratio in the range [0, 1] to indicate how far between p[1] and p[2] + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param interp the interpolation method to use + * \return true if there was an error + */ + int mlt_property_interpolate( mlt_property self, mlt_property p[], double progress, double fps, locale_t locale, mlt_keyframe_type interp ) { @@ -1069,6 +1103,16 @@ int mlt_property_interpolate( mlt_property self, mlt_property p[], return error; } +/** Create a new animation or refresh an existing one. + * + * \private \memberof mlt_property_s + * \param self a property + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param length the maximum number of frames when interpreting negative keyframe times, + * <=0 if you don't care or need that + */ + static void refresh_animation( mlt_property self, double fps, locale_t locale, int length ) { if ( !self->animation ) @@ -1081,9 +1125,11 @@ static void refresh_animation( mlt_property self, double fps, locale_t locale, i else { mlt_animation_set_length( self->animation, length ); + pthread_mutex_lock( &self->mutex ); self->types |= mlt_prop_data; self->data = self->animation; self->serialiser = (mlt_serialiser) mlt_animation_serialize; + pthread_mutex_unlock( &self->mutex ); } } else if ( self->prop_string ) @@ -1092,8 +1138,21 @@ static void refresh_animation( mlt_property self, double fps, locale_t locale, i } } +/** Get the real number at a frame position. + * + * \public \memberof mlt_property_s + * \param self a property + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param position the frame number + * \param length the maximum number of frames when interpreting negative keyframe times, + * <=0 if you don't care or need that + * \return the real number + */ + double mlt_property_anim_get_double( mlt_property self, double fps, locale_t locale, int position, int length ) { + pthread_mutex_lock( &self->mutex ); double result; if ( self->animation || ( ( self->types & mlt_prop_string ) && self->prop_string ) ) { @@ -1110,11 +1169,25 @@ double mlt_property_anim_get_double( mlt_property self, double fps, locale_t loc { result = mlt_property_get_double( self, fps, locale ); } + pthread_mutex_unlock( &self->mutex ); return result; } +/** Get the property as an integer number at a frame position. + * + * \public \memberof mlt_property_s + * \param self a property + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param position the frame number + * \param length the maximum number of frames when interpreting negative keyframe times, + * <=0 if you don't care or need that + * \return an integer value + */ + int mlt_property_anim_get_int( mlt_property self, double fps, locale_t locale, int position, int length ) { + pthread_mutex_lock( &self->mutex ); int result; if ( self->animation || ( ( self->types & mlt_prop_string ) && self->prop_string ) ) { @@ -1131,11 +1204,25 @@ int mlt_property_anim_get_int( mlt_property self, double fps, locale_t locale, i { result = mlt_property_get_int( self, fps, locale ); } + pthread_mutex_unlock( &self->mutex ); return result; } +/** Get the string at certain a frame position. + * + * \public \memberof mlt_property_s + * \param self a property + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param position the frame number + * \param length the maximum number of frames when interpreting negative keyframe times, + * <=0 if you don't care or need that + * \return the string representation of the property or NULL if failed + */ + char* mlt_property_anim_get_string( mlt_property self, double fps, locale_t locale, int position, int length ) { + pthread_mutex_lock( &self->mutex ); char *result; if ( self->animation || ( ( self->types & mlt_prop_string ) && self->prop_string ) ) { @@ -1146,14 +1233,12 @@ char* mlt_property_anim_get_string( mlt_property self, double fps, locale_t loca 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 ); @@ -1162,6 +1247,7 @@ char* mlt_property_anim_get_string( mlt_property self, double fps, locale_t loca { result = mlt_property_get_string_l( self, locale ); } + pthread_mutex_unlock( &self->mutex ); return result; } @@ -1170,11 +1256,17 @@ char* mlt_property_anim_get_string( mlt_property self, double fps, locale_t loca * \public \memberof mlt_property_s * \param self a property * \param value a double precision floating point value + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param position the frame number + * \param length the maximum number of frames when interpreting negative keyframe times, + * <=0 if you don't care or need that + * \param keyframe_type the interpolation method for this keyframe * \return false if successful, true to indicate error */ int mlt_property_anim_set_double( mlt_property self, double value, double fps, locale_t locale, - mlt_keyframe_type keyframe_type, int position, int length ) + int position, int length, mlt_keyframe_type keyframe_type ) { int result; struct mlt_animation_item_s item; @@ -1196,12 +1288,18 @@ int mlt_property_anim_set_double( mlt_property self, double value, double fps, l * * \public \memberof mlt_property_s * \param self a property - * \param value a double precision floating point value + * \param value an integer + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param position the frame number + * \param length the maximum number of frames when interpreting negative keyframe times, + * <=0 if you don't care or need that + * \param keyframe_type the interpolation method for this keyframe * \return false if successful, true to indicate error */ int mlt_property_anim_set_int( mlt_property self, int value, double fps, locale_t locale, - mlt_keyframe_type keyframe_type, int position, int length ) + int position, int length, mlt_keyframe_type keyframe_type ) { int result; struct mlt_animation_item_s item; @@ -1219,6 +1317,22 @@ int mlt_property_anim_set_int( mlt_property self, int value, double fps, locale_ return result; } +/** Set a property animation keyframe to a string. + * + * Strings only support discrete animation. Do not use this to set a property's + * animation string that contains a semicolon-delimited set of values; use + * mlt_property_set() for that. + * \public \memberof mlt_property_s + * \param self a property + * \param value a string + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param position the frame number + * \param length the maximum number of frames when interpreting negative keyframe times, + * <=0 if you don't care or need that + * \return false if successful, true to indicate error + */ + int mlt_property_anim_set_string( mlt_property self, const char *value, double fps, locale_t locale, int position, int length ) { int result; @@ -1237,6 +1351,31 @@ int mlt_property_anim_set_string( mlt_property self, const char *value, double f return result; } +/** Get an object's animation object. + * + * You might need to call another mlt_property_anim_ function to actually construct + * the animation, as this is a simple accessor function. + * \public \memberof mlt_property_s + * \param self a property + * \return the animation object or NULL if there is no animation + */ + +mlt_animation mlt_property_get_animation( mlt_property self ) +{ + return self->animation; +} + +/** Convert a rectangle value into a string. + * + * Unlike the deprecated mlt_geometry API, the canonical form of a mlt_rect + * is a space delimited "x y w h o" even though many kinds of field delimiters + * may be used to convert a string to a rectangle. + * \private \memberof mlt_property_s + * \param rect the rectangle to convert + * \param length not used + * \return the string representation of a rectangle + */ + static char* serialise_mlt_rect( mlt_rect *rect, int length ) { char* result = calloc( 1, 100 ); @@ -1257,7 +1396,7 @@ static char* serialise_mlt_rect( mlt_rect *rect, int length ) * * \public \memberof mlt_property_s * \param self a property - * \param value a mlt_rect + * \param value a rectangle * \return false */ @@ -1275,12 +1414,14 @@ int mlt_property_set_rect( mlt_property self, mlt_rect value ) return 0; } -/** Get the property as a floating point. +/** Get the property as a rectangle. * + * You can use any non-numeric character(s) as a field delimiter. + * If the number has a '%' immediately following it, the number is divided by + * 100 to convert it into a real number. * \public \memberof mlt_property_s * \param self a property - * \param fps frames per second, used when converting from time value - * \param locale the locale to use for this conversion + * \param locale the locale to use for when converting from a string * \return a rectangle value */ @@ -1309,8 +1450,8 @@ mlt_rect mlt_property_get_rect( mlt_property self, locale_t locale ) #if defined(__GLIBC__) || defined(__DARWIN__) if ( locale ) temp = strtod_l( value, &p, locale ); + else #endif - else temp = strtod( value, &p ); if ( p != value ) { @@ -1342,11 +1483,17 @@ mlt_rect mlt_property_get_rect( mlt_property self, locale_t locale ) * \public \memberof mlt_property_s * \param self a property * \param value a rectangle + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param position the frame number + * \param length the maximum number of frames when interpreting negative keyframe times, + * <=0 if you don't care or need that + * \param keyframe_type the interpolation method for this keyframe * \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, - mlt_keyframe_type keyframe_type, int position, int length ) + int position, int length, mlt_keyframe_type keyframe_type ) { int result; struct mlt_animation_item_s item; @@ -1364,8 +1511,21 @@ int mlt_property_anim_set_rect( mlt_property self, mlt_rect value, double fps, l return result; } +/** Get a rectangle at a frame position. + * + * \public \memberof mlt_property_s + * \param self a property + * \param fps the frame rate, which may be needed for converting a time string to frame units + * \param locale the locale, which may be needed for converting a string to a real number + * \param position the frame number + * \param length the maximum number of frames when interpreting negative keyframe times, + * <=0 if you don't care or need that + * \return the rectangle + */ + mlt_rect mlt_property_anim_get_rect( mlt_property self, double fps, locale_t locale, int position, int length ) { + pthread_mutex_lock( &self->mutex ); mlt_rect result; if ( self->animation || ( ( self->types & mlt_prop_string ) && self->prop_string ) ) { @@ -1383,5 +1543,6 @@ mlt_rect mlt_property_anim_get_rect( mlt_property self, double fps, locale_t loc { result = mlt_property_get_rect( self, locale ); } + pthread_mutex_unlock( &self->mutex ); return result; }