mlt_repository mlt_repository_init( const char *directory ) { // Safety check if ( directory == NULL || strcmp( directory, "" ) == 0 ) return NULL; // Construct the repository mlt_repository self = calloc( 1, sizeof( struct mlt_repository_s )); mlt_properties_init( &self->parent, self ); self->consumers = mlt_properties_new(); self->filters = mlt_properties_new(); self->producers = mlt_properties_new(); self->transitions = mlt_properties_new(); // Get the directory list mlt_properties dir = mlt_properties_new(); int count = mlt_properties_dir_list( dir, directory, NULL, 0 ); int i; // Iterate over files for ( i = 0; i < count; i++ ) { int flags = RTLD_NOW; const char *object_name = mlt_properties_get_value( dir, i); // Very temporary hack to allow the quicktime plugins to work // TODO: extend repository to allow this to be used on a case by case basis if ( strstr( object_name, "libmltkino" ) ) flags |= RTLD_GLOBAL; // Open the shared object void *object = dlopen( object_name, flags ); if ( object != NULL ) { // Get the registration function mlt_repository_callback symbol_ptr = dlsym( object, "mlt_register" ); // Call the registration function if ( symbol_ptr != NULL ) { symbol_ptr( self ); // Register the object file for closure mlt_properties_set_data( &self->parent, object_name, object, 0, ( mlt_destructor )dlclose, NULL ); } else { dlclose( object ); } } else if ( strstr( object_name, "libmlt" ) ) { mlt_log( NULL, MLT_LOG_WARNING, "%s: failed to dlopen %s\n (%s)\n", __FUNCTION__, object_name, dlerror() ); } } mlt_properties_close( dir ); return self; }
mlt_cache mlt_cache_init() { mlt_cache result = calloc( 1, sizeof( struct mlt_cache_s ) ); if ( result ) { result->current = result->A; pthread_mutex_init( &result->mutex, NULL ); result->active = mlt_properties_new(); result->garbage = mlt_properties_new(); } return result; }
mlt_properties mlt_profile_list( ) { char *filename = NULL; const char *prefix = getenv( "MLT_PROFILES_PATH" ); mlt_properties properties = mlt_properties_new(); mlt_properties dir = mlt_properties_new(); int sort = 1; const char *wildcard = NULL; int i; // Load from $datadir/mlt/profiles if no env var if ( prefix == NULL ) { prefix = mlt_environment( "MLT_DATA" ); filename = calloc( 1, strlen( prefix ) + strlen( PROFILES_DIR ) + 1 ); strcpy( filename, prefix ); strcat( filename, PROFILES_DIR ); prefix = filename; } mlt_properties_dir_list( dir, prefix, wildcard, sort ); for ( i = 0; i < mlt_properties_count( dir ); i++ ) { char *filename = mlt_properties_get_value( dir, i ); char *profile_name = basename( filename ); if ( profile_name[0] != '.' && strcmp( profile_name, "Makefile" ) && profile_name[ strlen( profile_name ) - 1 ] != '~' ) { mlt_properties profile = mlt_properties_load( filename ); if ( profile ) { mlt_properties_set_data( properties, profile_name, profile, 0, (mlt_destructor) mlt_properties_close, NULL ); } } } mlt_properties_close( dir ); if ( filename ) free( filename ); return properties; }
Mlt::Properties GlslManager::effect_list( Mlt::Service& service ) { char *unique_id = service.get( "_unique_id" ); mlt_properties properties = (mlt_properties) get_data( unique_id ); if ( !properties ) { properties = mlt_properties_new(); set( unique_id, properties, 0, (mlt_destructor) mlt_properties_close ); } Mlt::Properties p( properties ); return p; }
dv_decoder_t *dv_decoder_alloc( ) { // We'll return a dv_decoder dv_decoder_t *this = NULL; // Lock the mutex pthread_mutex_lock( &decoder_lock ); // Create the properties if necessary if ( dv_decoders == NULL ) { // Create the properties dv_decoders = mlt_properties_new( ); // Create the stack mlt_properties_set_data( dv_decoders, "stack", mlt_deque_init( ), 0, ( mlt_destructor )mlt_deque_close, NULL ); // Register the properties for clean up mlt_factory_register_for_clean_up( dv_decoders, ( mlt_destructor )mlt_properties_close ); } // Now try to obtain a decoder if ( dv_decoders != NULL ) { // Obtain the stack mlt_deque stack = mlt_properties_get_data( dv_decoders, "stack", NULL ); // Pop the top of the stack this = mlt_deque_pop_back( stack ); // Create a new decoder if none available if ( this == NULL ) { // We'll need a unique property ID for this char label[ 256 ]; // Configure the decoder this = dv_decoder_new( FALSE, FALSE, FALSE ); this->quality = DV_QUALITY_COLOR | DV_QUALITY_AC_2; this->audio->arg_audio_emphasis = 2; dv_set_audio_correction( this, DV_AUDIO_CORRECT_AVERAGE ); dv_set_error_log( this, NULL ); // Register it with the properties to ensure clean up sprintf( label, "%p", this ); mlt_properties_set_data( dv_decoders, label, this, 0, ( mlt_destructor )dv_decoder_free, NULL ); } } // Unlock the mutex pthread_mutex_unlock( &decoder_lock ); return this; }
static void load_filenames( producer_qimage self, mlt_properties properties ) { char *filename = mlt_properties_get( properties, "resource" ); self->filenames = mlt_properties_new( ); if (!load_svg( self, properties, filename ) && !load_sequence( self, properties, filename ) && !load_sequence2( self, properties, filename ) && !load_folder( self, properties, filename ) ) { mlt_properties_set( self->filenames, "0", filename ); } self->count = mlt_properties_count( self->filenames ); }
static void load_filenames( producer_pixbuf self, mlt_properties properties ) { char *filename = mlt_properties_get( properties, "resource" ); self->filenames = mlt_properties_new( ); if (!load_svg( self, properties, filename ) && !load_sequence_querystring( self, properties, filename ) && !load_sequence_sprintf( self, properties, filename ) && !load_sequence_deprecated( self, properties, filename ) && !load_folder( self, properties, filename ) ) { mlt_properties_set( self->filenames, "0", filename ); } self->count = mlt_properties_count( self->filenames ); }
mlt_properties mlt_frame_unique_properties( mlt_frame self, mlt_service service ) { mlt_properties frame_props = MLT_FRAME_PROPERTIES( self ); mlt_properties service_props = MLT_SERVICE_PROPERTIES( service ); char *unique = mlt_properties_get( service_props, "_unique_id" ); mlt_properties instance_props = mlt_properties_get_data( frame_props, unique, NULL ); if ( !instance_props ) { instance_props = mlt_properties_new(); mlt_properties_set_data( frame_props, unique, instance_props, 0, (mlt_destructor) mlt_properties_close, NULL ); } return instance_props; }
mlt_properties mlt_repository_languages( mlt_repository self ) { mlt_properties languages = mlt_properties_get_data( &self->parent, "languages", NULL ); if ( languages ) return languages; languages = mlt_properties_new(); char *locale = getenv_locale(); if ( locale ) { locale = strdup( locale ); mlt_tokeniser tokeniser = mlt_tokeniser_init(); int count = mlt_tokeniser_parse_new( tokeniser, locale, ":" ); if ( count ) { int i; for ( i = 0; i < count; i++ ) { char *locale = mlt_tokeniser_get_string( tokeniser, i ); if ( strcmp( locale, "C" ) == 0 || strcmp( locale, "POSIX" ) == 0 ) locale = "en"; else if ( strlen( locale ) > 2 ) locale[2] = 0; char string[21]; snprintf( string, sizeof(string), "%d", i ); mlt_properties_set( languages, string, locale ); } } else { mlt_properties_set( languages, "0", "en" ); } free( locale ); mlt_tokeniser_close( tokeniser ); } else { mlt_properties_set( languages, "0", "en" ); } mlt_properties_set_data( &self->parent, "languages", languages, 0, ( mlt_destructor )mlt_properties_close, NULL ); return languages; }
mlt_profile mlt_profile_load_string( const char *string ) { mlt_properties properties = mlt_properties_new(); mlt_profile profile = NULL; if ( properties ) { const char *p = string; while ( p ) { if ( strcmp( p, "" ) && p[ 0 ] != '#' ) mlt_properties_parse( properties, p ); p = strchr( p, '\n' ); if ( p ) p++; } profile = mlt_profile_load_properties( properties ); mlt_properties_close( properties ); } return profile; }
mlt_properties mlt_repository_presets( ) { mlt_properties result = mlt_properties_new(); char *path = getenv( "MLT_PRESETS_PATH" ); if ( path ) { path = strdup( path ); } else { path = malloc( strlen( mlt_environment( "MLT_DATA" ) ) + strlen( PRESETS_DIR ) + 1 ); strcpy( path, mlt_environment( "MLT_DATA" ) ); strcat( path, PRESETS_DIR ); } list_presets( result, NULL, path ); free( path ); return result; }
static mlt_cache get_cache( mlt_service self, const char *name ) { mlt_cache result = NULL; mlt_properties caches = mlt_properties_get_data( mlt_global_properties(), "caches", NULL ); if ( !caches ) { caches = mlt_properties_new(); mlt_properties_set_data( mlt_global_properties(), "caches", caches, 0, ( mlt_destructor )mlt_properties_close, NULL ); } if ( caches ) { result = mlt_properties_get_data( caches, name, NULL ); if ( !result ) { result = mlt_cache_init(); mlt_properties_set_data( caches, name, result, 0, ( mlt_destructor )mlt_cache_close, NULL ); } } return result; }
int mlt_producer_optimise( mlt_producer self ) { int error = 1; mlt_parser parser = mlt_parser_new( ); if ( parser != NULL ) { int i = 0, j = 0, k = 0; mlt_properties properties = mlt_parser_properties( parser ); mlt_properties producers = mlt_properties_new( ); mlt_deque stack = mlt_deque_init( ); mlt_properties_set_data( properties, "producers", producers, 0, ( mlt_destructor )mlt_properties_close, NULL ); mlt_properties_set_data( properties, "stack", stack, 0, ( mlt_destructor )mlt_deque_close, NULL ); parser->on_start_producer = on_start_producer; parser->on_start_track = on_start_track; parser->on_end_track = on_end_track; parser->on_start_multitrack = on_start_multitrack; parser->on_end_multitrack = on_end_multitrack; push( parser, 0, 0, 0 ); mlt_parser_start( parser, MLT_PRODUCER_SERVICE( self ) ); free( pop( parser ) ); for ( k = 0; k < mlt_properties_count( producers ); k ++ ) { char *name = mlt_properties_get_name( producers, k ); int count = 0; int clones = 0; int max_clones = 0; mlt_producer producer = mlt_properties_get_data_at( producers, k, &count ); if ( producer != NULL && count > 1 ) { clip_references *refs = mlt_properties_get_data( properties, name, &count ); for ( i = 0; i < count; i ++ ) { clones = 0; for ( j = i + 1; j < count; j ++ ) { if ( intersect( &refs[ i ], &refs[ j ] ) ) { clones ++; mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( refs[ j ].cut ), "_clone", clones ); } } if ( clones > max_clones ) max_clones = clones; } for ( i = 0; i < count; i ++ ) { mlt_producer cut = refs[ i ].cut; if ( mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( cut ), "_clone" ) == -1 ) mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( cut ), "_clone", 0 ); } mlt_producer_set_clones( producer, max_clones ); } else if ( producer != NULL ) { clip_references *refs = mlt_properties_get_data( properties, name, &count ); for ( i = 0; i < count; i ++ ) { mlt_producer cut = refs[ i ].cut; mlt_properties_set_int( MLT_PRODUCER_PROPERTIES( cut ), "_clone", 0 ); } mlt_producer_set_clones( producer, 0 ); } } mlt_parser_close( parser ); } return error; }
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 ) { #if !defined(WIN32) && !(defined(__DARWIN__) && defined(RELOCATABLE)) // Allow user overrides if ( directory == NULL || !strcmp( directory, "" ) ) directory = getenv( "MLT_REPOSITORY" ); #endif // If no directory is specified, default to install directory if ( 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( ); // Create and set up the events object event_object = mlt_properties_new( ); mlt_events_init( event_object ); mlt_events_register( event_object, "producer-create-request", ( mlt_transmitter )mlt_factory_create_request ); mlt_events_register( event_object, "producer-create-done", ( mlt_transmitter )mlt_factory_create_done ); mlt_events_register( event_object, "filter-create-request", ( mlt_transmitter )mlt_factory_create_request ); mlt_events_register( event_object, "filter-create-done", ( mlt_transmitter )mlt_factory_create_done ); mlt_events_register( event_object, "transition-create-request", ( mlt_transmitter )mlt_factory_create_request ); mlt_events_register( event_object, "transition-create-done", ( mlt_transmitter )mlt_factory_create_done ); 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 repository of services repository = mlt_repository_init( mlt_directory ); // Force a clean up when app closes atexit( mlt_factory_close ); } if ( global_properties ) { char *path = getenv( "MLT_PRESETS_PATH" ); if ( path ) { mlt_properties_set( global_properties, "MLT_PRESETS_PATH", path ); } else { path = malloc( strlen( mlt_environment( "MLT_DATA" ) ) + strlen( PRESETS_DIR ) + 1 ); strcpy( path, mlt_environment( "MLT_DATA" ) ); strcat( path, PRESETS_DIR ); mlt_properties_set( global_properties, "MLT_PRESETS_PATH", path ); free( path ); } } return repository; }
static void foreach_consumer_init( mlt_consumer consumer ) { const char *resource = mlt_properties_get( MLT_CONSUMER_PROPERTIES(consumer), "resource" ); mlt_properties properties = mlt_properties_parse_yaml( resource ); char key[20]; int index = 0; if ( mlt_properties_get_data( MLT_CONSUMER_PROPERTIES(consumer), "0", NULL ) ) { // Properties set directly by application mlt_properties p; if ( properties ) mlt_properties_close( properties ); properties = MLT_CONSUMER_PROPERTIES(consumer); do { snprintf( key, sizeof(key), "%d", index ); if ( ( p = mlt_properties_get_data( properties, key, NULL ) ) ) generate_consumer( consumer, p, index++ ); } while ( p ); } else if ( properties && mlt_properties_get_data( properties, "0", NULL ) ) { // YAML file supplied mlt_properties p; do { snprintf( key, sizeof(key), "%d", index ); if ( ( p = mlt_properties_get_data( properties, key, NULL ) ) ) generate_consumer( consumer, p, index++ ); } while ( p ); mlt_properties_close( properties ); } else { // properties file supplied or properties on this consumer const char *s; if ( properties ) mlt_properties_close( properties ); if ( resource ) properties = mlt_properties_load( resource ); else properties = MLT_CONSUMER_PROPERTIES( consumer ); do { snprintf( key, sizeof(key), "%d", index ); if ( ( s = mlt_properties_get( properties, key ) ) ) { mlt_properties p = mlt_properties_new(); int i, count; if ( !p ) break; mlt_properties_set( p, "mlt_service", mlt_properties_get( properties, key ) ); snprintf( key, sizeof(key), "%d.", index ); count = mlt_properties_count( properties ); for ( i = 0; i < count; i++ ) { char *name = mlt_properties_get_name( properties, i ); if ( !strncmp( name, key, strlen(key) ) ) mlt_properties_set( p, name + strlen(key), mlt_properties_get_value( properties, i ) ); } generate_consumer( consumer, p, index++ ); mlt_properties_close( p ); } } while ( s ); if ( resource ) mlt_properties_close( properties ); } }
static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { mlt_filter filter = mlt_frame_pop_service( this ); int maxdia = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxdiameter" ); int maxcount = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "maxcount" ); *format = mlt_image_yuv422; int error = mlt_frame_get_image( this, image, format, width, height, 1 ); // load svg mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); char *factory = mlt_properties_get( properties, "factory" ); char temp[1204]=""; sprintf( temp, "%s/oldfilm/", mlt_environment( "MLT_DATA" ) ); mlt_properties direntries=mlt_properties_new(); mlt_properties_dir_list(direntries,temp,"dust*.svg",1); if (!maxcount) return 0; double position = mlt_filter_get_progress( filter, this ); srand(position*10000); mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); int im=rand()%maxcount; int piccount=mlt_properties_count(direntries); while (im-- && piccount){ int picnum=rand()%piccount;
static void add_parameters( mlt_properties params, void *object, int req_flags, const char *unit, const char *subclass ) { const AVOption *opt = NULL; // For each AVOption on the AVClass object #if LIBAVUTIL_VERSION_INT >= ((51<<16)+(12<<8)+0) while ( ( opt = av_opt_next( object, opt ) ) ) #else while ( ( opt = av_next_option( object, opt ) ) ) #endif { // If matches flags and not a binary option (not supported by Mlt) if ( !( opt->flags & req_flags ) || ( opt->type == AV_OPT_TYPE_BINARY ) ) continue; // Ignore constants (keyword values) if ( !unit && opt->type == AV_OPT_TYPE_CONST ) continue; // When processing a groups of options (unit)... // ...ignore non-constants else if ( unit && opt->type != AV_OPT_TYPE_CONST ) continue; // ...ignore constants not in this group else if ( unit && opt->type == AV_OPT_TYPE_CONST && strcmp( unit, opt->unit ) ) continue; // ..add constants to the 'values' sequence else if ( unit && opt->type == AV_OPT_TYPE_CONST ) { char key[20]; snprintf( key, 20, "%d", mlt_properties_count( params ) ); mlt_properties_set( params, key, opt->name ); continue; } // Create a map for this option. mlt_properties p = mlt_properties_new(); char key[20]; snprintf( key, 20, "%d", mlt_properties_count( params ) ); // Add the map to the 'parameters' sequence. mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); // Add the parameter metadata for this AVOption. mlt_properties_set( p, "identifier", opt->name ); if ( opt->help ) { if ( subclass ) { char *s = malloc( strlen( opt->help ) + strlen( subclass ) + 4 ); strcpy( s, opt->help ); strcat( s, " (" ); strcat( s, subclass ); strcat( s, ")" ); mlt_properties_set( p, "description", s ); free( s ); } else mlt_properties_set( p, "description", opt->help ); } switch ( opt->type ) { case AV_OPT_TYPE_FLAGS: mlt_properties_set( p, "type", "string" ); mlt_properties_set( p, "format", "flags" ); break; case AV_OPT_TYPE_INT: if ( !opt->unit ) { mlt_properties_set( p, "type", "integer" ); if ( opt->min != INT_MIN ) mlt_properties_set_int( p, "minimum", (int) opt->min ); if ( opt->max != INT_MAX ) mlt_properties_set_int( p, "maximum", (int) opt->max ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set_int( p, "default", (int) opt->default_val.dbl ); #endif } else { mlt_properties_set( p, "type", "string" ); mlt_properties_set( p, "format", "integer or keyword" ); } break; case AV_OPT_TYPE_INT64: mlt_properties_set( p, "type", "integer" ); mlt_properties_set( p, "format", "64-bit" ); if ( opt->min != INT64_MIN ) mlt_properties_set_int64( p, "minimum", (int64_t) opt->min ); if ( opt->max != INT64_MAX ) mlt_properties_set_int64( p, "maximum", (int64_t) opt->max ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set_int64( p, "default", (int64_t) opt->default_val.dbl ); #endif break; case AV_OPT_TYPE_FLOAT: mlt_properties_set( p, "type", "float" ); if ( opt->min != FLT_MIN && opt->min != -340282346638528859811704183484516925440.0 ) mlt_properties_set_double( p, "minimum", opt->min ); if ( opt->max != FLT_MAX ) mlt_properties_set_double( p, "maximum", opt->max ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set_double( p, "default", opt->default_val.dbl ); #endif break; case AV_OPT_TYPE_DOUBLE: mlt_properties_set( p, "type", "float" ); mlt_properties_set( p, "format", "double" ); if ( opt->min != DBL_MIN ) mlt_properties_set_double( p, "minimum", opt->min ); if ( opt->max != DBL_MAX ) mlt_properties_set_double( p, "maximum", opt->max ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set_double( p, "default", opt->default_val.dbl ); #endif break; case AV_OPT_TYPE_STRING: mlt_properties_set( p, "type", "string" ); #if LIBAVUTIL_VERSION_MAJOR > 50 mlt_properties_set( p, "default", opt->default_val.str ); #endif break; case AV_OPT_TYPE_RATIONAL: mlt_properties_set( p, "type", "string" ); mlt_properties_set( p, "format", "numerator:denominator" ); break; case AV_OPT_TYPE_CONST: default: mlt_properties_set( p, "type", "integer" ); mlt_properties_set( p, "format", "constant" ); break; } // If the option belongs to a group (unit) and is not a constant (keyword value) if ( opt->unit && opt->type != AV_OPT_TYPE_CONST ) { // Create a 'values' sequence. mlt_properties values = mlt_properties_new(); // Recurse to add constants in this group to the 'values' sequence. add_parameters( values, object, req_flags, opt->unit, NULL ); if ( mlt_properties_count( values ) ) mlt_properties_set_data( p, "values", values, 0, (mlt_destructor) mlt_properties_close, NULL ); else mlt_properties_close( values ); } } }
p++; } gain += gain_step; } return 0; } /** Filter processing. */ static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) { mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); mlt_properties filter_props = MLT_FILTER_PROPERTIES( this ); mlt_properties instance_props = mlt_properties_new(); char *name = mlt_properties_get( filter_props, "_unique_id" ); mlt_properties_set_data( properties, name, instance_props, 0, (mlt_destructor) mlt_properties_close, NULL ); double gain = 1.0; // no adjustment // Parse the gain property if ( mlt_properties_get( filter_props, "gain" ) != NULL ) { char *p = mlt_properties_get( filter_props, "gain" ); if ( strncaseeq( p, "normalise", 9 ) ) mlt_properties_set( filter_props, "normalise", "" ); else {
static mlt_frame filter_process( mlt_filter filter, mlt_frame frame ) { mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); mlt_properties frame_props = MLT_FRAME_PROPERTIES( frame ); mlt_properties instance_props = mlt_properties_new(); // Only if mix is specified, otherwise a producer may set the mix if ( mlt_properties_get( properties, "start" ) != NULL ) { // Determine the time position of this frame in the filter duration mlt_properties props = mlt_properties_get_data( frame_props, "_producer", NULL ); int always_active = mlt_properties_get_int( properties, "always_active" ); mlt_position in = !always_active ? mlt_filter_get_in( filter ) : mlt_properties_get_int( props, "in" ); mlt_position out = !always_active ? mlt_filter_get_out( filter ) : mlt_properties_get_int( props, "out" ); int length = mlt_properties_get_int( properties, "length" ); mlt_position time = !always_active ? mlt_frame_get_position( frame ) : mlt_properties_get_int( props, "_frame" ); double mix = ( double )( time - in ) / ( double )( out - in + 1 ); if ( length == 0 ) { // If there is an end mix level adjust mix to the range if ( mlt_properties_get( properties, "end" ) != NULL ) { double start = mlt_properties_get_double( properties, "start" ); double end = mlt_properties_get_double( properties, "end" ); mix = start + ( end - start ) * mix; } // Use constant mix level if only start else if ( mlt_properties_get( properties, "start" ) != NULL ) { mix = mlt_properties_get_double( properties, "start" ); } // Use animated property "split" to get mix level if property is set char* split_property = mlt_properties_get( properties, "split" ); if ( split_property ) { mlt_position pos = mlt_filter_get_position( filter, frame ); mlt_position len = mlt_filter_get_length2( filter, frame ); mix = mlt_properties_anim_get_double( properties, "split", pos, len ); } // Convert it from [0, 1] to [-1, 1] mix = mix * 2.0 - 1.0; // Finally, set the mix property on the frame mlt_properties_set_double( instance_props, "mix", mix ); // Initialise filter previous mix value to prevent an inadvertant jump from 0 mlt_position last_position = mlt_properties_get_position( properties, "_last_position" ); mlt_position current_position = mlt_frame_get_position( frame ); mlt_properties_set_position( properties, "_last_position", current_position ); if ( mlt_properties_get( properties, "_previous_mix" ) == NULL || current_position != last_position + 1 ) mlt_properties_set_double( properties, "_previous_mix", mix ); // Tell the frame what the previous mix level was mlt_properties_set_double( instance_props, "previous_mix", mlt_properties_get_double( properties, "_previous_mix" ) ); // Save the current mix level for the next iteration mlt_properties_set_double( properties, "_previous_mix", mix ); } else { double level = mlt_properties_get_double( properties, "start" ); double mix_start = level; double mix_end = mix_start; double mix_increment = 1.0 / length; if ( time - in < length ) { mix_start *= ( double )( time - in ) / length; mix_end = mix_start + mix_increment; } else if ( time > out - length ) { mix_end = mix_start * ( ( double )( out - time - in ) / length ); mix_start = mix_end - mix_increment; } mix_start = mix_start < 0 ? 0 : mix_start > level ? level : mix_start; mix_end = mix_end < 0 ? 0 : mix_end > level ? level : mix_end; mlt_properties_set_double( instance_props, "previous_mix", mix_start ); mlt_properties_set_double( instance_props, "mix", mix_end ); } mlt_properties_set_int( instance_props, "channel", mlt_properties_get_int( properties, "channel" ) ); mlt_properties_set_int( instance_props, "gang", mlt_properties_get_int( properties, "gang" ) ); } mlt_properties_set_data( frame_props, mlt_properties_get( properties, "_unique_id" ), instance_props, 0, (mlt_destructor) mlt_properties_close, NULL ); // Override the get_audio method mlt_frame_push_audio( frame, filter ); mlt_frame_push_audio( frame, instance_props ); mlt_frame_push_audio( frame, filter_get_audio ); return frame; }
static mlt_properties new_service( void *symbol ) { mlt_properties properties = mlt_properties_new(); mlt_properties_set_data( properties, "symbol", symbol, 0, NULL, NULL ); return properties; }
static mlt_properties fill_param_info ( mlt_service_type type, const char *service_name, char *name ) { char file[ PATH_MAX ]; char servicetype[ 1024 ]=""; struct stat stat_buff; switch ( type ) { case producer_type: strcpy ( servicetype , "producer" ); break; case filter_type: strcpy ( servicetype , "filter" ); break; case transition_type: strcpy ( servicetype , "transition" ) ; break; default: strcpy ( servicetype , "" ); }; snprintf( file, PATH_MAX, "%s/frei0r/%s_%s.yml", mlt_environment( "MLT_DATA" ), servicetype, service_name ); memset(&stat_buff, 0, sizeof(stat_buff)); stat(file,&stat_buff); if (S_ISREG(stat_buff.st_mode)){ return mlt_properties_parse_yaml( file ); } void* handle=dlopen(name,RTLD_LAZY); if (!handle) return NULL; void (*plginfo)(f0r_plugin_info_t*)=dlsym(handle,"f0r_get_plugin_info"); void (*param_info)(f0r_param_info_t*,int param_index)=dlsym(handle,"f0r_get_param_info"); void (*f0r_init)(void)=dlsym(handle,"f0r_init"); void (*f0r_deinit)(void)=dlsym(handle,"f0r_deinit"); f0r_instance_t (*f0r_construct)(unsigned int , unsigned int)=dlsym(handle, "f0r_construct"); void (*f0r_destruct)(f0r_instance_t)=dlsym(handle, "f0r_destruct"); void (*f0r_get_param_value)(f0r_instance_t instance, f0r_param_t param, int param_index)=dlsym(handle,"f0r_get_param_value" ); if (!plginfo || !param_info) { dlclose(handle); return NULL; } mlt_properties metadata = mlt_properties_new(); f0r_plugin_info_t info; char string[48]; int j=0; f0r_init(); f0r_instance_t instance = f0r_construct(720, 576); if (!instance) { f0r_deinit(); dlclose(handle); mlt_properties_close(metadata); return NULL; } plginfo(&info); snprintf ( string, sizeof(string) , "%d" , info.minor_version ); mlt_properties_set_double ( metadata, "schema_version" , 0.1 ); mlt_properties_set ( metadata, "title" , info.name ); mlt_properties_set_double ( metadata, "version", info.major_version + info.minor_version / pow( 10, strlen( string ) ) ); mlt_properties_set ( metadata, "identifier" , service_name ); mlt_properties_set ( metadata, "description" , info.explanation ); mlt_properties_set ( metadata, "creator" , info.author ); switch (type){ case producer_type: mlt_properties_set ( metadata, "type" , "producer" ); break; case filter_type: mlt_properties_set ( metadata, "type" , "filter" ); break; case transition_type: mlt_properties_set ( metadata, "type" , "transition" ); break; default: break; } mlt_properties tags = mlt_properties_new ( ); mlt_properties_set_data ( metadata , "tags" , tags , 0 , ( mlt_destructor )mlt_properties_close, NULL ); mlt_properties_set ( tags , "0" , "Video" ); mlt_properties parameter = mlt_properties_new ( ); mlt_properties_set_data ( metadata , "parameters" , parameter , 0 , ( mlt_destructor )mlt_properties_close, NULL ); for (j=0;j<info.num_params;j++){ snprintf ( string , sizeof(string), "%d" , j ); mlt_properties pnum = mlt_properties_new ( ); mlt_properties_set_data ( parameter , string , pnum , 0 , ( mlt_destructor )mlt_properties_close, NULL ); f0r_param_info_t paraminfo; param_info(¶minfo,j); mlt_properties_set ( pnum , "identifier" , string ); mlt_properties_set ( pnum , "title" , paraminfo.name ); mlt_properties_set ( pnum , "description" , paraminfo.explanation); if ( paraminfo.type == F0R_PARAM_DOUBLE ){ double deflt = 0; mlt_properties_set ( pnum , "type" , "float" ); mlt_properties_set ( pnum , "minimum" , "0" ); mlt_properties_set ( pnum , "maximum" , "1" ); f0r_get_param_value( instance, &deflt, j); mlt_properties_set_double ( pnum, "default", CLAMP(deflt, 0.0, 1.0) ); mlt_properties_set ( pnum , "mutable" , "yes" ); mlt_properties_set ( pnum , "widget" , "spinner" ); }else if ( paraminfo.type == F0R_PARAM_BOOL ){ double deflt = 0; mlt_properties_set ( pnum , "type" , "boolean" ); mlt_properties_set ( pnum , "minimum" , "0" ); mlt_properties_set ( pnum , "maximum" , "1" ); f0r_get_param_value( instance, &deflt, j); mlt_properties_set_int ( pnum, "default", deflt != 0.0 ); mlt_properties_set ( pnum , "mutable" , "yes" ); mlt_properties_set ( pnum , "widget" , "checkbox" ); }else if ( paraminfo.type == F0R_PARAM_COLOR ){ char colorstr[8]; f0r_param_color_t deflt = {0, 0, 0}; mlt_properties_set ( pnum , "type" , "color" ); f0r_get_param_value( instance, &deflt, j); sprintf( colorstr, "#%02x%02x%02x", (unsigned) CLAMP(deflt.r * 255, 0 , 255), (unsigned) CLAMP(deflt.g * 255, 0 , 255), (unsigned) CLAMP(deflt.b * 255, 0 , 255)); colorstr[7] = 0; mlt_properties_set ( pnum , "default", colorstr ); mlt_properties_set ( pnum , "mutable" , "yes" ); mlt_properties_set ( pnum , "widget" , "color" ); }else if ( paraminfo.type == F0R_PARAM_STRING ){ char *deflt = NULL; mlt_properties_set ( pnum , "type" , "string" ); f0r_get_param_value( instance, &deflt, j ); mlt_properties_set ( pnum , "default", deflt ); mlt_properties_set ( pnum , "mutable" , "yes" ); mlt_properties_set ( pnum , "widget" , "text" ); } } f0r_destruct(instance); f0r_deinit(); dlclose(handle); free(name); return metadata; }
static mlt_properties fill_param_info ( mlt_service_type type, const char *service_name, char *name ) { char file[ PATH_MAX ]; char servicetype[ 1024 ]=""; struct stat stat_buff; switch ( type ) { case producer_type: strcpy ( servicetype , "producer" ); break; case filter_type: strcpy ( servicetype , "filter" ); break; case transition_type: strcpy ( servicetype , "transition" ) ; break; default: strcpy ( servicetype , "" ); }; snprintf( file, PATH_MAX, "%s/frei0r/%s_%s.yml", mlt_environment( "MLT_DATA" ), servicetype, service_name ); stat(file,&stat_buff); if (S_ISREG(stat_buff.st_mode)){ return mlt_properties_parse_yaml( file ); } void* handle=dlopen(name,RTLD_LAZY); if (!handle) return NULL; void (*plginfo)(f0r_plugin_info_t*)=dlsym(handle,"f0r_get_plugin_info"); void (*param_info)(f0r_param_info_t*,int param_index)=dlsym(handle,"f0r_get_param_info"); if (!plginfo || !param_info) { dlclose(handle); return NULL; } mlt_properties metadata = mlt_properties_new(); f0r_plugin_info_t info; char string[48]; int j=0; plginfo(&info); snprintf ( string, sizeof(string) , "%d.%d" , info.major_version , info.minor_version ); mlt_properties_set ( metadata, "schema_version" , "0.1" ); mlt_properties_set ( metadata, "title" , info.name ); mlt_properties_set ( metadata, "version", string ); mlt_properties_set ( metadata, "identifier" , service_name ); mlt_properties_set ( metadata, "description" , info.explanation ); mlt_properties_set ( metadata, "creator" , info.author ); switch (type){ case producer_type: mlt_properties_set ( metadata, "type" , "producer" ); break; case filter_type: mlt_properties_set ( metadata, "type" , "filter" ); break; case transition_type: mlt_properties_set ( metadata, "type" , "transition" ); break; default: break; } mlt_properties parameter = mlt_properties_new ( ); mlt_properties_set_data ( metadata , "parameters" , parameter , 0 , ( mlt_destructor )mlt_properties_close, NULL ); mlt_properties tags = mlt_properties_new ( ); mlt_properties_set_data ( metadata , "tags" , tags , 0 , ( mlt_destructor )mlt_properties_close, NULL ); mlt_properties_set ( tags , "0" , "Video" ); for (j=0;j<info.num_params;j++){ snprintf ( string , sizeof(string), "%d" , j ); mlt_properties pnum = mlt_properties_new ( ); mlt_properties_set_data ( parameter , string , pnum , 0 , ( mlt_destructor )mlt_properties_close, NULL ); f0r_param_info_t paraminfo; param_info(¶minfo,j); mlt_properties_set ( pnum , "identifier" , paraminfo.name ); mlt_properties_set ( pnum , "title" , paraminfo.name ); mlt_properties_set ( pnum , "description" , paraminfo.explanation); if ( paraminfo.type == F0R_PARAM_DOUBLE ){ mlt_properties_set ( pnum , "type" , "float" ); mlt_properties_set ( pnum , "minimum" , "0" ); mlt_properties_set ( pnum , "maximum" , "1" ); mlt_properties_set ( pnum , "readonly" , "no" ); mlt_properties_set ( pnum , "widget" , "spinner" ); }else if ( paraminfo.type == F0R_PARAM_BOOL ){ mlt_properties_set ( pnum , "type" , "boolean" ); mlt_properties_set ( pnum , "minimum" , "0" ); mlt_properties_set ( pnum , "maximum" , "1" ); mlt_properties_set ( pnum , "readonly" , "no" ); }else if ( paraminfo.type == F0R_PARAM_COLOR ){ mlt_properties_set ( pnum , "type" , "color" ); mlt_properties_set ( pnum , "readonly" , "no" ); }else if ( paraminfo.type == F0R_PARAM_STRING ){ mlt_properties_set ( pnum , "type" , "string" ); mlt_properties_set ( pnum , "readonly" , "no" ); } } dlclose(handle); free(name); return metadata; }
static void load_consumer( mlt_consumer *consumer, mlt_profile profile, int argc, char **argv ) { int i; int multi = 0; for ( i = 1; i < argc; i ++ ) multi += !strcmp( argv[ i ], "-consumer" ); if ( multi > 1 ) { // If there is more than one -consumer use the 'multi' consumer. int k = 0; char key[20]; if ( *consumer ) mlt_consumer_close( *consumer ); *consumer = create_consumer( profile, "multi" ); mlt_properties properties = MLT_CONSUMER_PROPERTIES( *consumer ); for ( i = 1; i < argc; i ++ ) { if ( !strcmp( argv[ i ], "-consumer" ) && argv[ i + 1 ]) { // Create a properties object for each sub-consumer mlt_properties new_props = mlt_properties_new(); snprintf( key, sizeof(key), "%d", k++ ); mlt_properties_set_data( properties, key, new_props, 0, (mlt_destructor) mlt_properties_close, NULL ); if ( strchr( argv[i + 1], ':' ) ) { char *temp = strdup( argv[++i] ); char *service = temp; char *target = strchr( temp, ':' ); *target++ = 0; mlt_properties_set( new_props, "mlt_service", service ); mlt_properties_set( new_props, "target", target ); } else { mlt_properties_set( new_props, "mlt_service", argv[ ++i ] ); } while ( argv[ i + 1 ] && strchr( argv[ i + 1 ], '=' ) ) mlt_properties_parse( new_props, argv[ ++ i ] ); } } } else for ( i = 1; i < argc; i ++ ) { if ( !strcmp( argv[ i ], "-consumer" ) ) { if ( *consumer ) mlt_consumer_close( *consumer ); *consumer = create_consumer( profile, argv[ ++ i ] ); if ( *consumer ) { mlt_properties properties = MLT_CONSUMER_PROPERTIES( *consumer ); while ( argv[ i + 1 ] != NULL && strchr( argv[ i + 1 ], '=' ) ) mlt_properties_parse( properties, argv[ ++ i ] ); } } } }
static void load_consumer( mlt_consumer *consumer, mlt_profile profile, int argc, char **argv ) { int i; int multi = 0; int qglsl = 0; for ( i = 1; i < argc; i ++ ) { // See if we need multi consumer. multi += !strcmp( argv[i], "-consumer" ); // Seee if we need the qglsl variant of multi consumer. if ( !strncmp( argv[i], "glsl.", 5 ) || !strncmp( argv[i], "movit.", 6 ) ) qglsl = 1; } // Disable qglsl if xgl is being used! for ( i = 1; qglsl && i < argc; i ++ ) if ( !strcmp( argv[i], "xgl" ) ) qglsl = 0; if ( multi > 1 || qglsl ) { // If there is more than one -consumer use the 'multi' consumer. int k = 0; char key[20]; if ( *consumer ) mlt_consumer_close( *consumer ); *consumer = create_consumer( profile, ( qglsl? "qglsl" : "multi" ) ); mlt_properties properties = MLT_CONSUMER_PROPERTIES( *consumer ); for ( i = 1; i < argc; i ++ ) { if ( !strcmp( argv[ i ], "-consumer" ) && argv[ i + 1 ]) { // Create a properties object for each sub-consumer mlt_properties new_props = mlt_properties_new(); snprintf( key, sizeof(key), "%d", k++ ); mlt_properties_set_data( properties, key, new_props, 0, (mlt_destructor) mlt_properties_close, NULL ); if ( strchr( argv[i + 1], ':' ) ) { char *temp = strdup( argv[++i] ); char *service = temp; char *target = strchr( temp, ':' ); *target++ = 0; mlt_properties_set( new_props, "mlt_service", service ); mlt_properties_set( new_props, "target", target ); } else { mlt_properties_set( new_props, "mlt_service", argv[ ++i ] ); } while ( argv[ i + 1 ] && strchr( argv[ i + 1 ], '=' ) ) mlt_properties_parse( new_props, argv[ ++ i ] ); } } } else for ( i = 1; i < argc; i ++ ) { if ( !strcmp( argv[ i ], "-consumer" ) ) { if ( *consumer ) mlt_consumer_close( *consumer ); *consumer = create_consumer( profile, argv[ ++ i ] ); if ( *consumer ) { mlt_properties properties = MLT_CONSUMER_PROPERTIES( *consumer ); while ( argv[ i + 1 ] != NULL && strchr( argv[ i + 1 ], '=' ) ) mlt_properties_parse( properties, argv[ ++ i ] ); } } } }
static mlt_properties metadata( mlt_service_type type, const char *id, char *data ) { char file[ PATH_MAX ]; if( type == filter_type ) { snprintf( file, PATH_MAX, "%s/jackrack/%s", mlt_environment( "MLT_DATA" ), strncmp( id, "ladspa.", 7 ) ? data : "filter_ladspa.yml" ); } else { snprintf( file, PATH_MAX, "%s/jackrack/%s", mlt_environment( "MLT_DATA" ), strncmp( id, "ladspa.", 7 ) ? data : "producer_ladspa.yml" ); } mlt_properties result = mlt_properties_parse_yaml( file ); #ifdef GPL if ( !strncmp( id, "ladspa.", 7 ) ) { // Annotate the yaml properties with ladspa control port info. plugin_desc_t *desc = plugin_mgr_get_any_desc( g_jackrack_plugin_mgr, strtol( id + 7, NULL, 10 ) ); if ( desc ) { mlt_properties params = mlt_properties_new(); mlt_properties p; char key[20]; int i; mlt_properties_set( result, "identifier", id ); mlt_properties_set( result, "title", desc->name ); mlt_properties_set( result, "creator", desc->maker ? desc->maker : "unknown" ); mlt_properties_set( result, "description", "LADSPA plugin" ); mlt_properties_set_data( result, "parameters", params, 0, (mlt_destructor) mlt_properties_close, NULL ); for ( i = 0; i < desc->control_port_count; i++ ) { int j = desc->control_port_indicies[i]; p = mlt_properties_new(); snprintf( key, sizeof(key), "%d", mlt_properties_count( params ) ); mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); snprintf( key, sizeof(key), "%d", j ); mlt_properties_set( p, "identifier", key ); add_port_to_metadata( p, desc, j ); mlt_properties_set( p, "mutable", "yes" ); } for ( i = 0; i < desc->status_port_count; i++ ) { int j = desc->status_port_indicies[i]; p = mlt_properties_new(); snprintf( key, sizeof(key), "%d", mlt_properties_count( params ) ); mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); snprintf( key, sizeof(key), "%d[*]", j ); mlt_properties_set( p, "identifier", key ); add_port_to_metadata( p, desc, j ); mlt_properties_set( p, "readonly", "yes" ); } p = mlt_properties_new(); snprintf( key, sizeof(key), "%d", mlt_properties_count( params ) ); mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); mlt_properties_set( p, "identifier", "instances" ); mlt_properties_set( p, "title", "Instances" ); mlt_properties_set( p, "description", "The number of instances of the plugin that are in use.\n" "MLT will create the number of plugins that are required " "to support the number of audio channels.\n" "Status parameters (readonly) are provided for each instance " "and are accessed by specifying the instance number after the " "identifier (starting at zero).\n" "e.g. 9[0] provides the value of status 9 for the first instance." ); mlt_properties_set( p, "type", "integer" ); mlt_properties_set( p, "readonly", "yes" ); if( type == filter_type ) { p = mlt_properties_new(); snprintf( key, sizeof(key), "%d", mlt_properties_count( params ) ); mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); mlt_properties_set( p, "identifier", "wetness" ); mlt_properties_set( p, "title", "Wet/Dry" ); mlt_properties_set( p, "type", "float" ); mlt_properties_set_double( p, "default", 1 ); mlt_properties_set_double( p, "minimum", 0 ); mlt_properties_set_double( p, "maximum", 1 ); mlt_properties_set( p, "mutable", "yes" ); } } } #endif return result; }
static mlt_properties metadata( mlt_service_type type, const char *id, char *data ) { char file[ PATH_MAX ]; if( type == filter_type ) { snprintf( file, PATH_MAX, "%s/jackrack/%s", mlt_environment( "MLT_DATA" ), strncmp( id, "ladspa.", 7 ) ? data : "filter_ladspa.yml" ); } else { snprintf( file, PATH_MAX, "%s/jackrack/%s", mlt_environment( "MLT_DATA" ), strncmp( id, "ladspa.", 7 ) ? data : "producer_ladspa.yml" ); } mlt_properties result = mlt_properties_parse_yaml( file ); #ifdef GPL if ( !strncmp( id, "ladspa.", 7 ) ) { // Annotate the yaml properties with ladspa control port info. plugin_desc_t *desc = plugin_mgr_get_any_desc( g_jackrack_plugin_mgr, strtol( id + 7, NULL, 10 ) ); if ( desc ) { mlt_properties params = mlt_properties_new(); mlt_properties p; char key[20]; int i; mlt_properties_set( result, "identifier", id ); mlt_properties_set( result, "title", desc->name ); mlt_properties_set( result, "creator", desc->maker ? desc->maker : "unknown" ); mlt_properties_set( result, "description", "LADSPA plugin" ); mlt_properties_set_data( result, "parameters", params, 0, (mlt_destructor) mlt_properties_close, NULL ); for ( i = 0; i < desc->control_port_count; i++ ) { int j = desc->control_port_indicies[i]; LADSPA_Data sample_rate = 48000; LADSPA_PortRangeHintDescriptor hint_descriptor = desc->port_range_hints[j].HintDescriptor; p = mlt_properties_new(); snprintf( key, sizeof(key), "%d", i ); mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); snprintf( key, sizeof(key), "%d", j ); mlt_properties_set( p, "identifier", key ); mlt_properties_set( p, "title", desc->port_names[ j ] ); if ( LADSPA_IS_HINT_INTEGER( hint_descriptor ) ) { mlt_properties_set( p, "type", "integer" ); mlt_properties_set_int( p, "default", plugin_desc_get_default_control_value( desc, j, sample_rate ) ); } else if ( LADSPA_IS_HINT_TOGGLED( hint_descriptor ) ) { mlt_properties_set( p, "type", "boolean" ); mlt_properties_set_int( p, "default", plugin_desc_get_default_control_value( desc, j, sample_rate ) ); } else { mlt_properties_set( p, "type", "float" ); mlt_properties_set_double( p, "default", plugin_desc_get_default_control_value( desc, j, sample_rate ) ); } /* set upper and lower, possibly adjusted to the sample rate */ if ( LADSPA_IS_HINT_BOUNDED_BELOW( hint_descriptor ) ) { LADSPA_Data lower = desc->port_range_hints[j].LowerBound; if ( LADSPA_IS_HINT_SAMPLE_RATE( hint_descriptor ) ) lower *= sample_rate; if ( LADSPA_IS_HINT_LOGARITHMIC( hint_descriptor ) ) { if (lower < FLT_EPSILON) lower = FLT_EPSILON; } mlt_properties_set_double( p, "minimum", lower ); } if ( LADSPA_IS_HINT_BOUNDED_ABOVE( hint_descriptor ) ) { LADSPA_Data upper = desc->port_range_hints[j].UpperBound; if ( LADSPA_IS_HINT_SAMPLE_RATE( hint_descriptor ) ) upper *= sample_rate; mlt_properties_set_double( p, "maximum", upper ); } if ( LADSPA_IS_HINT_LOGARITHMIC( hint_descriptor ) ) mlt_properties_set( p, "scale", "log" ); mlt_properties_set( p, "mutable", "yes" ); } if( type == filter_type ) { p = mlt_properties_new(); snprintf( key, sizeof(key), "%d", i ); mlt_properties_set_data( params, key, p, 0, (mlt_destructor) mlt_properties_close, NULL ); mlt_properties_set( p, "identifier", "wetness" ); mlt_properties_set( p, "title", "Wet/Dry" ); mlt_properties_set( p, "type", "float" ); mlt_properties_set_double( p, "default", 1 ); mlt_properties_set_double( p, "minimum", 0 ); mlt_properties_set_double( p, "maximum", 1 ); mlt_properties_set( p, "mutable", "yes" ); } } } #endif return result; }
static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame ); mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); mlt_position pos = mlt_filter_get_position( filter, frame ); mlt_position len = mlt_filter_get_length2( filter, frame ); int maxdia = mlt_properties_anim_get_int( properties, "maxdiameter", pos, len ); int maxcount = mlt_properties_anim_get_int( properties, "maxcount", pos, len ); *format = mlt_image_yuv422; int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); // Load svg char *factory = mlt_properties_get( properties, "factory" ); char temp[1204] = ""; sprintf( temp, "%s/oldfilm/", mlt_environment( "MLT_DATA" ) ); mlt_properties direntries = mlt_properties_new(); mlt_properties_dir_list( direntries, temp,"dust*.svg",1 ); if (!maxcount) return 0; double position = mlt_filter_get_progress( filter, frame ); srand( position * 10000 ); mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); int im = rand() % maxcount; int piccount = mlt_properties_count( direntries ); while ( im-- && piccount ) { int picnum = rand() % piccount; int y1 = rand() % *height; int x1 = rand() % *width; char resource[1024] = ""; char savename[1024] = "", savename1[1024] = "", cachedy[100]; int dx = ( *width * maxdia / 100); int luma_width, luma_height; uint8_t *luma_image = NULL; uint8_t *alpha = NULL; int updown = rand() % 2; int mirror = rand() % 2; sprintf( resource, "%s", mlt_properties_get_value(direntries,picnum) ); sprintf( savename, "cache-%d-%d", picnum,dx ); sprintf( savename1, "cache-alpha-%d-%d", picnum, dx ); sprintf( cachedy, "cache-dy-%d-%d", picnum,dx ); luma_image = mlt_properties_get_data( properties , savename , NULL ); alpha = mlt_properties_get_data( properties , savename1 , NULL ); if ( luma_image == NULL || alpha == NULL ) { mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) ); mlt_producer producer = mlt_factory_producer( profile, factory, resource ); if ( producer != NULL ) { mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); mlt_properties_set( producer_properties, "eof", "loop" ); mlt_frame luma_frame = NULL; if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &luma_frame, 0 ) == 0 ) { mlt_image_format luma_format = mlt_image_yuv422; luma_width = dx; luma_height = luma_width * mlt_properties_get_int( MLT_FRAME_PROPERTIES ( luma_frame ) , "height" ) / mlt_properties_get_int( MLT_FRAME_PROPERTIES ( luma_frame ) , "width" ); mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "best" );// none/nearest/tiles/hyper mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 ); alpha = mlt_frame_get_alpha_mask (luma_frame ); uint8_t* savealpha = mlt_pool_alloc( luma_width * luma_height ); uint8_t* savepic = mlt_pool_alloc( luma_width * luma_height * 2); if ( savealpha && savepic ) { memcpy( savealpha, alpha , luma_width * luma_height ); memcpy( savepic, luma_image , luma_width * luma_height * 2 ); mlt_properties_set_data( properties, savename, savepic, luma_width * luma_height * 2, mlt_pool_release, NULL ); mlt_properties_set_data( properties, savename1, savealpha, luma_width * luma_height, mlt_pool_release, NULL ); mlt_properties_set_int( properties, cachedy, luma_height ); overlay_image( *image, *width, *height, luma_image, luma_width, luma_height, alpha, x1, y1, updown, mirror ); } else { if ( savealpha ) mlt_pool_release( savealpha ); if ( savepic ) mlt_pool_release( savepic ); } mlt_frame_close( luma_frame ); } mlt_producer_close( producer ); } } else { overlay_image ( *image, *width, *height, luma_image, dx, mlt_properties_get_int ( properties, cachedy ), alpha, x1, y1, updown, mirror ); } } mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); if (piccount>0 ) return 0; if ( error == 0 && *image ) { int h = *height; int w = *width; int im = rand() % maxcount; while ( im-- ) { int type = im % 2; int y1 = rand() % h; int x1 = rand() % w; int dx = rand() % maxdia; int dy = rand() % maxdia; int x=0, y=0; double v = 0.0; for ( x = -dx ; x < dx ; x++ ) { for ( y = -dy ; y < dy ; y++ ) { if ( x1 + x < w && x1 + x > 0 && y1 + y < h && y1 + y > 0 ){ uint8_t *pix = *image + (y+y1) * w * 2 + (x + x1) * 2; v=pow((double) x /(double)dx * 5.0, 2.0) + pow((double)y / (double)dy * 5.0, 2.0); if (v>10) v=10; v = 1.0 - ( v / 10.0 ); switch(type) { case 0: *pix -= (*pix) * v; break; case 1: *pix += ( 255-*pix ) * v; break; } } } } } } return error; }