+
+/** Convert a frame count to a time string.
+ *
+ * Do not free the returned string. It's lifetime is controlled by the property.
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param frames the frame count to convert
+ * \param format the time format that you want
+ * \return the time string or NULL if error, e.g. there is no profile
+ */
+
+char *mlt_properties_frames_to_time( mlt_properties self, mlt_position frames, mlt_time_format format )
+{
+ const char *name = "_mlt_properties_time";
+ mlt_properties_set_position( self, name, frames );
+ return mlt_properties_get_time( self, name, format );
+}
+
+/** Convert a time string to a frame count.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param time the time string to convert
+ * \return a frame count or a negative value if error, e.g. there is no profile
+ */
+
+mlt_position mlt_properties_time_to_frames( mlt_properties self, const char *time )
+{
+ const char *name = "_mlt_properties_time";
+ mlt_properties_set( self, name, time );
+ return mlt_properties_get_position( self, name );
+}
+
+/** Convert a numeric property to a tuple of color components.
+ *
+ * If the property's string is red, green, blue, white, or black, then it
+ * is converted to the corresponding opaque color tuple. Otherwise, the property
+ * is fetched as an integer and then converted.
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \return a color structure
+ */
+
+mlt_color mlt_properties_get_color( mlt_properties self, const char* name )
+{
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
+ mlt_property value = mlt_properties_find( self, name );
+ mlt_color result = { 0xff, 0xff, 0xff, 0xff };
+ if ( value )
+ {
+ const char *color = mlt_property_get_string_l( value, list->locale );
+ unsigned int color_int = mlt_property_get_int( value, fps, list->locale );
+
+ if ( !strcmp( color, "red" ) )
+ {
+ result.r = 0xff;
+ result.g = 0x00;
+ result.b = 0x00;
+ }
+ else if ( !strcmp( color, "green" ) )
+ {
+ result.r = 0x00;
+ result.g = 0xff;
+ result.b = 0x00;
+ }
+ else if ( !strcmp( color, "blue" ) )
+ {
+ result.r = 0x00;
+ result.g = 0x00;
+ result.b = 0xff;
+ }
+ else if ( !strcmp( color, "black" ) )
+ {
+ result.r = 0x00;
+ result.g = 0x00;
+ result.b = 0x00;
+ }
+ else if ( strcmp( color, "white" ) )
+ {
+ result.r = ( color_int >> 24 ) & 0xff;
+ result.g = ( color_int >> 16 ) & 0xff;
+ result.b = ( color_int >> 8 ) & 0xff;
+ result.a = ( color_int ) & 0xff;
+ }
+ }
+ return result;
+}
+
+/** Set a property to an integer value by color.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to set
+ * \param color the color
+ * \return true if error
+ */
+
+int mlt_properties_set_color( mlt_properties self, const char *name, mlt_color color )
+{
+ int error = 1;
+
+ if ( !self || !name ) return error;
+
+ // Fetch the property to work with
+ mlt_property property = mlt_properties_fetch( self, name );
+
+ // Set it if not NULL
+ if ( property != NULL )
+ {
+ uint32_t value = ( color.r << 24 ) | ( color.g << 16 ) | ( color.b << 8 ) | color.a;
+ error = mlt_property_set_int( property, value );
+ mlt_properties_do_mirror( self, name );
+ }
+
+ mlt_events_fire( self, "property-changed", name, NULL );
+
+ return error;
+}
+
+/** Get a string value by name at a frame position.
+ *
+ * Do not free the returned string. It's lifetime is controlled by the property
+ * and this properties object.
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \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 property's string value or NULL if it does not exist
+ */
+
+char* mlt_properties_anim_get( mlt_properties self, const char *name, int position, int length )
+{
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ mlt_property value = mlt_properties_find( self, name );
+ property_list *list = self->local;
+ return value == NULL ? NULL : mlt_property_anim_get_string( value, fps, list->locale, position, length );
+}
+
+/** Set a property to a string at a frame position.
+ *
+ * The event "property-changed" is fired after the property has been set.
+ *
+ * This makes a copy of the string value you supply.
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to set
+ * \param value the property's new value
+ * \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 true if error
+ */
+
+int mlt_properties_anim_set( mlt_properties self, const char *name, const char *value, int position, int length )
+{
+ int error = 1;
+
+ if ( !self || !name ) return error;
+
+ // Fetch the property to work with
+ mlt_property property = mlt_properties_fetch( self, name );
+
+ // Set it if not NULL
+ if ( property )
+ {
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
+ error = mlt_property_anim_set_string( property, value,
+ fps, list->locale, position, length );
+ mlt_properties_do_mirror( self, name );
+ }
+
+ mlt_events_fire( self, "property-changed", name, NULL );
+
+ return error;
+}
+
+/** Get an integer associated to the name at a frame position.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \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 integer value, 0 if not found (which may also be a legitimate value)
+ */
+
+int mlt_properties_anim_get_int( mlt_properties self, const char *name, int position, int length )
+{
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
+ mlt_property value = mlt_properties_find( self, name );
+ return value == NULL ? 0 : mlt_property_anim_get_int( value, fps, list->locale, position, length );
+}
+
+/** Set a property to an integer value at a frame position.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to set
+ * \param value the integer
+ * \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 true if error
+ */
+
+int mlt_properties_anim_set_int( mlt_properties self, const char *name, int value,
+ int position, int length, mlt_keyframe_type keyframe_type )
+{
+ int error = 1;
+
+ if ( !self || !name ) return error;
+
+ // Fetch the property to work with
+ mlt_property property = mlt_properties_fetch( self, name );
+
+ // Set it if not NULL
+ if ( property != NULL )
+ {
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
+ error = mlt_property_anim_set_int( property, value, fps, list->locale, position, length, keyframe_type );
+ mlt_properties_do_mirror( self, name );
+ }
+
+ mlt_events_fire( self, "property-changed", name, NULL );
+
+ return error;
+}
+
+/** Get a real number associated to the name at a frame position.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \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, 0 if not found (which may also be a legitimate value)
+ */
+
+double mlt_properties_anim_get_double( mlt_properties self, const char *name, int position, int length )
+{
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
+ mlt_property value = mlt_properties_find( self, name );
+ return value == NULL ? 0.0 : mlt_property_anim_get_double( value, fps, list->locale, position, length );
+}
+
+/** Set a property to a real number at a frame position.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to set
+ * \param value the 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 true if error
+ */
+
+int mlt_properties_anim_set_double( mlt_properties self, const char *name, double value,
+ int position, int length, mlt_keyframe_type keyframe_type )
+{
+ int error = 1;
+
+ if ( !self || !name ) return error;
+
+ // Fetch the property to work with
+ mlt_property property = mlt_properties_fetch( self, name );
+
+ // Set it if not NULL
+ if ( property != NULL )
+ {
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
+ error = mlt_property_anim_set_double( property, value, fps, list->locale, position, length, keyframe_type );
+ mlt_properties_do_mirror( self, name );
+ }
+
+ mlt_events_fire( self, "property-changed", name, NULL );
+
+ return error;
+}
+
+/** Get the animation associated to the name.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \return The animation object or NULL if the property has no animation
+ */
+
+mlt_animation mlt_properties_get_animation( mlt_properties self, const char *name )
+{
+ mlt_property value = mlt_properties_find( self, name );
+ return value == NULL ? NULL : mlt_property_get_animation( value );
+}
+
+/** Set a property to a rectangle value.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to set
+ * \param value the rectangle
+ * \return true if error
+ */
+
+extern int mlt_properties_set_rect( mlt_properties self, const char *name, mlt_rect value )
+{
+ int error = 1;
+
+ if ( !self || !name ) return error;
+
+ // Fetch the property to work with
+ mlt_property property = mlt_properties_fetch( self, name );
+
+ // Set it if not NULL
+ if ( property != NULL )
+ {
+ error = mlt_property_set_rect( property, value );
+ mlt_properties_do_mirror( self, name );
+ }
+
+ mlt_events_fire( self, "property-changed", name, NULL );
+
+ return error;
+}
+
+/** Get a rectangle associated to the name.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \return the rectangle value, the rectangle fields will be DBL_MIN if not found
+ */
+
+extern mlt_rect mlt_properties_get_rect( mlt_properties self, const char* name )
+{
+ property_list *list = self->local;
+ mlt_property value = mlt_properties_find( self, name );
+ mlt_rect rect = { DBL_MIN, DBL_MIN, DBL_MIN, DBL_MIN, DBL_MIN };
+ return value == NULL ? rect : mlt_property_get_rect( value, list->locale );
+}
+
+/** Set a property to a rectangle value at a frame position.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to set
+ * \param value the rectangle
+ * \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 true if error
+ */
+
+extern int mlt_properties_anim_set_rect( mlt_properties self, const char *name, mlt_rect value,
+ int position, int length , mlt_keyframe_type keyframe_type )
+{
+ int error = 1;
+
+ if ( !self || !name ) return error;
+
+ // Fetch the property to work with
+ mlt_property property = mlt_properties_fetch( self, name );
+
+ // Set it if not NULL
+ if ( property != NULL )
+ {
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
+ error = mlt_property_anim_set_rect( property, value, fps, list->locale, position, length, keyframe_type );
+ mlt_properties_do_mirror( self, name );
+ }
+
+ mlt_events_fire( self, "property-changed", name, NULL );
+
+ return error;
+}
+
+/** Get a rectangle associated to the name at a frame position.
+ *
+ * \public \memberof mlt_properties_s
+ * \param self a properties list
+ * \param name the property to get
+ * \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 value, the rectangle fields will be DBL_MIN if not found
+ */
+
+extern mlt_rect mlt_properties_anim_get_rect( mlt_properties self, const char *name, int position, int length )
+{
+ mlt_profile profile = mlt_properties_get_data( self, "_profile", NULL );
+ double fps = mlt_profile_fps( profile );
+ property_list *list = self->local;
+ mlt_property value = mlt_properties_find( self, name );
+ mlt_rect rect = { DBL_MIN, DBL_MIN, DBL_MIN, DBL_MIN, DBL_MIN };
+ return value == NULL ? rect : mlt_property_anim_get_rect( value, fps, list->locale, position, length );
+}