#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <locale.h>
+#include <libgen.h>
+#ifdef WIN32
+#include <windows.h>
/** the default subdirectory of the libdir for holding modules (plugins) */
-#define PREFIX_LIB LIBDIR "/mlt"
+#define PREFIX_LIB "\\lib\\mlt"
/** the default subdirectory of the install prefix for holding module (plugin) data */
-#define PREFIX_DATA PREFIX "/share/mlt"
-
+#define PREFIX_DATA "\\share\\mlt"
+#elif defined(__DARWIN__) && defined(RELOCATABLE)
+#include <mach-o/dyld.h>
+/** the default subdirectory of the libdir for holding modules (plugins) */
+#define PREFIX_LIB "/lib/mlt"
+/** the default subdirectory of the install prefix for holding module (plugin) data */
+#define PREFIX_DATA "/share/mlt"
+#endif
/** holds the full path to the modules directory - initialized and retained for the entire session */
static char *mlt_directory = NULL;
*
* \param listener
* \param owner
- * \param this
+ * \param self
* \param args
*/
-static void mlt_factory_create_request( mlt_listener listener, mlt_properties owner, mlt_service this, void **args )
+static void mlt_factory_create_request( mlt_listener listener, mlt_properties owner, mlt_service self, void **args )
{
if ( listener != NULL )
- listener( owner, this, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service * )args[ 2 ] );
+ listener( owner, self, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service * )args[ 2 ] );
}
/** the -create-done event transmitter
*
* \param listener
* \param owner
- * \param this
+ * \param self
* \param args
*/
-static void mlt_factory_create_done( mlt_listener listener, mlt_properties owner, mlt_service this, void **args )
+static void mlt_factory_create_done( mlt_listener listener, mlt_properties owner, mlt_service self, void **args )
{
if ( listener != NULL )
- listener( owner, this, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service )args[ 2 ] );
+ listener( owner, self, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service )args[ 2 ] );
}
/** Construct the repository and factories.
*
- * The environment variable MLT_PRODUCER is the name of a default producer often used by other services, defaults to "fezzil".
+ * The environment variable MLT_PRODUCER is the name of a default producer often used by other services, defaults to "loader".
*
* The environment variable MLT_CONSUMER is the name of a default consumer, defaults to "sdl".
*
mlt_repository mlt_factory_init( const char *directory )
{
+ // Load the system locales
+ setlocale( LC_ALL, "" );
+
+ if ( ! global_properties )
+ global_properties = mlt_properties_new( );
+
+ // Allow property refresh on a subsequent initialisation
+ if ( global_properties )
+ {
+ mlt_properties_set_or_default( global_properties, "MLT_NORMALISATION", getenv( "MLT_NORMALISATION" ), "PAL" );
+ mlt_properties_set_or_default( global_properties, "MLT_PRODUCER", getenv( "MLT_PRODUCER" ), "loader" );
+ mlt_properties_set_or_default( global_properties, "MLT_CONSUMER", getenv( "MLT_CONSUMER" ), "sdl" );
+ mlt_properties_set( global_properties, "MLT_TEST_CARD", getenv( "MLT_TEST_CARD" ) );
+ mlt_properties_set_or_default( global_properties, "MLT_PROFILE", getenv( "MLT_PROFILE" ), "dv_pal" );
+ mlt_properties_set_or_default( global_properties, "MLT_DATA", getenv( "MLT_DATA" ), PREFIX_DATA );
+#if defined(WIN32)
+ char path[1024];
+ DWORD size = sizeof( path );
+ GetModuleFileName( NULL, path, size );
+#elif defined(__DARWIN__) && defined(RELOCATABLE)
+ char path[1024];
+ uint32_t size = sizeof( path );
+ _NSGetExecutablePath( path, &size );
+#endif
+#if defined(WIN32) || (defined(__DARWIN__) && defined(RELOCATABLE))
+ char *path2 = strdup( path );
+ char *appdir = dirname( path2 );
+ mlt_properties_set( global_properties, "MLT_APPDIR", appdir );
+ free( path2 );
+#endif
+ }
+
// Only initialise once
if ( mlt_directory == NULL )
{
directory = PREFIX_LIB;
// Store the prefix for later retrieval
+#if defined(WIN32) || (defined(__DARWIN__) && defined(RELOCATABLE))
+ char *exedir = mlt_environment( "MLT_APPDIR" );
+ size_t size = strlen( exedir );
+ if ( global_properties && !getenv( "MLT_DATA" ) )
+ {
+ mlt_directory = calloc( 1, size + strlen( PREFIX_DATA ) + 1 );
+ strcpy( mlt_directory, exedir );
+ strcat( mlt_directory, PREFIX_DATA );
+ mlt_properties_set( global_properties, "MLT_DATA", mlt_directory );
+ free( mlt_directory );
+ }
+ mlt_directory = calloc( 1, size + strlen( directory ) + 1 );
+ strcpy( mlt_directory, exedir );
+ strcat( mlt_directory, directory );
+#else
mlt_directory = strdup( directory );
-
+#endif
+
// Initialise the pool
mlt_pool_init( );
mlt_events_register( event_object, "consumer-create-request", ( mlt_transmitter )mlt_factory_create_request );
mlt_events_register( event_object, "consumer-create-done", ( mlt_transmitter )mlt_factory_create_done );
- // Create the global properties
- global_properties = mlt_properties_new( );
-
// Create the repository of services
- repository = mlt_repository_init( directory );
+ repository = mlt_repository_init( mlt_directory );
// Force a clean up when app closes
atexit( mlt_factory_close );
}
- // Allow property refresh on a subsequent initialisation
- if ( global_properties != NULL )
- {
- mlt_properties_set_or_default( global_properties, "MLT_NORMALISATION", getenv( "MLT_NORMALISATION" ), "PAL" );
- mlt_properties_set_or_default( global_properties, "MLT_PRODUCER", getenv( "MLT_PRODUCER" ), "fezzik" );
- mlt_properties_set_or_default( global_properties, "MLT_CONSUMER", getenv( "MLT_CONSUMER" ), "sdl" );
- mlt_properties_set( global_properties, "MLT_TEST_CARD", getenv( "MLT_TEST_CARD" ) );
- mlt_properties_set_or_default( global_properties, "MLT_PROFILE", getenv( "MLT_PROFILE" ), "dv_pal" );
- mlt_properties_set_or_default( global_properties, "MLT_DATA", getenv( "MLT_DATA" ), PREFIX_DATA );
- }
-
-
return repository;
}
* \return a new producer
*/
-mlt_producer mlt_factory_producer( mlt_profile profile, const char *service, void *input )
+mlt_producer mlt_factory_producer( mlt_profile profile, const char *service, const void *input )
{
mlt_producer obj = NULL;
* \return a new filter
*/
-mlt_filter mlt_factory_filter( mlt_profile profile, const char *service, void *input )
+mlt_filter mlt_factory_filter( mlt_profile profile, const char *service, const void *input )
{
mlt_filter obj = NULL;
* \return a new transition
*/
-mlt_transition mlt_factory_transition( mlt_profile profile, const char *service, void *input )
+mlt_transition mlt_factory_transition( mlt_profile profile, const char *service, const void *input )
{
mlt_transition obj = NULL;
* \return a new consumer
*/
-mlt_consumer mlt_factory_consumer( mlt_profile profile, const char *service, void *input )
+mlt_consumer mlt_factory_consumer( mlt_profile profile, const char *service, const void *input )
{
mlt_consumer obj = NULL;
if ( mlt_directory != NULL )
{
mlt_properties_close( event_object );
+ event_object = NULL;
+#if !defined(WIN32)
+ // XXX something in here is causing Shotcut/Win32 to not exit completely
+ // under certain conditions: e.g. play a playlist.
mlt_properties_close( global_properties );
- mlt_repository_close( repository );
+ global_properties = NULL;
+#endif
+ if ( repository )
+ {
+ mlt_repository_close( repository );
+ repository = NULL;
+ }
free( mlt_directory );
mlt_directory = NULL;
mlt_pool_close( );