From 9e5de764d2019378ab3cd1053260adeea534129f Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Mon, 11 Jun 2018 13:21:18 -0700 Subject: [PATCH] Add functions to serialize animation with a time format. This also includes functions to clear a property (set it to zero and null values), which is important for reconstructing an animation by API. mlt_animation_serialize_cut_tf() mlt_animation_serialize_tf() mlt_property_clear() mlt_property_get_string_tf() mlt_property_get_string_l_tf() mlt_properties_clear() mlt_properties_get_value_tf() Mlt::Properties::get(int, mlt_time_format) Mlt::Properties::clear() Mlt::Animation::serialize_cut(mlt_time_format, int, int) --- src/framework/mlt.vers | 11 +++ src/framework/mlt_animation.c | 63 +++++++++++++-- src/framework/mlt_animation.h | 13 ++++ src/framework/mlt_properties.c | 44 ++++++++++- src/framework/mlt_properties.h | 2 + src/framework/mlt_property.c | 77 ++++++++++++++----- src/framework/mlt_property.h | 3 + src/mlt++/MltAnimation.cpp | 8 +- src/mlt++/MltAnimation.h | 2 +- src/mlt++/MltProperties.cpp | 13 +++- src/mlt++/MltProperties.h | 6 +- src/mlt++/mlt++.vers | 9 +++ src/tests/common.pri | 10 ++- src/tests/test_animation/test_animation.cpp | 45 +++++++++++ src/tests/test_properties/test_properties.cpp | 23 +++++- 15 files changed, 287 insertions(+), 42 deletions(-) diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index 18c0fb1b8..6e490d441 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -512,3 +512,14 @@ MLT_6.8.0 { mlt_animation_key_set_type; mlt_animation_key_set_frame; } MLT_6.6.0; + +MLT_6.10.0 { + global: + mlt_animation_serialize_cut_tf; + mlt_animation_serialize_tf; + mlt_property_clear; + mlt_property_get_string_tf; + mlt_property_get_string_l_tf; + mlt_properties_clear; + mlt_properties_get_value_tf; +} MLT_6.8.0; diff --git a/src/framework/mlt_animation.c b/src/framework/mlt_animation.c index efc0574f9..172d07569 100644 --- a/src/framework/mlt_animation.c +++ b/src/framework/mlt_animation.c @@ -23,6 +23,8 @@ #include "mlt_animation.h" #include "mlt_tokeniser.h" #include "mlt_profile.h" +#include "mlt_factory.h" +#include "mlt_properties.h" #include #include @@ -585,22 +587,24 @@ int mlt_animation_prev_key( mlt_animation self, mlt_animation_item item, int pos return ( node == NULL ); } -/** Serialize a cut of the animation. +/** Serialize a cut of the animation (with time format). * * The caller is responsible for free-ing the returned string. * \public \memberof mlt_animation_s * \param self an animation * \param in the frame at which to start serializing animation nodes * \param out the frame at which to stop serializing nodes + * \param time_format the time format to use for the key frames * \return a string representing the animation */ -char *mlt_animation_serialize_cut( mlt_animation self, int in, int out ) +char *mlt_animation_serialize_cut_tf( mlt_animation self, int in, int out, mlt_time_format time_format ) { struct mlt_animation_item_s item; char *ret = calloc( 1, 1000 ); size_t used = 0; size_t size = 1000; + mlt_property time_property = mlt_property_init(); item.property = mlt_property_init(); item.frame = item.is_key = 0; @@ -652,8 +656,7 @@ char *mlt_animation_serialize_cut( mlt_animation self, int in, int out ) } // Determine length of string to be appended. - if ( item.frame - in != 0 ) - item_len += 20; + item_len += 100; if ( item.is_key ) item_len += strlen( mlt_property_get_string_l( item.property, self->locale ) ); @@ -685,7 +688,13 @@ char *mlt_animation_serialize_cut( mlt_animation self, int in, int out ) s = ""; break; } - sprintf( ret + used, "%d%s=", item.frame - in, s ); + if ( time_property && self->fps > 0.0 ) { + mlt_property_set_int( time_property, item.frame - in ); + const char *time = mlt_property_get_time( time_property, time_format, self->fps, self->locale ); + sprintf( ret + used, "%s%s=", time, s ); + } else { + sprintf( ret + used, "%d%s=", item.frame - in, s ); + } // Append item value. if ( item.is_key ) @@ -696,21 +705,45 @@ char *mlt_animation_serialize_cut( mlt_animation self, int in, int out ) } } mlt_property_close( item.property ); + mlt_property_close( time_property ); return ret; } -/** Serialize the animation. +static mlt_time_format default_time_format() +{ + const char *e = getenv("MLT_ANIMATION_TIME_FORMAT"); + return e? strtol( e, NULL, 10 ) : mlt_time_frames; +} + +/** Serialize a cut of the animation. * + * This version outputs the key frames' position as a frame number. * The caller is responsible for free-ing the returned string. * \public \memberof mlt_animation_s * \param self an animation + * \param in the frame at which to start serializing animation nodes + * \param out the frame at which to stop serializing nodes * \return a string representing the animation */ -char *mlt_animation_serialize( mlt_animation self ) +char *mlt_animation_serialize_cut( mlt_animation self, int in, int out ) +{ + return mlt_animation_serialize_cut_tf( self, in, out, default_time_format() ); +} + +/** Serialize the animation (with time format). + * + * The caller is responsible for free-ing the returned string. + * \public \memberof mlt_animation_s + * \param self an animation + * \param time_format the time format to use for the key frames + * \return a string representing the animation + */ + +char *mlt_animation_serialize_tf( mlt_animation self, mlt_time_format time_format ) { - char *ret = mlt_animation_serialize_cut( self, -1, -1 ); + char *ret = mlt_animation_serialize_cut_tf( self, -1, -1, time_format ); if ( self && ret ) { free( self->data ); @@ -720,6 +753,20 @@ char *mlt_animation_serialize( mlt_animation self ) return ret; } +/** Serialize the animation. + * + * This version outputs the key frames' position as a frame number. + * The caller is responsible for free-ing the returned string. + * \public \memberof mlt_animation_s + * \param self an animation + * \return a string representing the animation + */ + +char *mlt_animation_serialize( mlt_animation self ) +{ + return mlt_animation_serialize_tf( self, default_time_format() ); +} + /** Get the number of keyframes. * * \public \memberof mlt_animation_s diff --git a/src/framework/mlt_animation.h b/src/framework/mlt_animation.h index c0f0f819b..48d478ce6 100644 --- a/src/framework/mlt_animation.h +++ b/src/framework/mlt_animation.h @@ -26,6 +26,17 @@ #include "mlt_types.h" #include "mlt_property.h" +/** \brief Animation class + * + * Once an animation has been constructed using mlt_properties_s, this interface + * provides a to query and manipulate the animation except for values. One must + * use mlt_properties_s still to get, set, and change values. + * + * \envvar \em MLT_ANIMATION_TIME_FORMAT the time value string format to use, + * defaults to mlt_time_frames. Use the numeric value of mlt_time_format as + * the value of this variable. + */ + /** \brief An animation item that represents a keyframe-property combination. */ struct mlt_animation_item_s @@ -49,7 +60,9 @@ extern int mlt_animation_remove( mlt_animation self, int position ); extern void mlt_animation_interpolate( mlt_animation self ); extern int mlt_animation_next_key( mlt_animation self, mlt_animation_item item, int position ); extern int mlt_animation_prev_key( mlt_animation self, mlt_animation_item item, int position ); +extern char *mlt_animation_serialize_cut_tf( mlt_animation self, int in, int out, mlt_time_format ); extern char *mlt_animation_serialize_cut( mlt_animation self, int in, int out ); +extern char *mlt_animation_serialize_tf( mlt_animation self, mlt_time_format ); extern char *mlt_animation_serialize( mlt_animation self ); extern int mlt_animation_key_count( mlt_animation self ); extern int mlt_animation_key_get( mlt_animation self, mlt_animation_item item, int index ); diff --git a/src/framework/mlt_properties.c b/src/framework/mlt_properties.c index efe9650f0..7ee3e1be2 100644 --- a/src/framework/mlt_properties.c +++ b/src/framework/mlt_properties.c @@ -812,24 +812,39 @@ char *mlt_properties_get_name( mlt_properties self, int index ) return NULL; } -/** Get a property's string value by index. +/** Get a property's string value by index (with time format). * * Do not free the returned string. * \public \memberof mlt_properties_s * \param self a properties list * \param index the numeric index of the property + * \param time_format the time format to use for animation * \return the property value as a string or NULL if the index is out of range */ -char *mlt_properties_get_value( mlt_properties self, int index ) +char *mlt_properties_get_value_tf( mlt_properties self, int index, mlt_time_format time_format ) { if ( !self ) return NULL; property_list *list = self->local; if ( index >= 0 && index < list->count ) - return mlt_property_get_string_l( list->value[ index ], list->locale ); + return mlt_property_get_string_l_tf( list->value[ index ], list->locale, time_format ); return NULL; } +/** Get a property's string value by index. + * + * Do not free the returned string. + * \public \memberof mlt_properties_s + * \param self a properties list + * \param index the numeric index of the property + * \return the property value as a string or NULL if the index is out of range + */ + +char *mlt_properties_get_value( mlt_properties self, int index ) +{ + return mlt_properties_get_value_tf( self, index, mlt_time_frames ); +} + /** Get a data value by index. * * Do not free the returned pointer if you supplied a destructor function when you @@ -2125,6 +2140,29 @@ void mlt_properties_unlock( mlt_properties self ) pthread_mutex_unlock( &( ( property_list* )( self->local ) )->mutex ); } +/** Remove the value for a property. + * + * This initializes the value to zero and removes any string, data, or animation. + * This is especially useful when you want to reset an animation. + * \public \memberof mlt_properties_s + * \param self a properties list + * \param name the name of the property to clear + */ + +void mlt_properties_clear( mlt_properties self, const char *name ) +{ + if ( !self || !name ) return; + + // Fetch the property to work with + mlt_property property = mlt_properties_fetch( self, name ); + + // Set it if not NULL + if ( property ) + mlt_property_clear( property ); + + mlt_events_fire( self, "property-changed", name, NULL ); +} + /** Get a time string associated to the name. * * Do not free the returned string. It's lifetime is controlled by the property. diff --git a/src/framework/mlt_properties.h b/src/framework/mlt_properties.h index 094a8ca63..ba4764d3f 100644 --- a/src/framework/mlt_properties.h +++ b/src/framework/mlt_properties.h @@ -62,6 +62,7 @@ extern int mlt_properties_set_or_default( mlt_properties self, const char *name, extern int mlt_properties_parse( mlt_properties self, const char *namevalue ); extern char *mlt_properties_get( mlt_properties self, const char *name ); extern char *mlt_properties_get_name( mlt_properties self, int index ); +extern char *mlt_properties_get_value_tf( mlt_properties self, int index, mlt_time_format ); extern char *mlt_properties_get_value( mlt_properties self, int index ); extern void *mlt_properties_get_data_at( mlt_properties self, int index, int *size ); extern int mlt_properties_get_int( mlt_properties self, const char *name ); @@ -86,6 +87,7 @@ extern mlt_properties mlt_properties_parse_yaml( const char *file ); extern char *mlt_properties_serialise_yaml( mlt_properties self ); extern void mlt_properties_lock( mlt_properties self ); extern void mlt_properties_unlock( mlt_properties self ); +extern void mlt_properties_clear( mlt_properties self, const char *name ); extern char *mlt_properties_get_time( mlt_properties, const char* name, mlt_time_format ); extern char *mlt_properties_frames_to_time( mlt_properties, mlt_position, mlt_time_format ); diff --git a/src/framework/mlt_property.c b/src/framework/mlt_property.c index 5f2966b7a..4dc8a192b 100644 --- a/src/framework/mlt_property.c +++ b/src/framework/mlt_property.c @@ -98,11 +98,11 @@ mlt_property mlt_property_init( ) /** Clear (0/null) a property. * * Frees up any associated resources in the process. - * \private \memberof mlt_property_s + * \public \memberof mlt_property_s * \param self a property */ -static inline void mlt_property_clear( mlt_property self ) +void mlt_property_clear( mlt_property self ) { // Special case data handling if ( self->types & mlt_prop_data && self->destructor != NULL ) @@ -619,7 +619,7 @@ int64_t mlt_property_get_int64( mlt_property self ) return 0; } -/** Get the property as a string. +/** Get the property as a string (with time format). * * The caller is not responsible for deallocating the returned string! * The string is deallocated when the Property is closed. @@ -627,10 +627,11 @@ int64_t mlt_property_get_int64( mlt_property self ) * a serialization function for binary data, if supplied. * \public \memberof mlt_property_s * \param self a property + * \param time_format the time format to use for animation * \return a string representation of the property or NULL if failed */ -char *mlt_property_get_string( mlt_property self ) +char *mlt_property_get_string_tf( mlt_property self, mlt_time_format time_format ) { // Construct a string if need be pthread_mutex_lock( &self->mutex ); @@ -638,7 +639,7 @@ char *mlt_property_get_string( mlt_property self ) { if ( self->prop_string ) free( self->prop_string ); - self->prop_string = self->serialiser( self->data, self->length ); + self->prop_string = self->serialiser( self->data, time_format ); } else if ( ! ( self->types & mlt_prop_string ) ) { @@ -678,7 +679,29 @@ char *mlt_property_get_string( mlt_property self ) return self->prop_string; } -/** Get the property as a string (with locale). +static mlt_time_format default_time_format() +{ + const char *e = getenv("MLT_ANIMATION_TIME_FORMAT"); + return e? strtol( e, NULL, 10 ) : mlt_time_frames; +} + +/** Get the property as a string. + * + * The caller is not responsible for deallocating the returned string! + * The string is deallocated when the Property is closed. + * This tries its hardest to convert the property to string including using + * a serialization function for binary data, if supplied. + * \public \memberof mlt_property_s + * \param self a property + * \return a string representation of the property or NULL if failed + */ + +char *mlt_property_get_string( mlt_property self ) +{ + return mlt_property_get_string_tf( self, default_time_format() ); +} + +/** Get the property as a string (with locale and time format). * * The caller is not responsible for deallocating the returned string! * The string is deallocated when the Property is closed. @@ -687,14 +710,15 @@ char *mlt_property_get_string( mlt_property self ) * \public \memberof mlt_property_s * \param self a property * \param locale the locale to use for this conversion + * \param time_format the time format to use for animation * \return a string representation of the property or NULL if failed */ -char *mlt_property_get_string_l( mlt_property self, locale_t locale ) +char *mlt_property_get_string_l_tf( mlt_property self, locale_t locale, mlt_time_format time_format ) { // Optimization for no locale if ( !locale ) - return mlt_property_get_string( self ); + return mlt_property_get_string_tf( self, time_format ); // Construct a string if need be pthread_mutex_lock( &self->mutex ); @@ -702,7 +726,7 @@ char *mlt_property_get_string_l( mlt_property self, locale_t locale ) { if ( self->prop_string ) free( self->prop_string ); - self->prop_string = self->serialiser( self->data, self->length ); + self->prop_string = self->serialiser( self->data, time_format ); } else if ( ! ( self->types & mlt_prop_string ) ) { @@ -764,6 +788,23 @@ char *mlt_property_get_string_l( mlt_property self, locale_t locale ) return self->prop_string; } +/** Get the property as a string (with locale). + * + * The caller is not responsible for deallocating the returned string! + * The string is deallocated when the Property is closed. + * This tries its hardest to convert the property to string including using + * a serialization function for binary data, if supplied. + * \public \memberof mlt_property_s + * \param self a property + * \param locale the locale to use for this conversion + * \return a string representation of the property or NULL if failed + */ + +char *mlt_property_get_string_l( mlt_property self, locale_t locale ) +{ + return mlt_property_get_string_l_tf( self, locale, default_time_format() ); +} + /** Get the binary data from a property. * * This only works if you previously put binary data into the property. @@ -840,7 +881,12 @@ void mlt_property_pass( mlt_property self, mlt_property that ) self->destructor = free; self->serialiser = that->serialiser; } - else if ( self->types & mlt_prop_data && that->serialiser != NULL ) + else if ( that->animation && that->serialiser ) + { + self->types = mlt_prop_string; + self->prop_string = that->serialiser( that->animation, default_time_format() ); + } + else if ( that->types & mlt_prop_data && that->serialiser ) { self->types = mlt_prop_string; self->prop_string = that->serialiser( that->data, that->length ); @@ -1215,15 +1261,8 @@ static void refresh_animation( mlt_property self, double fps, locale_t locale, i self->animation = mlt_animation_new(); self->types |= mlt_prop_data; self->data = self->animation; - self->serialiser = (mlt_serialiser) mlt_animation_serialize; - if ( self->prop_string ) - { - mlt_animation_parse( self->animation, self->prop_string, length, fps, locale ); - } - else - { - mlt_animation_set_length( self->animation, length ); - } + self->serialiser = (mlt_serialiser) mlt_animation_serialize_tf; + mlt_animation_parse( self->animation, self->prop_string, length, fps, locale ); } else if ( ( self->types & mlt_prop_string ) && self->prop_string ) { diff --git a/src/framework/mlt_property.h b/src/framework/mlt_property.h index 427faa463..32a2f97ab 100644 --- a/src/framework/mlt_property.h +++ b/src/framework/mlt_property.h @@ -39,6 +39,7 @@ typedef char* locale_t; #endif extern mlt_property mlt_property_init( ); +extern void mlt_property_clear( mlt_property self ); extern int mlt_property_set_int( mlt_property self, int value ); extern int mlt_property_set_double( mlt_property self, double value ); extern int mlt_property_set_position( mlt_property self, mlt_position value ); @@ -49,7 +50,9 @@ extern int mlt_property_get_int( mlt_property self, double fps, locale_t ); extern double mlt_property_get_double( mlt_property self, double fps, locale_t ); extern mlt_position mlt_property_get_position( mlt_property self, double fps, locale_t ); extern int64_t mlt_property_get_int64( mlt_property self ); +extern char *mlt_property_get_string_tf( mlt_property self, mlt_time_format ); extern char *mlt_property_get_string( mlt_property self ); +extern char *mlt_property_get_string_l_tf( mlt_property self, locale_t, mlt_time_format ); extern char *mlt_property_get_string_l( mlt_property self, locale_t ); extern void *mlt_property_get_data( mlt_property self, int *length ); extern void mlt_property_close( mlt_property self ); diff --git a/src/mlt++/MltAnimation.cpp b/src/mlt++/MltAnimation.cpp index 25c27d6ea..d11e97e67 100644 --- a/src/mlt++/MltAnimation.cpp +++ b/src/mlt++/MltAnimation.cpp @@ -1,7 +1,6 @@ /** * MltAnimation.cpp - MLT Wrapper - * Copyright (C) 2015 Meltytech, LLC - * Author: Dan Dennedy + * Copyright (C) 2015-2018 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -194,3 +193,8 @@ char *Animation::serialize_cut( int in, int out ) { return mlt_animation_serialize_cut( instance, in, out ); } + +char *Animation::serialize_cut( mlt_time_format format , int in, int out ) +{ + return mlt_animation_serialize_cut_tf( instance, in, out, format ); +} diff --git a/src/mlt++/MltAnimation.h b/src/mlt++/MltAnimation.h index 7837295b9..e989ceaba 100644 --- a/src/mlt++/MltAnimation.h +++ b/src/mlt++/MltAnimation.h @@ -1,7 +1,6 @@ /** * MltAnimation.h - MLT Wrapper * Copyright (C) 2015-2018 Meltytech, LLC - * 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 @@ -58,6 +57,7 @@ namespace Mlt int remove( int position ); void interpolate(); char* serialize_cut( int in = -1, int out = -1 ); + char* serialize_cut( mlt_time_format format, int in = -1, int out = -1 ); }; } diff --git a/src/mlt++/MltProperties.cpp b/src/mlt++/MltProperties.cpp index 010d9feb7..2ae3f1e23 100644 --- a/src/mlt++/MltProperties.cpp +++ b/src/mlt++/MltProperties.cpp @@ -1,7 +1,6 @@ /** * MltProperties.cpp - MLT Wrapper - * Copyright (C) 2004-2015 Meltytech, LLC - * Author: Charles Yates + * Copyright (C) 2004-2018 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -203,6 +202,11 @@ char *Properties::get( int index ) return mlt_properties_get_value( get_properties( ), index ); } +char *Properties::get( int index , mlt_time_format format ) +{ + return mlt_properties_get_value_tf( get_properties( ), index, format ); +} + void *Properties::get_data( int index, int &size ) { return mlt_properties_get_data_at( get_properties( ), index, &size ); @@ -318,6 +322,11 @@ const char *Properties::get_lcnumeric( ) return mlt_properties_get_lcnumeric( get_properties() ); } +void Properties::clear( const char *name ) +{ + return mlt_properties_clear( get_properties(), name ); +} + char *Properties::get_time( const char *name, mlt_time_format format ) { return mlt_properties_get_time( get_properties(), name, format ); diff --git a/src/mlt++/MltProperties.h b/src/mlt++/MltProperties.h index b1b4e84b2..8a786b922 100644 --- a/src/mlt++/MltProperties.h +++ b/src/mlt++/MltProperties.h @@ -1,7 +1,6 @@ /** * MltProperties.h - MLT Wrapper - * Copyright (C) 2004-2015 Meltytech, LLC - * Author: Charles Yates + * Copyright (C) 2004-2018 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -74,6 +73,7 @@ namespace Mlt int parse( const char *namevalue ); char *get_name( int index ); char *get( int index ); + char *get( int index, mlt_time_format ); void *get_data( int index, int &size ); void mirror( Properties &that ); int inherit( Properties &that ); @@ -97,6 +97,8 @@ namespace Mlt int preset( const char *name ); int set_lcnumeric( const char *locale ); const char *get_lcnumeric( ); + void clear( const char *name ); + char *get_time( const char *name, mlt_time_format = mlt_time_smpte_df ); char *frames_to_time( int, mlt_time_format = mlt_time_smpte_df ); int time_to_frames( const char* time ); diff --git a/src/mlt++/mlt++.vers b/src/mlt++/mlt++.vers index 602fa895c..0c06738b3 100644 --- a/src/mlt++/mlt++.vers +++ b/src/mlt++/mlt++.vers @@ -537,3 +537,12 @@ MLTPP_6.8.0 { "Mlt::Animation::key_set_frame(int, int)"; }; } MLTPP_6.6.0; + +MLTPP_6.10.0 { + global: + extern "C++" { + "Mlt::Properties::get(int, mlt_time_format)"; + "Mlt::Properties::clear(char const*)"; + "Mlt::Animation::serialize_cut(mlt_time_format, int, int)"; + }; +} MLTPP_6.8.0; diff --git a/src/tests/common.pri b/src/tests/common.pri index 85e978da8..b9848e442 100644 --- a/src/tests/common.pri +++ b/src/tests/common.pri @@ -8,8 +8,14 @@ TEMPLATE = app DEFINES += SRCDIR=\\\"$$PWD/\\\" win32 { - INCLUDEPATH += include/mlt++ include/mlt - LIBS += -Llib -lmlt++ -lmlt + INCLUDEPATH += $$PWD/.. + LIBS += -L$$PWD/../framework -L$$PWD/../mlt++ -lmlt++ -lmlt + isEmpty(PREFIX) { + message("Install PREFIX not set; using C:\\Projects\\Shotcut. You can change this with 'qmake PREFIX=...'") + PREFIX = C:\\Projects\\Shotcut + } + target.path = $$PREFIX + INSTALLS += target } else { CONFIG += link_pkgconfig PKGCONFIG += mlt++ diff --git a/src/tests/test_animation/test_animation.cpp b/src/tests/test_animation/test_animation.cpp index 71b102b11..d07727f7c 100644 --- a/src/tests/test_animation/test_animation.cpp +++ b/src/tests/test_animation/test_animation.cpp @@ -293,6 +293,51 @@ private Q_SLOTS: QCOMPARE(a.keyframe_type(1), mlt_keyframe_linear); QCOMPARE(a.keyframe_type(2), mlt_keyframe_linear); } + + void SerializesInTimeFormat() + { + Profile profile; + Properties p; + p.set("_profile", profile.get_profile(), 0); + p.set("foo", "50=100; 60=60; 100=0"); + // Cause the string to be interpreted as animated value. + p.anim_get("foo", 0); + Animation a = p.get_animation("foo"); + QVERIFY(a.is_valid()); + QCOMPARE(a.serialize_cut(mlt_time_clock), "00:00:02.000=100;00:00:02.400=60;00:00:04.000=0"); + QCOMPARE(a.serialize_cut(mlt_time_smpte_ndf), "00:00:02:00=100;00:00:02:10=60;00:00:04:00=0"); + } + + void GetPropertyInTimeFormat() + { + Profile profile; + Properties p; + p.set("_profile", profile.get_profile(), 0); + p.set("foo", "50=100; 60=60; 100=0"); + // Cause the string to be interpreted as animated value. + p.anim_get_int("foo", 0); + Animation a = p.get_animation("foo"); + QVERIFY(a.is_valid()); + for (int i = 0; i < p.count(); i++) { + if (!qstrcmp(p.get_name(i), "foo")) { + QCOMPARE(p.get(i, mlt_time_clock), "00:00:02.000=100;00:00:02.400=60;00:00:04.000=0"); + QCOMPARE(p.get(i, mlt_time_smpte_ndf), "00:00:02:00=100;00:00:02:10=60;00:00:04:00=0"); + break; + } + } + } + + void AnimationClears() + { + Properties p; + p.set("foo", "50=100; 60=60; 100=0"); + // Cause the string to be interpreted as animated value. + p.anim_get_int("foo", 0); + Animation a = p.get_animation("foo"); + QVERIFY(a.is_valid()); + p.clear("foo"); + QCOMPARE(p.get_animation("foo"), mlt_animation(0)); + } }; QTEST_APPLESS_MAIN(TestAnimation) diff --git a/src/tests/test_properties/test_properties.cpp b/src/tests/test_properties/test_properties.cpp index 5f504f6b1..f399ab578 100644 --- a/src/tests/test_properties/test_properties.cpp +++ b/src/tests/test_properties/test_properties.cpp @@ -30,7 +30,7 @@ extern "C" { } #include -static const bool kRunLongTests = false; +static const bool kRunLongTests = true; class TestProperties: public QObject { @@ -39,14 +39,16 @@ class TestProperties: public QObject public: TestProperties() { -#if defined(__linux__) || defined(__APPLE__) +#if !defined(_WIN32) && (defined(__GLIBC__) || defined(__APPLE__)) locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL ); +#else + locale = 0; #endif Factory::init(); } ~TestProperties() { -#if defined(__linux__) || defined(__APPLE__) +#if !defined(_WIN32) && (defined(__GLIBC__) || defined(__APPLE__)) freelocale(locale); #endif } @@ -453,9 +455,11 @@ private Q_SLOTS: p.set_lcnumeric("en_US"); p.set("key", "0.125"); QCOMPARE(p.get_double("key"), double(1) / double(8)); +#if !defined(_WIN32) p.set_lcnumeric("de_DE"); p.set("key", "0,125"); QCOMPARE(p.get_double("key"), double(1) / double(8)); +#endif } void AnimationInsert() @@ -1077,6 +1081,19 @@ private Q_SLOTS: p.set("key", "0=100; -1:=200"); QCOMPARE(p.anim_get_int("key", 75, 125), 175); } + + void PropertyClears() + { + Properties p; + p.set("key", 1); + QCOMPARE(p.get_int("key"), 1); + QCOMPARE(p.get("key"), "1"); + p.clear("key"); + QCOMPARE(p.get("key"), (char*) 0); + QCOMPARE(p.get_data("key"), (void*) 0); + QCOMPARE(p.get_animation("key"), mlt_animation(0)); + QCOMPARE(p.get_int("key"), 0); + } }; QTEST_APPLESS_MAIN(TestProperties)