/*
- * dvlocal.c -- Local dv1394d Parser
+ * miracle_local.c -- Local Miracle Parser
* Copyright (C) 2002-2003 Ushodaya Enterprises Limited
* Author: Charles Yates <charles.yates@pandora.be>
*
#include <string.h>
#include <signal.h>
-/* Library header files */
-#include <dvutil.h>
+/* Needed for backtrace on linux */
+#ifdef linux
+#include <execinfo.h>
+#endif
+
+/* Valerie header files */
+#include <valerie/valerie_util.h>
+
+/* MLT header files. */
+#include <framework/mlt_factory.h>
/* Application header files */
-#include <dvclipfactory.h>
-#include <dvframepool.h>
-#include "dvlocal.h"
-#include "dvconnection.h"
-#include "global_commands.h"
-#include "unit_commands.h"
-#include "log.h"
-#include "raw1394util.h"
-
-/** Private dv_local structure.
+#include "miracle_local.h"
+#include "miracle_connection.h"
+#include "miracle_commands.h"
+#include "miracle_unit_commands.h"
+#include "miracle_log.h"
+
+/** Private miracle_local structure.
*/
typedef struct
{
- dv_parser parser;
+ valerie_parser parser;
char root_dir[1024];
}
-*dv_local, dv_local_t;
+*miracle_local, miracle_local_t;
/** Forward declarations.
*/
-static dv_response dv_local_connect( dv_local );
-static dv_response dv_local_execute( dv_local, char * );
-static void dv_local_close( dv_local );
-response_codes print_help( command_argument arg );
-response_codes dv1394d_run( command_argument arg );
-response_codes dv1394d_shutdown( command_argument arg );
+static valerie_response miracle_local_connect( miracle_local );
+static valerie_response miracle_local_execute( miracle_local, char * );
+static valerie_response miracle_local_push( miracle_local, char *, mlt_service );
+static valerie_response miracle_local_receive( miracle_local, char *, char * );
+static void miracle_local_close( miracle_local );
+response_codes miracle_help( command_argument arg );
+response_codes miracle_run( command_argument arg );
+response_codes miracle_shutdown( command_argument arg );
/** DV Parser constructor.
*/
-dv_parser dv_parser_init_local( )
+valerie_parser miracle_parser_init_local( )
{
- dv_parser parser = malloc( sizeof( dv_parser_t ) );
- dv_local local = malloc( sizeof( dv_local_t ) );
+ valerie_parser parser = malloc( sizeof( valerie_parser_t ) );
+ miracle_local local = malloc( sizeof( miracle_local_t ) );
if ( parser != NULL )
{
- memset( parser, 0, sizeof( dv_parser_t ) );
+ memset( parser, 0, sizeof( valerie_parser_t ) );
- parser->connect = (parser_connect)dv_local_connect;
- parser->execute = (parser_execute)dv_local_execute;
- parser->close = (parser_close)dv_local_close;
+ parser->connect = (parser_connect)miracle_local_connect;
+ parser->execute = (parser_execute)miracle_local_execute;
+ parser->push = (parser_push)miracle_local_push;
+ parser->received = (parser_received)miracle_local_receive;
+ parser->close = (parser_close)miracle_local_close;
parser->real = local;
if ( local != NULL )
{
- memset( local, 0, sizeof( dv_local_t ) );
+ memset( local, 0, sizeof( miracle_local_t ) );
local->parser = parser;
local->root_dir[0] = '/';
}
+
+ // Construct the factory
+ mlt_factory_init( getenv( "MLT_REPOSITORY" ) );
}
return parser;
}
ATYPE_NONE,
ATYPE_FLOAT,
ATYPE_STRING,
- ATYPE_INT
+ ATYPE_INT,
+ ATYPE_PAIR
}
arguments_types;
static command_t vocabulary[] =
{
{"BYE", NULL, 0, ATYPE_NONE, "Terminates the session. Units are not removed and task queue is not flushed."},
- {"HELP", print_help, 0, ATYPE_NONE, "Display this information!"},
- {"NLS", dv1394d_list_nodes, 0, ATYPE_NONE, "List the AV/C nodes on the 1394 bus."},
- {"UADD", dv1394d_add_unit, 0, ATYPE_STRING, "Create a new DV unit (virtual VTR) to transmit to receiver specified in GUID argument."},
- {"ULS", dv1394d_list_units, 0, ATYPE_NONE, "Lists the units that have already been added to the server."},
- {"CLS", dv1394d_list_clips, 0, ATYPE_STRING, "Lists the clips at directory name argument."},
- {"SET", dv1394d_set_global_property, 0, ATYPE_STRING, "Set a server configuration property."},
- {"GET", dv1394d_get_global_property, 0, ATYPE_STRING, "Get a server configuration property."},
- {"RUN", dv1394d_run, 0, ATYPE_STRING, "Run a batch file." },
- {"LIST", dv1394d_list, 1, ATYPE_NONE, "List the playlist associated to a unit."},
- {"LOAD", dv1394d_load, 1, ATYPE_STRING, "Load clip specified in absolute filename argument."},
- {"INSERT", dv1394d_insert, 1, ATYPE_STRING, "Insert a clip at the given clip index."},
- {"REMOVE", dv1394d_remove, 1, ATYPE_NONE, "Remove a clip at the given clip index."},
- {"CLEAN", dv1394d_clean, 1, ATYPE_NONE, "Clean a unit by removing all but the currently playing clip."},
- {"MOVE", dv1394d_move, 1, ATYPE_INT, "Move a clip to another clip index."},
- {"APND", dv1394d_append, 1, ATYPE_STRING, "Append a clip specified in absolute filename argument."},
- {"PLAY", dv1394d_play, 1, ATYPE_NONE, "Play a loaded clip at speed -2000 to 2000 where 1000 = normal forward speed."},
- {"STOP", dv1394d_stop, 1, ATYPE_NONE, "Stop a loaded and playing clip."},
- {"PAUSE", dv1394d_pause, 1, ATYPE_NONE, "Pause a playing clip."},
- {"REW", dv1394d_rewind, 1, ATYPE_NONE, "Rewind a unit. If stopped, seek to beginning of clip. If playing, play fast backwards."},
- {"FF", dv1394d_ff, 1, ATYPE_NONE, "Fast forward a unit. If stopped, seek to beginning of clip. If playing, play fast forwards."},
- {"STEP", dv1394d_step, 1, ATYPE_INT, "Step argument number of frames forward or backward."},
- {"GOTO", dv1394d_goto, 1, ATYPE_INT, "Jump to frame number supplied as argument."},
- {"SIN", dv1394d_set_in_point, 1, ATYPE_INT, "Set the IN point of the loaded clip to frame number argument. -1 = reset in point to 0"},
- {"SOUT", dv1394d_set_out_point, 1, ATYPE_INT, "Set the OUT point of the loaded clip to frame number argument. -1 = reset out point to maximum."},
- {"USTA", dv1394d_get_unit_status, 1, ATYPE_NONE, "Report information about the unit."},
- {"USET", dv1394d_set_unit_property, 1, ATYPE_STRING, "Set a unit configuration property."},
- {"UGET", dv1394d_get_unit_property, 1, ATYPE_STRING, "Get a unit configuration property."},
- {"XFER", dv1394d_transfer, 1, ATYPE_STRING, "Transfer the unit's clip to another unit specified as argument."},
- {"SHUTDOWN", dv1394d_shutdown, 0, ATYPE_NONE, "Shutdown the server."},
+ {"HELP", miracle_help, 0, ATYPE_NONE, "Display this information!"},
+ {"NLS", miracle_list_nodes, 0, ATYPE_NONE, "List the AV/C nodes on the 1394 bus."},
+ {"UADD", miracle_add_unit, 0, ATYPE_STRING, "Create a new DV unit (virtual VTR) to transmit to receiver specified in GUID argument."},
+ {"ULS", miracle_list_units, 0, ATYPE_NONE, "Lists the units that have already been added to the server."},
+ {"CLS", miracle_list_clips, 0, ATYPE_STRING, "Lists the clips at directory name argument."},
+ {"SET", miracle_set_global_property, 0, ATYPE_PAIR, "Set a server configuration property."},
+ {"GET", miracle_get_global_property, 0, ATYPE_STRING, "Get a server configuration property."},
+ {"RUN", miracle_run, 0, ATYPE_STRING, "Run a batch file." },
+ {"LIST", miracle_list, 1, ATYPE_NONE, "List the playlist associated to a unit."},
+ {"LOAD", miracle_load, 1, ATYPE_STRING, "Load clip specified in absolute filename argument."},
+ {"INSERT", miracle_insert, 1, ATYPE_STRING, "Insert a clip at the given clip index."},
+ {"REMOVE", miracle_remove, 1, ATYPE_NONE, "Remove a clip at the given clip index."},
+ {"CLEAN", miracle_clean, 1, ATYPE_NONE, "Clean a unit by removing all but the currently playing clip."},
+ {"WIPE", miracle_wipe, 1, ATYPE_NONE, "Clean a unit by removing everything before the currently playing clip."},
+ {"CLEAR", miracle_clear, 1, ATYPE_NONE, "Clear a unit by removing all clips."},
+ {"MOVE", miracle_move, 1, ATYPE_INT, "Move a clip to another clip index."},
+ {"APND", miracle_append, 1, ATYPE_STRING, "Append a clip specified in absolute filename argument."},
+ {"PLAY", miracle_play, 1, ATYPE_NONE, "Play a loaded clip at speed -2000 to 2000 where 1000 = normal forward speed."},
+ {"STOP", miracle_stop, 1, ATYPE_NONE, "Stop a loaded and playing clip."},
+ {"PAUSE", miracle_pause, 1, ATYPE_NONE, "Pause a playing clip."},
+ {"REW", miracle_rewind, 1, ATYPE_NONE, "Rewind a unit. If stopped, seek to beginning of clip. If playing, play fast backwards."},
+ {"FF", miracle_ff, 1, ATYPE_NONE, "Fast forward a unit. If stopped, seek to beginning of clip. If playing, play fast forwards."},
+ {"STEP", miracle_step, 1, ATYPE_INT, "Step argument number of frames forward or backward."},
+ {"GOTO", miracle_goto, 1, ATYPE_INT, "Jump to frame number supplied as argument."},
+ {"SIN", miracle_set_in_point, 1, ATYPE_INT, "Set the IN point of the loaded clip to frame number argument. -1 = reset in point to 0"},
+ {"SOUT", miracle_set_out_point, 1, ATYPE_INT, "Set the OUT point of the loaded clip to frame number argument. -1 = reset out point to maximum."},
+ {"USTA", miracle_get_unit_status, 1, ATYPE_NONE, "Report information about the unit."},
+ {"USET", miracle_set_unit_property, 1, ATYPE_PAIR, "Set a unit configuration property."},
+ {"UGET", miracle_get_unit_property, 1, ATYPE_STRING, "Get a unit configuration property."},
+ {"XFER", miracle_transfer, 1, ATYPE_STRING, "Transfer the unit's clip to another unit specified as argument."},
+ {"SHUTDOWN", miracle_shutdown, 0, ATYPE_NONE, "Shutdown the server."},
{NULL, NULL, 0, ATYPE_NONE, NULL}
};
*/
static char helpstr [] =
- "dv1394d -- A DV over IEEE 1394 TCP Server\n"
+ "Miracle -- A Multimedia Playout Server\n"
" Copyright (C) 2002-2003 Ushodaya Enterprises Limited\n"
" Authors:\n"
" Dan Dennedy <dan@dennedy.org>\n"
return responses[ i ].message;
}
-/** Tell the user the dv1394d command set
+/** Tell the user the miracle command set
*/
-response_codes print_help( command_argument cmd_arg )
+response_codes miracle_help( command_argument cmd_arg )
{
int i = 0;
- dv_response_printf( cmd_arg->response, 10240, "%s", helpstr );
+ valerie_response_printf( cmd_arg->response, 10240, "%s", helpstr );
for ( i = 0; vocabulary[ i ].command != NULL; i ++ )
- dv_response_printf( cmd_arg->response, 1024,
+ valerie_response_printf( cmd_arg->response, 1024,
"%-10.10s%s\n",
vocabulary[ i ].command,
vocabulary[ i ].help );
- dv_response_printf( cmd_arg->response, 2, "\n" );
+ valerie_response_printf( cmd_arg->response, 2, "\n" );
return RESPONSE_SUCCESS_N;
}
/** Execute a batch file.
*/
-response_codes dv1394d_run( command_argument cmd_arg )
+response_codes miracle_run( command_argument cmd_arg )
{
- dv_response temp = dv_parser_run( cmd_arg->parser, (char *)cmd_arg->argument );
+ valerie_response temp = valerie_parser_run( cmd_arg->parser, (char *)cmd_arg->argument );
if ( temp != NULL )
{
int index = 0;
- dv_response_set_error( cmd_arg->response,
- dv_response_get_error_code( temp ),
- dv_response_get_error_string( temp ) );
+ valerie_response_set_error( cmd_arg->response,
+ valerie_response_get_error_code( temp ),
+ valerie_response_get_error_string( temp ) );
- for ( index = 1; index < dv_response_count( temp ); index ++ )
- dv_response_printf( cmd_arg->response, 10240, "%s\n", dv_response_get_line( temp, index ) );
+ for ( index = 1; index < valerie_response_count( temp ); index ++ )
+ valerie_response_printf( cmd_arg->response, 10240, "%s\n", valerie_response_get_line( temp, index ) );
- dv_response_close( temp );
+ valerie_response_close( temp );
}
- return dv_response_get_error_code( cmd_arg->response );
+ return valerie_response_get_error_code( cmd_arg->response );
}
-response_codes dv1394d_shutdown( command_argument cmd_arg )
+response_codes miracle_shutdown( command_argument cmd_arg )
{
exit( 0 );
return RESPONSE_SUCCESS;
{
#ifdef _GNU_SOURCE
- dv1394d_log( LOG_DEBUG, "Received %s - shutting down.", strsignal(sig) );
+ miracle_log( LOG_DEBUG, "Received %s - shutting down.", strsignal(sig) );
#else
- dv1394d_log( LOG_DEBUG, "Received signal %i - shutting down.", sig );
+ miracle_log( LOG_DEBUG, "Received signal %i - shutting down.", sig );
#endif
exit(EXIT_SUCCESS);
}
}
+static void sigsegv_handler()
+{
+#ifdef linux
+ void *array[ 10 ];
+ size_t size;
+ char **strings;
+ size_t i;
+
+ miracle_log( LOG_CRIT, "\a\nMiracle experienced a segmentation fault.\n"
+ "Dumping stack from the offending thread\n\n" );
+ size = backtrace( array, 10 );
+ strings = backtrace_symbols( array, size );
+
+ miracle_log( LOG_CRIT, "Obtained %zd stack frames.\n", size );
+
+ for ( i = 0; i < size; i++ )
+ miracle_log( LOG_CRIT, "%s", strings[ i ] );
+
+ free( strings );
+
+ miracle_log( LOG_CRIT, "\nDone dumping - exiting.\n" );
+#else
+ miracle_log( LOG_CRIT, "\a\nMiracle experienced a segmentation fault.\n" );
+#endif
+ exit( EXIT_FAILURE );
+}
+
+
+
/** Local 'connect' function.
*/
-static dv_response dv_local_connect( dv_local local )
+static valerie_response miracle_local_connect( miracle_local local )
{
- dv_response response = dv_response_init( );
+ valerie_response response = valerie_response_init( );
self = pthread_self( );
- dv_response_set_error( response, 100, "VTR Ready" );
+ valerie_response_set_error( response, 100, "VTR Ready" );
signal( SIGHUP, signal_handler );
signal( SIGINT, signal_handler );
- signal( SIGTERM, signal_handler );
+ signal( SIGTERM, SIG_DFL );
signal( SIGSTOP, signal_handler );
+ signal( SIGPIPE, signal_handler );
+ signal( SIGALRM, signal_handler );
signal( SIGCHLD, SIG_IGN );
-
- raw1394_reconcile_bus();
- /* Start the raw1394 service threads for handling bus resets */
- raw1394_start_service_threads();
+ if ( getenv( "MLT_SIGSEGV" ) )
+ signal( SIGSEGV, sigsegv_handler );
return response;
}
/** Set the error and determine the message associated to this command.
*/
-void dv_command_set_error( command_argument cmd, response_codes code )
+void miracle_command_set_error( command_argument cmd, response_codes code )
{
- dv_response_set_error( cmd->response, code, get_response_msg( code ) );
+ valerie_response_set_error( cmd->response, code, get_response_msg( code ) );
}
/** Parse the unit argument.
*/
-int dv_command_parse_unit( command_argument cmd, int argument )
+int miracle_command_parse_unit( command_argument cmd, int argument )
{
int unit = -1;
- char *string = dv_tokeniser_get_string( cmd->tokeniser, argument );
+ char *string = valerie_tokeniser_get_string( cmd->tokeniser, argument );
if ( string != NULL && ( string[ 0 ] == 'U' || string[ 0 ] == 'u' ) && strlen( string ) > 1 )
unit = atoi( string + 1 );
return unit;
/** Parse a normal argument.
*/
-void *dv_command_parse_argument( command_argument cmd, int argument, arguments_types type )
+void *miracle_command_parse_argument( command_argument cmd, int argument, arguments_types type, char *command )
{
void *ret = NULL;
- char *value = dv_tokeniser_get_string( cmd->tokeniser, argument );
+ char *value = valerie_tokeniser_get_string( cmd->tokeniser, argument );
if ( value != NULL )
{
ret = strdup( value );
break;
+ case ATYPE_PAIR:
+ if ( strchr( command, '=' ) )
+ {
+ char *ptr = strchr( command, '=' );
+ while ( *( ptr - 1 ) != ' ' )
+ ptr --;
+ ret = strdup( ptr );
+ ptr = ret;
+ while( ptr[ strlen( ptr ) - 1 ] == ' ' )
+ ptr[ strlen( ptr ) - 1 ] = '\0';
+ }
+ break;
+
case ATYPE_INT:
ret = malloc( sizeof( int ) );
if ( ret != NULL )
/** Get the error code - note that we simply the success return.
*/
-response_codes dv_command_get_error( command_argument cmd )
+response_codes miracle_command_get_error( command_argument cmd )
{
- response_codes ret = dv_response_get_error_code( cmd->response );
+ response_codes ret = valerie_response_get_error_code( cmd->response );
if ( ret == RESPONSE_SUCCESS_N || ret == RESPONSE_SUCCESS_1 )
ret = RESPONSE_SUCCESS;
return ret;
/** Execute the command.
*/
-static dv_response dv_local_execute( dv_local local, char *command )
+static valerie_response miracle_local_execute( miracle_local local, char *command )
{
command_argument_t cmd;
cmd.parser = local->parser;
- cmd.response = dv_response_init( );
- cmd.tokeniser = dv_tokeniser_init( );
+ cmd.response = valerie_response_init( );
+ cmd.tokeniser = valerie_tokeniser_init( );
cmd.command = command;
cmd.unit = -1;
cmd.argument = NULL;
cmd.root_dir = local->root_dir;
/* Set the default error */
- dv_command_set_error( &cmd, RESPONSE_UNKNOWN_COMMAND );
+ miracle_command_set_error( &cmd, RESPONSE_UNKNOWN_COMMAND );
/* Parse the command */
- if ( dv_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 )
+ if ( valerie_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 )
{
int index = 0;
- char *value = dv_tokeniser_get_string( cmd.tokeniser, 0 );
+ char *value = valerie_tokeniser_get_string( cmd.tokeniser, 0 );
int found = 0;
/* Strip quotes from all tokens */
- for ( index = 0; index < dv_tokeniser_count( cmd.tokeniser ); index ++ )
- dv_util_strip( dv_tokeniser_get_string( cmd.tokeniser, index ), '\"' );
+ for ( index = 0; index < valerie_tokeniser_count( cmd.tokeniser ); index ++ )
+ valerie_util_strip( valerie_tokeniser_get_string( cmd.tokeniser, index ), '\"' );
/* Search the vocabulary array for value */
for ( index = 1; !found && vocabulary[ index ].command != NULL; index ++ )
{
int position = 1;
- dv_command_set_error( &cmd, RESPONSE_SUCCESS );
+ miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
if ( vocabulary[ index ].is_unit )
{
- cmd.unit = dv_command_parse_unit( &cmd, position );
+ cmd.unit = miracle_command_parse_unit( &cmd, position );
if ( cmd.unit == -1 )
- dv_command_set_error( &cmd, RESPONSE_MISSING_ARG );
+ miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG );
position ++;
}
- if ( dv_command_get_error( &cmd ) == RESPONSE_SUCCESS )
+ if ( miracle_command_get_error( &cmd ) == RESPONSE_SUCCESS )
{
- cmd.argument = dv_command_parse_argument( &cmd, position, vocabulary[ index ].type );
+ cmd.argument = miracle_command_parse_argument( &cmd, position, vocabulary[ index ].type, command );
if ( cmd.argument == NULL && vocabulary[ index ].type != ATYPE_NONE )
- dv_command_set_error( &cmd, RESPONSE_MISSING_ARG );
+ miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG );
position ++;
}
- if ( dv_command_get_error( &cmd ) == RESPONSE_SUCCESS )
+ if ( miracle_command_get_error( &cmd ) == RESPONSE_SUCCESS )
{
response_codes error = vocabulary[ index ].operation( &cmd );
- dv_command_set_error( &cmd, error );
+ miracle_command_set_error( &cmd, error );
}
free( cmd.argument );
}
}
- dv_tokeniser_close( cmd.tokeniser );
+ valerie_tokeniser_close( cmd.tokeniser );
+
+ return cmd.response;
+}
+
+static valerie_response miracle_local_receive( miracle_local local, char *command, char *doc )
+{
+ command_argument_t cmd;
+ cmd.parser = local->parser;
+ cmd.response = valerie_response_init( );
+ cmd.tokeniser = valerie_tokeniser_init( );
+ cmd.command = command;
+ cmd.unit = -1;
+ cmd.argument = NULL;
+ cmd.root_dir = local->root_dir;
+
+ /* Set the default error */
+ miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+ /* Parse the command */
+ if ( valerie_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 )
+ {
+ int index = 0;
+ int position = 1;
+
+ /* Strip quotes from all tokens */
+ for ( index = 0; index < valerie_tokeniser_count( cmd.tokeniser ); index ++ )
+ valerie_util_strip( valerie_tokeniser_get_string( cmd.tokeniser, index ), '\"' );
+
+ cmd.unit = miracle_command_parse_unit( &cmd, position );
+ if ( cmd.unit == -1 )
+ miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG );
+ position ++;
+
+ miracle_receive( &cmd, doc );
+ miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+ free( cmd.argument );
+ }
+
+ valerie_tokeniser_close( cmd.tokeniser );
+
+ return cmd.response;
+}
+
+static valerie_response miracle_local_push( miracle_local local, char *command, mlt_service service )
+{
+ command_argument_t cmd;
+ cmd.parser = local->parser;
+ cmd.response = valerie_response_init( );
+ cmd.tokeniser = valerie_tokeniser_init( );
+ cmd.command = command;
+ cmd.unit = -1;
+ cmd.argument = NULL;
+ cmd.root_dir = local->root_dir;
+
+ /* Set the default error */
+ miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+ /* Parse the command */
+ if ( valerie_tokeniser_parse_new( cmd.tokeniser, command, " " ) > 0 )
+ {
+ int index = 0;
+ int position = 1;
+
+ /* Strip quotes from all tokens */
+ for ( index = 0; index < valerie_tokeniser_count( cmd.tokeniser ); index ++ )
+ valerie_util_strip( valerie_tokeniser_get_string( cmd.tokeniser, index ), '\"' );
+
+ cmd.unit = miracle_command_parse_unit( &cmd, position );
+ if ( cmd.unit == -1 )
+ miracle_command_set_error( &cmd, RESPONSE_MISSING_ARG );
+ position ++;
+
+ miracle_push( &cmd, service );
+ miracle_command_set_error( &cmd, RESPONSE_SUCCESS );
+
+ free( cmd.argument );
+ }
+
+ valerie_tokeniser_close( cmd.tokeniser );
return cmd.response;
}
/** Close the parser.
*/
-static void dv_local_close( dv_local local )
+static void miracle_local_close( miracle_local local )
{
- raw1394_stop_service_threads();
- dv1394d_delete_all_units();
- pthread_kill_other_threads_np();
- dv1394d_log( LOG_DEBUG, "Clean shutdown." );
- free( local );
- dv_clip_factory_close( );
- dv_frame_pool_close( );
+ miracle_delete_all_units();
+#ifdef linux
+ //pthread_kill_other_threads_np();
+ miracle_log( LOG_DEBUG, "Clean shutdown." );
+ //free( local );
+ //mlt_factory_close( );
+#endif
}