]> git.sesse.net Git - mlt/blobdiff - src/framework/mlt_property.c
Detect video codecs that use the new libavcodec "encode2" method.
[mlt] / src / framework / mlt_property.c
index 7334e97576d321250dde0c3ee3f8023fe82b24d1..3cc9f8b8bdfc3151916067fb1f11b9c714bdde5e 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+// For strtod_l
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+
 #include "mlt_property.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <locale.h>
+#include <pthread.h>
 
 
 /** Bit pattern used internally to indicated representations available.
@@ -68,6 +75,8 @@ struct mlt_property_s
        int length;
        mlt_destructor destructor;
        mlt_serialiser serialiser;
+
+       pthread_mutex_t mutex;
 };
 
 /** Construct a property and initialize it
@@ -89,6 +98,7 @@ mlt_property mlt_property_init( )
                self->length = 0;
                self->destructor = NULL;
                self->serialiser = NULL;
+               pthread_mutex_init( &self->mutex, NULL );
        }
        return self;
 }
@@ -133,9 +143,11 @@ static inline void mlt_property_clear( mlt_property self )
 
 int mlt_property_set_int( mlt_property self, int value )
 {
+       pthread_mutex_lock( &self->mutex );
        mlt_property_clear( self );
        self->types = mlt_prop_int;
        self->prop_int = value;
+       pthread_mutex_unlock( &self->mutex );
        return 0;
 }
 
@@ -149,9 +161,11 @@ int mlt_property_set_int( mlt_property self, int value )
 
 int mlt_property_set_double( mlt_property self, double value )
 {
+       pthread_mutex_lock( &self->mutex );
        mlt_property_clear( self );
        self->types = mlt_prop_double;
        self->prop_double = value;
+       pthread_mutex_unlock( &self->mutex );
        return 0;
 }
 
@@ -166,9 +180,11 @@ int mlt_property_set_double( mlt_property self, double value )
 
 int mlt_property_set_position( mlt_property self, mlt_position value )
 {
+       pthread_mutex_lock( &self->mutex );
        mlt_property_clear( self );
        self->types = mlt_prop_position;
        self->prop_position = value;
+       pthread_mutex_unlock( &self->mutex );
        return 0;
 }
 
@@ -184,6 +200,7 @@ int mlt_property_set_position( mlt_property self, mlt_position value )
 
 int mlt_property_set_string( mlt_property self, const char *value )
 {
+       pthread_mutex_lock( &self->mutex );
        if ( value != self->prop_string )
        {
                mlt_property_clear( self );
@@ -195,6 +212,7 @@ int mlt_property_set_string( mlt_property self, const char *value )
        {
                self->types = mlt_prop_string;
        }
+       pthread_mutex_unlock( &self->mutex );
        return self->prop_string == NULL;
 }
 
@@ -208,9 +226,11 @@ int mlt_property_set_string( mlt_property self, const char *value )
 
 int mlt_property_set_int64( mlt_property self, int64_t value )
 {
+       pthread_mutex_lock( &self->mutex );
        mlt_property_clear( self );
        self->types = mlt_prop_int64;
        self->prop_int64 = value;
+       pthread_mutex_unlock( &self->mutex );
        return 0;
 }
 
@@ -231,6 +251,7 @@ int mlt_property_set_int64( mlt_property self, int64_t value )
 
 int mlt_property_set_data( mlt_property self, void *value, int length, mlt_destructor destructor, mlt_serialiser serialiser )
 {
+       pthread_mutex_lock( &self->mutex );
        if ( self->data == value )
                self->destructor = NULL;
        mlt_property_clear( self );
@@ -239,6 +260,7 @@ int mlt_property_set_data( mlt_property self, void *value, int length, mlt_destr
        self->length = length;
        self->destructor = destructor;
        self->serialiser = serialiser;
+       pthread_mutex_unlock( &self->mutex );
        return 0;
 }
 
@@ -326,6 +348,33 @@ double mlt_property_get_double( mlt_property self )
        return 0;
 }
 
+/** Get the property (with locale) as a floating point.
+ *
+ * \public \memberof mlt_property_s
+ * \param self a property
+ * \param locale the locale to use for this conversion
+ * \return a floating point value
+ */
+
+double mlt_property_get_double_l( mlt_property self, locale_t locale )
+{
+       if ( self->types & mlt_prop_double )
+               return self->prop_double;
+       else if ( self->types & mlt_prop_int )
+               return ( double )self->prop_int;
+       else if ( self->types & mlt_prop_position )
+               return ( double )self->prop_position;
+       else if ( self->types & mlt_prop_int64 )
+               return ( double )self->prop_int64;
+#if defined(__GLIBC__) || defined(__DARWIN__)
+       else if ( locale && ( self->types & mlt_prop_string ) && self->prop_string )
+               return strtod_l( self->prop_string, NULL, locale );
+#endif
+       else if ( ( self->types & mlt_prop_string ) && self->prop_string )
+               return strtod( self->prop_string, NULL );
+       return 0;
+}
+
 /** Get the property as a position.
  *
  * A position is an offset time in terms of frame units.
@@ -405,6 +454,7 @@ char *mlt_property_get_string( mlt_property self )
        // Construct a string if need be
        if ( ! ( self->types & mlt_prop_string ) )
        {
+               pthread_mutex_lock( &self->mutex );
                if ( self->types & mlt_prop_int )
                {
                        self->types |= mlt_prop_string;
@@ -421,19 +471,99 @@ char *mlt_property_get_string( mlt_property self )
                {
                        self->types |= mlt_prop_string;
                        self->prop_string = malloc( 32 );
-                       sprintf( self->prop_string, "%d", (int)self->prop_position ); /* I don't know if self is wanted. -Zach */
+                       sprintf( self->prop_string, "%d", (int)self->prop_position );
                }
                else if ( self->types & mlt_prop_int64 )
                {
                        self->types |= mlt_prop_string;
                        self->prop_string = malloc( 32 );
-                        sprintf( self->prop_string, "%lld", (long long int)self->prop_int64 );
+                       sprintf( self->prop_string, "%"PRId64, self->prop_int64 );
                }
                else if ( self->types & mlt_prop_data && self->serialiser != NULL )
                {
                        self->types |= mlt_prop_string;
                        self->prop_string = self->serialiser( self->data, self->length );
                }
+               pthread_mutex_unlock( &self->mutex );
+       }
+
+       // Return the string (may be NULL)
+       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 )
+{
+       // Optimization for no locale
+       if ( !locale )
+               return mlt_property_get_string( self );
+
+       // Construct a string if need be
+       if ( ! ( self->types & mlt_prop_string ) )
+       {
+               // TODO: when glibc gets sprintf_l, start using it! For now, hack on setlocale.
+               // Save the current locale
+#if defined(__DARWIN__)
+               const char *localename = querylocale( LC_NUMERIC, locale );
+#elif defined(__GLIBC__)
+               const char *localename = locale->__names[ LC_NUMERIC ];
+#else
+               // TODO: not yet sure what to do on other platforms
+               const char *localename = "";
+#endif
+               // Protect damaging the global locale from a temporary locale on another thread.
+               pthread_mutex_lock( &self->mutex );
+
+               // Get the current locale
+               char *orig_localename = strdup( setlocale( LC_NUMERIC, NULL ) );
+
+               // Set the new locale
+               setlocale( LC_NUMERIC, localename );
+
+               if ( self->types & mlt_prop_int )
+               {
+                       self->types |= mlt_prop_string;
+                       self->prop_string = malloc( 32 );
+                       sprintf( self->prop_string, "%d", self->prop_int );
+               }
+               else if ( self->types & mlt_prop_double )
+               {
+                       self->types |= mlt_prop_string;
+                       self->prop_string = malloc( 32 );
+                       sprintf( self->prop_string, "%f", self->prop_double );
+               }
+               else if ( self->types & mlt_prop_position )
+               {
+                       self->types |= mlt_prop_string;
+                       self->prop_string = malloc( 32 );
+                       sprintf( self->prop_string, "%d", (int)self->prop_position );
+               }
+               else if ( self->types & mlt_prop_int64 )
+               {
+                       self->types |= mlt_prop_string;
+                       self->prop_string = malloc( 32 );
+                       sprintf( self->prop_string, "%"PRId64, self->prop_int64 );
+               }
+               else if ( self->types & mlt_prop_data && self->serialiser != NULL )
+               {
+                       self->types |= mlt_prop_string;
+                       self->prop_string = self->serialiser( self->data, self->length );
+               }
+               // Restore the current locale
+               setlocale( LC_NUMERIC, orig_localename );
+               free( orig_localename );
+               pthread_mutex_unlock( &self->mutex );
        }
 
        // Return the string (may be NULL)
@@ -473,6 +603,7 @@ void *mlt_property_get_data( mlt_property self, int *length )
 void mlt_property_close( mlt_property self )
 {
        mlt_property_clear( self );
+       pthread_mutex_destroy( &self->mutex );
        free( self );
 }
 
@@ -487,6 +618,7 @@ void mlt_property_close( mlt_property self )
  */
 void mlt_property_pass( mlt_property self, mlt_property that )
 {
+       pthread_mutex_lock( &self->mutex );
        mlt_property_clear( self );
 
        self->types = that->types;
@@ -499,7 +631,7 @@ void mlt_property_pass( mlt_property self, mlt_property that )
                self->prop_double = that->prop_double;
        else if ( self->types & mlt_prop_position )
                self->prop_position = that->prop_position;
-       else if ( self->types & mlt_prop_string )
+       if ( self->types & mlt_prop_string )
        {
                if ( that->prop_string != NULL )
                        self->prop_string = strdup( that->prop_string );
@@ -509,4 +641,5 @@ void mlt_property_pass( mlt_property self, mlt_property that )
                self->types = mlt_prop_string;
                self->prop_string = self->serialiser( self->data, self->length );
        }
+       pthread_mutex_unlock( &self->mutex );
 }