From: lilo_booter Date: Mon, 22 Dec 2003 13:27:32 +0000 (+0000) Subject: Factory implementation X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=4ed2712bbdac2182c7c0d6477ac77c9f92aaf02a;p=mlt Factory implementation git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@7 d19143bc-622f-0410-bfdd-b5b2a6649095 --- diff --git a/README b/README index e72975b0..6ed3c5f6 100644 --- a/README +++ b/README @@ -1,10 +1,10 @@ README ------ - This document provides a description of the VPS project organisation. + This document provides a description of the MLT project organisation. It provides *CRITICAL* architecture information, so please read carefully - if you plan to extend or use the VPS code base. + if you plan to extend or use the MLT code base. Directories ----------- @@ -14,7 +14,6 @@ Directories + docs - Location of all text and source format documentation + src - All project source is provided here - + client - Client API to access the server + framework - The media framework - this code is 100% posix and as such contain no implementations requiring additional libraries @@ -24,7 +23,8 @@ Directories + ffmpeg - ffmpeg dependent modules and test code + mainconcept - mainconcept dependent modules and test code + SDL - SDL dependent modules and test code - + server - The server implementation + + valerie - Client API to access the server + + miracle - The server implementation Additional subdirectories may be nested below those shown and should be documented in their parent or here. diff --git a/mlt/README b/mlt/README index e72975b0..6ed3c5f6 100644 --- a/mlt/README +++ b/mlt/README @@ -1,10 +1,10 @@ README ------ - This document provides a description of the VPS project organisation. + This document provides a description of the MLT project organisation. It provides *CRITICAL* architecture information, so please read carefully - if you plan to extend or use the VPS code base. + if you plan to extend or use the MLT code base. Directories ----------- @@ -14,7 +14,6 @@ Directories + docs - Location of all text and source format documentation + src - All project source is provided here - + client - Client API to access the server + framework - The media framework - this code is 100% posix and as such contain no implementations requiring additional libraries @@ -24,7 +23,8 @@ Directories + ffmpeg - ffmpeg dependent modules and test code + mainconcept - mainconcept dependent modules and test code + SDL - SDL dependent modules and test code - + server - The server implementation + + valerie - Client API to access the server + + miracle - The server implementation Additional subdirectories may be nested below those shown and should be documented in their parent or here. diff --git a/mlt/src/framework/Makefile b/mlt/src/framework/Makefile index e2d60ee3..3cb84617 100644 --- a/mlt/src/framework/Makefile +++ b/mlt/src/framework/Makefile @@ -16,13 +16,14 @@ OBJS = $(FRAMEWORK_OBJS) SRCS := $(OBJS:.o=.c) -CFLAGS=-g -Wall -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = -g -Wall -D_FILE_OFFSET_BITS=64 -pthread -all: libmlt.a +LDFLAGS = -lm -ldl -lpthread -libmlt.a: $(OBJS) - $(AR) rvu $@ $(OBJS) - ranlib $@ +all: libmlt.so + +libmlt.so: $(OBJS) + $(CC) -shared -o $@ $(OBJS) $(LDFLAGS) depend: $(SRCS) $(CC) -MM $(CFLAGS) $^ 1>.depend @@ -31,7 +32,7 @@ dist-clean: clean rm -f .depend clean: - rm -f $(FRAMEWORK_OBJS) libmlt.a + rm -f $(FRAMEWORK_OBJS) libmlt.so ifneq ($(wildcard .depend),) include .depend diff --git a/mlt/src/framework/mlt.h b/mlt/src/framework/mlt.h new file mode 100644 index 00000000..e38419ca --- /dev/null +++ b/mlt/src/framework/mlt.h @@ -0,0 +1,37 @@ +/* + * mlt.h -- header file for lazy client and implementation code :-) + * Copyright (C) 2003-2004 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _MLT_H_ +#define _MLT_H_ + +#include "mlt_factory.h" +#include "mlt_frame.h" +#include "mlt_multitrack.h" +#include "mlt_producer.h" +#include "mlt_transition.h" +#include "mlt_consumer.h" +#include "mlt_filter.h" +#include "mlt_manager.h" +#include "mlt_playlist.h" +#include "mlt_properties.h" +#include "mlt_tractor.h" + +#endif + diff --git a/mlt/src/framework/mlt_factory.c b/mlt/src/framework/mlt_factory.c index 3b40464d..5d7187b3 100644 --- a/mlt/src/framework/mlt_factory.c +++ b/mlt/src/framework/mlt_factory.c @@ -21,12 +21,14 @@ #include "config.h" #include "mlt_factory.h" #include "mlt_repository.h" +#include "mlt_properties.h" #include /** Singleton repositories */ +static mlt_properties object_list = NULL; static mlt_repository producers = NULL; static mlt_repository filters = NULL; static mlt_repository transitions = NULL; @@ -35,12 +37,22 @@ static mlt_repository consumers = NULL; /** Construct the factories. */ -int mlt_factory_init( ) +int mlt_factory_init( char *prefix ) { - producers = mlt_repository_init( PREFIX_DATA "/producers.dat", "mlt_create_producer" ); - filters = mlt_repository_init( PREFIX_DATA "/filters.dat", "mlt_create_filter" ); - transitions = mlt_repository_init( PREFIX_DATA "/transitions.dat", "mlt_create_transition" ); - consumers = mlt_repository_init( PREFIX_DATA "/consumers.dat", "mlt_create_consumer" ); + // If no directory is specified, default to install directory + if ( prefix == NULL ) + prefix = PREFIX_DATA; + + // Create the object list. + object_list = calloc( sizeof( struct mlt_properties_s ), 1 ); + mlt_properties_init( object_list, NULL ); + + // Create a repository for each service type + producers = mlt_repository_init( object_list, prefix, "producers.dat", "mlt_create_producer" ); + filters = mlt_repository_init( object_list, prefix, "filters.dat", "mlt_create_filter" ); + transitions = mlt_repository_init( object_list, prefix, "transitions.dat", "mlt_create_transition" ); + consumers = mlt_repository_init( object_list, prefix, "consumers.dat", "mlt_create_consumer" ); + return 0; } @@ -63,7 +75,7 @@ mlt_filter mlt_factory_filter( char *service, void *input ) /** Fetch a transition from the repository. */ -mlt_transition mlt_transition_filter( char *service, void *input ) +mlt_transition mlt_factory_transition( char *service, void *input ) { return ( mlt_transition )mlt_repository_fetch( transitions, service, input ); } @@ -85,5 +97,7 @@ void mlt_factory_close( ) mlt_repository_close( filters ); mlt_repository_close( transitions ); mlt_repository_close( consumers ); + mlt_properties_close( object_list ); + free( object_list ); } diff --git a/mlt/src/framework/mlt_factory.h b/mlt/src/framework/mlt_factory.h index 4cece1da..c9e77663 100644 --- a/mlt/src/framework/mlt_factory.h +++ b/mlt/src/framework/mlt_factory.h @@ -23,7 +23,7 @@ #include "mlt_types.h" -extern int mlt_factory_init( ); +extern int mlt_factory_init( char *prefix ); extern mlt_producer mlt_factory_producer( char *name, void *input ); extern mlt_filter mlt_factory_filter( char *name, void *input ); extern mlt_transition mlt_factory_transition( char *name, void *input ); diff --git a/mlt/src/framework/mlt_multitrack.c b/mlt/src/framework/mlt_multitrack.c index 77158c76..92473377 100644 --- a/mlt/src/framework/mlt_multitrack.c +++ b/mlt/src/framework/mlt_multitrack.c @@ -238,8 +238,6 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int ind mlt_producer_prepare_next( parent ); } - fprintf( stderr, "timestamp for %d = %f\n", index, ( float )mlt_frame_get_timecode( *frame ) ); - return 0; } diff --git a/mlt/src/framework/mlt_playlist.h b/mlt/src/framework/mlt_playlist.h index aa916c8e..d77bd9ad 100644 --- a/mlt/src/framework/mlt_playlist.h +++ b/mlt/src/framework/mlt_playlist.h @@ -31,7 +31,7 @@ extern mlt_producer mlt_playlist_producer( mlt_playlist this ); extern mlt_service mlt_playlist_service( mlt_playlist this ); extern int mlt_playlist_append( mlt_playlist this, mlt_producer producer ); extern int mlt_playlist_pad( mlt_playlist this, mlt_timecode length ); -extern mlt_playlist_close( mlt_playlist this ); +extern void mlt_playlist_close( mlt_playlist this ); #endif diff --git a/mlt/src/framework/mlt_repository.c b/mlt/src/framework/mlt_repository.c index 9c41bf92..0928b371 100644 --- a/mlt/src/framework/mlt_repository.c +++ b/mlt/src/framework/mlt_repository.c @@ -19,24 +19,190 @@ */ #include "mlt_repository.h" +#include "mlt_properties.h" + +#include #include +#include +#include struct mlt_repository_s { + struct mlt_properties_s parent; + mlt_properties object_list; }; -mlt_repository mlt_repository_init( char *file, char *symbol ) +static char *construct_full_file( char *output, char *prefix, char *file ) { - return NULL; + strcpy( output, prefix ); + if ( prefix[ strlen( prefix ) - 1 ] != '/' ) + strcat( output, "/" ); + strcat( output, file ); + return output; +} + +static char *chomp( char *input ) +{ + if ( input[ strlen( input ) - 1 ] == '\n' ) + input[ strlen( input ) - 1 ] = '\0'; + return input; +} + +static mlt_properties construct_object( char *prefix, char *id ) +{ + mlt_properties output = calloc( sizeof( struct mlt_properties_s ), 1 ); + mlt_properties_init( output, NULL ); + mlt_properties_set( output, "prefix", prefix ); + mlt_properties_set( output, "id", id ); + return output; +} + +static mlt_properties construct_service( mlt_properties object, char *id ) +{ + mlt_properties output = calloc( sizeof( struct mlt_properties_s ), 1 ); + mlt_properties_init( output, NULL ); + mlt_properties_set_data( output, "object", object, 0, NULL, NULL ); + mlt_properties_set( output, "id", id ); + return output; +} + +void *construct_instance( mlt_properties service_properties, char *symbol, void *input ) +{ + // Extract the service + char *service = mlt_properties_get( service_properties, "id" ); + + // Get the object properties + void *object_properties = mlt_properties_get_data( service_properties, "object", NULL ); + + // Get the dlopen'd object + void *object = mlt_properties_get_data( object_properties, "dlopen", NULL ); + + // Get the dlsym'd symbol + void *( *symbol_ptr )( char *, void * ) = mlt_properties_get_data( object_properties, symbol, NULL ); + + // Check that we have object and open if we don't + if ( object == NULL ) + { + char full_file[ 512 ]; + + // Get the prefix and id of the shared object + char *prefix = mlt_properties_get( object_properties, "prefix" ); + char *file = mlt_properties_get( object_properties, "id" ); + + // Construct the full file + construct_full_file( full_file, prefix, file ); + + // Open the shared object + object = dlopen( full_file, RTLD_NOW | RTLD_GLOBAL ); + + // Set it on the properties + mlt_properties_set_data( object_properties, "dlopen", object, 0, ( void (*)( void * ) )dlclose, NULL ); + } + + // Now check if we have this symbol pointer + if ( object != NULL && symbol_ptr == NULL ) + { + // Construct it now + symbol_ptr = dlsym( object, symbol ); + + // Set it on the properties + mlt_properties_set_data( object_properties, "dlsym", symbol_ptr, 0, NULL, NULL ); + } + + // Construct the service + return symbol_ptr != NULL ? symbol_ptr( service, input ) : NULL; +} + +void destroy_properties( void *arg ) +{ + mlt_properties_close( arg ); + free( arg ); +} + +mlt_repository mlt_repository_init( mlt_properties object_list, char *prefix, char *data, char *symbol ) +{ + char full_file[ 512 ]; + FILE *file; + + // Construct the repository + mlt_repository this = calloc( sizeof( struct mlt_repository_s ), 1 ); + mlt_properties_init( &this->parent, NULL ); + + // Add the symbol to THIS repository properties. + mlt_properties_set( &this->parent, "_symbol", symbol ); + + // Asociate the repository to the global object_list + this->object_list = object_list; + + // Construct full file + construct_full_file( full_file, prefix, data ); + + // Open the file + file = fopen( full_file, "r" ); + + // Parse the contents + if ( file != NULL ) + { + char full[ 512 ]; + char service[ 256 ]; + char object[ 256 ]; + + while( fgets( full, 512, file ) ) + { + chomp( full ); + + if ( full[ 0 ] != '#' && full[ 0 ] != '\0' && sscanf( full, "%s %s", service, object ) == 2 ) + { + // Get the object properties first + mlt_properties object_properties = mlt_properties_get_data( object_list, object, NULL ); + + // If their are no properties, create them now + if ( object_properties == NULL ) + { + // Construct the object + object_properties = construct_object( prefix, object ); + + // Add it to the object list + mlt_properties_set_data( object_list, object, object_properties, 0, destroy_properties, NULL ); + } + + // Now construct a property for the service + mlt_properties service_properties = construct_service( object_properties, service ); + + // Add it to the repository + mlt_properties_set_data( &this->parent, service, service_properties, 0, destroy_properties, NULL ); + } + } + + // Close the file + fclose( file ); + } + + return this; } void *mlt_repository_fetch( mlt_repository this, char *service, void *input ) { + // Get the service properties + mlt_properties service_properties = mlt_properties_get_data( &this->parent, service, NULL ); + + // If the service exists + if ( service_properties != NULL ) + { + // Get the symbol that is used to generate this service + char *symbol = mlt_properties_get( &this->parent, "_symbol" ); + + // Now get an instance of the service + return construct_instance( service_properties, symbol, input ); + } + return NULL; } void mlt_repository_close( mlt_repository this ) { + mlt_properties_close( &this->parent ); + free( this ); } diff --git a/mlt/src/framework/mlt_repository.h b/mlt/src/framework/mlt_repository.h index afab1cc8..f00ad5ba 100644 --- a/mlt/src/framework/mlt_repository.h +++ b/mlt/src/framework/mlt_repository.h @@ -21,6 +21,8 @@ #ifndef _MLT_REPOSITORY_H_ #define _MLT_REPOSITORY_H_ +#include "mlt_types.h" + /** Repository structure forward reference. */ @@ -29,7 +31,7 @@ typedef struct mlt_repository_s *mlt_repository; /** Public functions. */ -extern mlt_repository mlt_repository_init( char *file, char *symbol ); +extern mlt_repository mlt_repository_init( mlt_properties object_list, char *prefix, char *file, char *symbol ); extern void *mlt_repository_fetch( mlt_repository this, char *service, void *input ); extern void mlt_repository_close( mlt_repository this ); diff --git a/mlt/src/modules/core/Makefile b/mlt/src/modules/core/Makefile index 5b8ac04a..5ef6eb2d 100644 --- a/mlt/src/modules/core/Makefile +++ b/mlt/src/modules/core/Makefile @@ -1,5 +1,5 @@ -TARGET=libmltcore.so +TARGET = ../libmltcore.so OBJS = factory.o \ producer_ppm.o \ @@ -7,7 +7,7 @@ OBJS = factory.o \ filter_greyscale.o \ transition_composite.o -CFLAGS=-I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread SRCS := $(OBJS:.o=.c) diff --git a/mlt/src/modules/dv/Makefile b/mlt/src/modules/dv/Makefile index 22d999ee..218f85bc 100644 --- a/mlt/src/modules/dv/Makefile +++ b/mlt/src/modules/dv/Makefile @@ -1,10 +1,10 @@ -TARGET = factory.o \ - libmltdv.so +TARGET = ../libmltdv.so -OBJS = producer_libdv.o +OBJS = factory.o \ + producer_libdv.o -CFLAGS=-I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread LDFLAGS=-ldv -lpthread diff --git a/mlt/src/modules/gtk2/Makefile b/mlt/src/modules/gtk2/Makefile index 0136b31f..17a75ab1 100644 --- a/mlt/src/modules/gtk2/Makefile +++ b/mlt/src/modules/gtk2/Makefile @@ -1,12 +1,12 @@ -TARGET = libmltgtk2.so +TARGET = ../libmltgtk2.so OBJS = factory.o \ producer_pixbuf.o -CFLAGS=`pkg-config gdk-pixbuf-2.0 --cflags` -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = `pkg-config gdk-pixbuf-2.0 --cflags` -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread -LDFLAGS=`pkg-config gdk-pixbuf-2.0 --libs` +LDFLAGS = `pkg-config gdk-pixbuf-2.0 --libs` SRCS := $(OBJS:.o=.c) diff --git a/mlt/src/modules/sdl/Makefile b/mlt/src/modules/sdl/Makefile index 51074412..b5275940 100644 --- a/mlt/src/modules/sdl/Makefile +++ b/mlt/src/modules/sdl/Makefile @@ -1,10 +1,10 @@ -TARGET = libmltsdl.so +TARGET = ../libmltsdl.so OBJS = factory.o \ consumer_sdl.o -CFLAGS=-I../../ `sdl-config --cflags` -Wall -g -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = -I../../ `sdl-config --cflags` -Wall -g -D_FILE_OFFSET_BITS=64 -pthread LDFLAGS= `sdl-config --libs` diff --git a/mlt/src/tests/Makefile b/mlt/src/tests/Makefile new file mode 100644 index 00000000..6812f785 --- /dev/null +++ b/mlt/src/tests/Makefile @@ -0,0 +1,23 @@ +TARGET = dan charlie + +CFLAGS = -I .. -Wall -rdynamic -pthread + +LDFLAGS = -L ../framework -lmlt + +all: $(TARGET) + +dan: dan.o + $(CC) dan.o -o $@ $(LDFLAGS) + +charlie: charlie.o + $(CC) charlie.o -o $@ $(LDFLAGS) + +clean: + rm -f dan.o charlie.o dan charlie + +depend: dan.c charlie.c + $(CC) -MM $(CFLAGS) $^ 1>.depend + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/mlt/src/tests/charlie.c b/mlt/src/tests/charlie.c index 174cb20c..12a45b2c 100644 --- a/mlt/src/tests/charlie.c +++ b/mlt/src/tests/charlie.c @@ -1,15 +1,11 @@ -#include "mlt_producer.h" -#include "mlt_consumer.h" -#include "mlt_filter.h" -#include "mlt_tractor.h" -#include "mlt_transition.h" -#include "mlt_multitrack.h" - -#include "producer_libdv.h" -#include "producer_ppm.h" -#include "filter_deinterlace.h" -#include "filter_greyscale.h" -#include "consumer_sdl.h" +#include + +#include +#include +#include +#include +#include +#include #include @@ -19,23 +15,26 @@ int main( int argc, char **argv ) char *file1 = NULL; char *file2 = NULL; - // Start the consumer... - mlt_consumer sdl_out = consumer_sdl_init( NULL ); - - fprintf( stderr, "Press return to continue\n" ); - fgets( temp, 132, stdin ); + mlt_factory_init( "../modules" ); if ( argc >= 2 ) file1 = argv[ 1 ]; if ( argc >= 3 ) file2 = argv[ 2 ]; + // Start the consumer... + mlt_consumer sdl_out = mlt_factory_consumer( "sdl", NULL ); + + fprintf( stderr, "Press return to continue\n" ); + fgets( temp, 132, stdin ); + // Create the producer(s) + mlt_producer dv1 = mlt_factory_producer( "libdv", file1 ); + mlt_producer dv2 = mlt_factory_producer( "libdv", file2 ); //mlt_producer dv1 = producer_ppm_init( NULL ); //mlt_producer dv2 = producer_ppm_init( NULL ); - mlt_producer dv1 = producer_libdv_init( file1 ); - mlt_producer dv2 = producer_libdv_init( file2 ); + // Connect a producer to our sdl consumer mlt_consumer_connect( sdl_out, mlt_producer_service( dv1 ) ); fprintf( stderr, "Press return to continue\n" ); @@ -47,12 +46,12 @@ int main( int argc, char **argv ) mlt_multitrack_connect( multitrack, dv2, 1 ); // Create a filter and associate it to track 0 - mlt_filter filter = filter_deinterlace_init( NULL ); + mlt_filter filter = mlt_factory_filter( "deinterlace", NULL ); mlt_filter_connect( filter, mlt_multitrack_service( multitrack ), 0 ); mlt_filter_set_in_and_out( filter, 0, 5 ); // Create another - mlt_filter greyscale = filter_greyscale_init( NULL ); + mlt_filter greyscale = mlt_factory_filter( "greyscale", NULL ); mlt_filter_connect( greyscale, mlt_filter_service( filter ), 0 ); mlt_filter_set_in_and_out( greyscale, 0, 10 ); @@ -68,12 +67,15 @@ int main( int argc, char **argv ) fgets( temp, 132, stdin ); // Close everything... - mlt_consumer_close( sdl_out ); - mlt_tractor_close( tractor ); - mlt_filter_close( filter ); - mlt_multitrack_close( multitrack ); - mlt_producer_close( dv1 ); - mlt_producer_close( dv2 ); + //mlt_consumer_close( sdl_out ); + //mlt_tractor_close( tractor ); + //mlt_filter_close( filter ); + //mlt_filter_close( greyscale ); + //mlt_multitrack_close( multitrack ); + //mlt_producer_close( dv1 ); + //mlt_producer_close( dv2 ); + + mlt_factory_close( ); return 0; } diff --git a/mlt/src/tests/dan.c b/mlt/src/tests/dan.c index ee76bb01..e8d61263 100644 --- a/mlt/src/tests/dan.c +++ b/mlt/src/tests/dan.c @@ -1,16 +1,5 @@ -#include "mlt_producer.h" -#include "mlt_consumer.h" -#include "mlt_filter.h" -#include "mlt_tractor.h" -#include "mlt_transition.h" -#include "mlt_multitrack.h" -#include "producer_libdv.h" -#include "filter_deinterlace.h" -#include "consumer_sdl.h" -#include "producer_ppm.h" -#include "producer_pixbuf.h" -#include "transition_composite.h" +#include #include @@ -20,19 +9,21 @@ int main( int argc, char **argv ) char *file1 = NULL; char *file2 = NULL; + mlt_factory_init( "../modules" ); + if ( argc >= 2 ) file1 = argv[ 1 ]; if ( argc >= 3 ) file2 = argv[ 2 ]; // Start the consumer... - mlt_consumer sdl_out = consumer_sdl_init( NULL ); + mlt_consumer sdl_out = mlt_factory_consumer( "sdl", NULL ); // Create the producer(s) - mlt_producer dv1 = producer_libdv_init( file1 ); + mlt_producer dv1 = mlt_factory_producer( "libdv", file1 ); //mlt_producer dv1 = producer_pixbuf_init( file1 ); //mlt_producer dv2 = producer_libdv_init( file2 ); - mlt_producer dv2 = producer_pixbuf_init( file2 ); + mlt_producer dv2 = mlt_factory_producer( "pixbuf", file2 ); // Register producers(s) with a multitrack object mlt_multitrack multitrack = mlt_multitrack_init( ); @@ -40,12 +31,12 @@ int main( int argc, char **argv ) mlt_multitrack_connect( multitrack, dv2, 1 ); // Create a filter and associate it to track 0 - mlt_filter filter = filter_deinterlace_init( NULL ); + mlt_filter filter = mlt_factory_filter( "deinterlace", NULL ); mlt_filter_connect( filter, mlt_multitrack_service( multitrack ), 0 ); mlt_filter_set_in_and_out( filter, 0, 1000 ); // Define a transition - mlt_transition transition = transition_composite_init( NULL ); + mlt_transition transition = mlt_factory_transition( "composite", NULL ); mlt_transition_connect( transition, mlt_filter_service( filter ), 0, 1 ); mlt_transition_set_in_and_out( transition, 0, 1000 ); @@ -61,12 +52,12 @@ int main( int argc, char **argv ) fgets( temp, 132, stdin ); // Close everything... - mlt_consumer_close( sdl_out ); - mlt_tractor_close( tractor ); - mlt_filter_close( filter ); - mlt_multitrack_close( multitrack ); - mlt_producer_close( dv1 ); - mlt_producer_close( dv2 ); + //mlt_consumer_close( sdl_out ); + //mlt_tractor_close( tractor ); + //mlt_filter_close( filter ); + //mlt_multitrack_close( multitrack ); + //mlt_producer_close( dv1 ); + //mlt_producer_close( dv2 ); return 0; } diff --git a/src/framework/Makefile b/src/framework/Makefile index e2d60ee3..3cb84617 100644 --- a/src/framework/Makefile +++ b/src/framework/Makefile @@ -16,13 +16,14 @@ OBJS = $(FRAMEWORK_OBJS) SRCS := $(OBJS:.o=.c) -CFLAGS=-g -Wall -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = -g -Wall -D_FILE_OFFSET_BITS=64 -pthread -all: libmlt.a +LDFLAGS = -lm -ldl -lpthread -libmlt.a: $(OBJS) - $(AR) rvu $@ $(OBJS) - ranlib $@ +all: libmlt.so + +libmlt.so: $(OBJS) + $(CC) -shared -o $@ $(OBJS) $(LDFLAGS) depend: $(SRCS) $(CC) -MM $(CFLAGS) $^ 1>.depend @@ -31,7 +32,7 @@ dist-clean: clean rm -f .depend clean: - rm -f $(FRAMEWORK_OBJS) libmlt.a + rm -f $(FRAMEWORK_OBJS) libmlt.so ifneq ($(wildcard .depend),) include .depend diff --git a/src/framework/mlt.h b/src/framework/mlt.h new file mode 100644 index 00000000..e38419ca --- /dev/null +++ b/src/framework/mlt.h @@ -0,0 +1,37 @@ +/* + * mlt.h -- header file for lazy client and implementation code :-) + * Copyright (C) 2003-2004 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _MLT_H_ +#define _MLT_H_ + +#include "mlt_factory.h" +#include "mlt_frame.h" +#include "mlt_multitrack.h" +#include "mlt_producer.h" +#include "mlt_transition.h" +#include "mlt_consumer.h" +#include "mlt_filter.h" +#include "mlt_manager.h" +#include "mlt_playlist.h" +#include "mlt_properties.h" +#include "mlt_tractor.h" + +#endif + diff --git a/src/framework/mlt_factory.c b/src/framework/mlt_factory.c index 3b40464d..5d7187b3 100644 --- a/src/framework/mlt_factory.c +++ b/src/framework/mlt_factory.c @@ -21,12 +21,14 @@ #include "config.h" #include "mlt_factory.h" #include "mlt_repository.h" +#include "mlt_properties.h" #include /** Singleton repositories */ +static mlt_properties object_list = NULL; static mlt_repository producers = NULL; static mlt_repository filters = NULL; static mlt_repository transitions = NULL; @@ -35,12 +37,22 @@ static mlt_repository consumers = NULL; /** Construct the factories. */ -int mlt_factory_init( ) +int mlt_factory_init( char *prefix ) { - producers = mlt_repository_init( PREFIX_DATA "/producers.dat", "mlt_create_producer" ); - filters = mlt_repository_init( PREFIX_DATA "/filters.dat", "mlt_create_filter" ); - transitions = mlt_repository_init( PREFIX_DATA "/transitions.dat", "mlt_create_transition" ); - consumers = mlt_repository_init( PREFIX_DATA "/consumers.dat", "mlt_create_consumer" ); + // If no directory is specified, default to install directory + if ( prefix == NULL ) + prefix = PREFIX_DATA; + + // Create the object list. + object_list = calloc( sizeof( struct mlt_properties_s ), 1 ); + mlt_properties_init( object_list, NULL ); + + // Create a repository for each service type + producers = mlt_repository_init( object_list, prefix, "producers.dat", "mlt_create_producer" ); + filters = mlt_repository_init( object_list, prefix, "filters.dat", "mlt_create_filter" ); + transitions = mlt_repository_init( object_list, prefix, "transitions.dat", "mlt_create_transition" ); + consumers = mlt_repository_init( object_list, prefix, "consumers.dat", "mlt_create_consumer" ); + return 0; } @@ -63,7 +75,7 @@ mlt_filter mlt_factory_filter( char *service, void *input ) /** Fetch a transition from the repository. */ -mlt_transition mlt_transition_filter( char *service, void *input ) +mlt_transition mlt_factory_transition( char *service, void *input ) { return ( mlt_transition )mlt_repository_fetch( transitions, service, input ); } @@ -85,5 +97,7 @@ void mlt_factory_close( ) mlt_repository_close( filters ); mlt_repository_close( transitions ); mlt_repository_close( consumers ); + mlt_properties_close( object_list ); + free( object_list ); } diff --git a/src/framework/mlt_factory.h b/src/framework/mlt_factory.h index 4cece1da..c9e77663 100644 --- a/src/framework/mlt_factory.h +++ b/src/framework/mlt_factory.h @@ -23,7 +23,7 @@ #include "mlt_types.h" -extern int mlt_factory_init( ); +extern int mlt_factory_init( char *prefix ); extern mlt_producer mlt_factory_producer( char *name, void *input ); extern mlt_filter mlt_factory_filter( char *name, void *input ); extern mlt_transition mlt_factory_transition( char *name, void *input ); diff --git a/src/framework/mlt_multitrack.c b/src/framework/mlt_multitrack.c index 77158c76..92473377 100644 --- a/src/framework/mlt_multitrack.c +++ b/src/framework/mlt_multitrack.c @@ -238,8 +238,6 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int ind mlt_producer_prepare_next( parent ); } - fprintf( stderr, "timestamp for %d = %f\n", index, ( float )mlt_frame_get_timecode( *frame ) ); - return 0; } diff --git a/src/framework/mlt_playlist.h b/src/framework/mlt_playlist.h index aa916c8e..d77bd9ad 100644 --- a/src/framework/mlt_playlist.h +++ b/src/framework/mlt_playlist.h @@ -31,7 +31,7 @@ extern mlt_producer mlt_playlist_producer( mlt_playlist this ); extern mlt_service mlt_playlist_service( mlt_playlist this ); extern int mlt_playlist_append( mlt_playlist this, mlt_producer producer ); extern int mlt_playlist_pad( mlt_playlist this, mlt_timecode length ); -extern mlt_playlist_close( mlt_playlist this ); +extern void mlt_playlist_close( mlt_playlist this ); #endif diff --git a/src/framework/mlt_repository.c b/src/framework/mlt_repository.c index 9c41bf92..0928b371 100644 --- a/src/framework/mlt_repository.c +++ b/src/framework/mlt_repository.c @@ -19,24 +19,190 @@ */ #include "mlt_repository.h" +#include "mlt_properties.h" + +#include #include +#include +#include struct mlt_repository_s { + struct mlt_properties_s parent; + mlt_properties object_list; }; -mlt_repository mlt_repository_init( char *file, char *symbol ) +static char *construct_full_file( char *output, char *prefix, char *file ) { - return NULL; + strcpy( output, prefix ); + if ( prefix[ strlen( prefix ) - 1 ] != '/' ) + strcat( output, "/" ); + strcat( output, file ); + return output; +} + +static char *chomp( char *input ) +{ + if ( input[ strlen( input ) - 1 ] == '\n' ) + input[ strlen( input ) - 1 ] = '\0'; + return input; +} + +static mlt_properties construct_object( char *prefix, char *id ) +{ + mlt_properties output = calloc( sizeof( struct mlt_properties_s ), 1 ); + mlt_properties_init( output, NULL ); + mlt_properties_set( output, "prefix", prefix ); + mlt_properties_set( output, "id", id ); + return output; +} + +static mlt_properties construct_service( mlt_properties object, char *id ) +{ + mlt_properties output = calloc( sizeof( struct mlt_properties_s ), 1 ); + mlt_properties_init( output, NULL ); + mlt_properties_set_data( output, "object", object, 0, NULL, NULL ); + mlt_properties_set( output, "id", id ); + return output; +} + +void *construct_instance( mlt_properties service_properties, char *symbol, void *input ) +{ + // Extract the service + char *service = mlt_properties_get( service_properties, "id" ); + + // Get the object properties + void *object_properties = mlt_properties_get_data( service_properties, "object", NULL ); + + // Get the dlopen'd object + void *object = mlt_properties_get_data( object_properties, "dlopen", NULL ); + + // Get the dlsym'd symbol + void *( *symbol_ptr )( char *, void * ) = mlt_properties_get_data( object_properties, symbol, NULL ); + + // Check that we have object and open if we don't + if ( object == NULL ) + { + char full_file[ 512 ]; + + // Get the prefix and id of the shared object + char *prefix = mlt_properties_get( object_properties, "prefix" ); + char *file = mlt_properties_get( object_properties, "id" ); + + // Construct the full file + construct_full_file( full_file, prefix, file ); + + // Open the shared object + object = dlopen( full_file, RTLD_NOW | RTLD_GLOBAL ); + + // Set it on the properties + mlt_properties_set_data( object_properties, "dlopen", object, 0, ( void (*)( void * ) )dlclose, NULL ); + } + + // Now check if we have this symbol pointer + if ( object != NULL && symbol_ptr == NULL ) + { + // Construct it now + symbol_ptr = dlsym( object, symbol ); + + // Set it on the properties + mlt_properties_set_data( object_properties, "dlsym", symbol_ptr, 0, NULL, NULL ); + } + + // Construct the service + return symbol_ptr != NULL ? symbol_ptr( service, input ) : NULL; +} + +void destroy_properties( void *arg ) +{ + mlt_properties_close( arg ); + free( arg ); +} + +mlt_repository mlt_repository_init( mlt_properties object_list, char *prefix, char *data, char *symbol ) +{ + char full_file[ 512 ]; + FILE *file; + + // Construct the repository + mlt_repository this = calloc( sizeof( struct mlt_repository_s ), 1 ); + mlt_properties_init( &this->parent, NULL ); + + // Add the symbol to THIS repository properties. + mlt_properties_set( &this->parent, "_symbol", symbol ); + + // Asociate the repository to the global object_list + this->object_list = object_list; + + // Construct full file + construct_full_file( full_file, prefix, data ); + + // Open the file + file = fopen( full_file, "r" ); + + // Parse the contents + if ( file != NULL ) + { + char full[ 512 ]; + char service[ 256 ]; + char object[ 256 ]; + + while( fgets( full, 512, file ) ) + { + chomp( full ); + + if ( full[ 0 ] != '#' && full[ 0 ] != '\0' && sscanf( full, "%s %s", service, object ) == 2 ) + { + // Get the object properties first + mlt_properties object_properties = mlt_properties_get_data( object_list, object, NULL ); + + // If their are no properties, create them now + if ( object_properties == NULL ) + { + // Construct the object + object_properties = construct_object( prefix, object ); + + // Add it to the object list + mlt_properties_set_data( object_list, object, object_properties, 0, destroy_properties, NULL ); + } + + // Now construct a property for the service + mlt_properties service_properties = construct_service( object_properties, service ); + + // Add it to the repository + mlt_properties_set_data( &this->parent, service, service_properties, 0, destroy_properties, NULL ); + } + } + + // Close the file + fclose( file ); + } + + return this; } void *mlt_repository_fetch( mlt_repository this, char *service, void *input ) { + // Get the service properties + mlt_properties service_properties = mlt_properties_get_data( &this->parent, service, NULL ); + + // If the service exists + if ( service_properties != NULL ) + { + // Get the symbol that is used to generate this service + char *symbol = mlt_properties_get( &this->parent, "_symbol" ); + + // Now get an instance of the service + return construct_instance( service_properties, symbol, input ); + } + return NULL; } void mlt_repository_close( mlt_repository this ) { + mlt_properties_close( &this->parent ); + free( this ); } diff --git a/src/framework/mlt_repository.h b/src/framework/mlt_repository.h index afab1cc8..f00ad5ba 100644 --- a/src/framework/mlt_repository.h +++ b/src/framework/mlt_repository.h @@ -21,6 +21,8 @@ #ifndef _MLT_REPOSITORY_H_ #define _MLT_REPOSITORY_H_ +#include "mlt_types.h" + /** Repository structure forward reference. */ @@ -29,7 +31,7 @@ typedef struct mlt_repository_s *mlt_repository; /** Public functions. */ -extern mlt_repository mlt_repository_init( char *file, char *symbol ); +extern mlt_repository mlt_repository_init( mlt_properties object_list, char *prefix, char *file, char *symbol ); extern void *mlt_repository_fetch( mlt_repository this, char *service, void *input ); extern void mlt_repository_close( mlt_repository this ); diff --git a/src/modules/core/Makefile b/src/modules/core/Makefile index 5b8ac04a..5ef6eb2d 100644 --- a/src/modules/core/Makefile +++ b/src/modules/core/Makefile @@ -1,5 +1,5 @@ -TARGET=libmltcore.so +TARGET = ../libmltcore.so OBJS = factory.o \ producer_ppm.o \ @@ -7,7 +7,7 @@ OBJS = factory.o \ filter_greyscale.o \ transition_composite.o -CFLAGS=-I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread SRCS := $(OBJS:.o=.c) diff --git a/src/modules/dv/Makefile b/src/modules/dv/Makefile index 22d999ee..218f85bc 100644 --- a/src/modules/dv/Makefile +++ b/src/modules/dv/Makefile @@ -1,10 +1,10 @@ -TARGET = factory.o \ - libmltdv.so +TARGET = ../libmltdv.so -OBJS = producer_libdv.o +OBJS = factory.o \ + producer_libdv.o -CFLAGS=-I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread LDFLAGS=-ldv -lpthread diff --git a/src/modules/gtk2/Makefile b/src/modules/gtk2/Makefile index 0136b31f..17a75ab1 100644 --- a/src/modules/gtk2/Makefile +++ b/src/modules/gtk2/Makefile @@ -1,12 +1,12 @@ -TARGET = libmltgtk2.so +TARGET = ../libmltgtk2.so OBJS = factory.o \ producer_pixbuf.o -CFLAGS=`pkg-config gdk-pixbuf-2.0 --cflags` -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = `pkg-config gdk-pixbuf-2.0 --cflags` -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread -LDFLAGS=`pkg-config gdk-pixbuf-2.0 --libs` +LDFLAGS = `pkg-config gdk-pixbuf-2.0 --libs` SRCS := $(OBJS:.o=.c) diff --git a/src/modules/sdl/Makefile b/src/modules/sdl/Makefile index 51074412..b5275940 100644 --- a/src/modules/sdl/Makefile +++ b/src/modules/sdl/Makefile @@ -1,10 +1,10 @@ -TARGET = libmltsdl.so +TARGET = ../libmltsdl.so OBJS = factory.o \ consumer_sdl.o -CFLAGS=-I../../ `sdl-config --cflags` -Wall -g -D_FILE_OFFSET_BITS=64 -pthread +CFLAGS = -I../../ `sdl-config --cflags` -Wall -g -D_FILE_OFFSET_BITS=64 -pthread LDFLAGS= `sdl-config --libs` diff --git a/src/tests/Makefile b/src/tests/Makefile new file mode 100644 index 00000000..6812f785 --- /dev/null +++ b/src/tests/Makefile @@ -0,0 +1,23 @@ +TARGET = dan charlie + +CFLAGS = -I .. -Wall -rdynamic -pthread + +LDFLAGS = -L ../framework -lmlt + +all: $(TARGET) + +dan: dan.o + $(CC) dan.o -o $@ $(LDFLAGS) + +charlie: charlie.o + $(CC) charlie.o -o $@ $(LDFLAGS) + +clean: + rm -f dan.o charlie.o dan charlie + +depend: dan.c charlie.c + $(CC) -MM $(CFLAGS) $^ 1>.depend + +ifneq ($(wildcard .depend),) +include .depend +endif diff --git a/src/tests/charlie.c b/src/tests/charlie.c index 174cb20c..12a45b2c 100644 --- a/src/tests/charlie.c +++ b/src/tests/charlie.c @@ -1,15 +1,11 @@ -#include "mlt_producer.h" -#include "mlt_consumer.h" -#include "mlt_filter.h" -#include "mlt_tractor.h" -#include "mlt_transition.h" -#include "mlt_multitrack.h" - -#include "producer_libdv.h" -#include "producer_ppm.h" -#include "filter_deinterlace.h" -#include "filter_greyscale.h" -#include "consumer_sdl.h" +#include + +#include +#include +#include +#include +#include +#include #include @@ -19,23 +15,26 @@ int main( int argc, char **argv ) char *file1 = NULL; char *file2 = NULL; - // Start the consumer... - mlt_consumer sdl_out = consumer_sdl_init( NULL ); - - fprintf( stderr, "Press return to continue\n" ); - fgets( temp, 132, stdin ); + mlt_factory_init( "../modules" ); if ( argc >= 2 ) file1 = argv[ 1 ]; if ( argc >= 3 ) file2 = argv[ 2 ]; + // Start the consumer... + mlt_consumer sdl_out = mlt_factory_consumer( "sdl", NULL ); + + fprintf( stderr, "Press return to continue\n" ); + fgets( temp, 132, stdin ); + // Create the producer(s) + mlt_producer dv1 = mlt_factory_producer( "libdv", file1 ); + mlt_producer dv2 = mlt_factory_producer( "libdv", file2 ); //mlt_producer dv1 = producer_ppm_init( NULL ); //mlt_producer dv2 = producer_ppm_init( NULL ); - mlt_producer dv1 = producer_libdv_init( file1 ); - mlt_producer dv2 = producer_libdv_init( file2 ); + // Connect a producer to our sdl consumer mlt_consumer_connect( sdl_out, mlt_producer_service( dv1 ) ); fprintf( stderr, "Press return to continue\n" ); @@ -47,12 +46,12 @@ int main( int argc, char **argv ) mlt_multitrack_connect( multitrack, dv2, 1 ); // Create a filter and associate it to track 0 - mlt_filter filter = filter_deinterlace_init( NULL ); + mlt_filter filter = mlt_factory_filter( "deinterlace", NULL ); mlt_filter_connect( filter, mlt_multitrack_service( multitrack ), 0 ); mlt_filter_set_in_and_out( filter, 0, 5 ); // Create another - mlt_filter greyscale = filter_greyscale_init( NULL ); + mlt_filter greyscale = mlt_factory_filter( "greyscale", NULL ); mlt_filter_connect( greyscale, mlt_filter_service( filter ), 0 ); mlt_filter_set_in_and_out( greyscale, 0, 10 ); @@ -68,12 +67,15 @@ int main( int argc, char **argv ) fgets( temp, 132, stdin ); // Close everything... - mlt_consumer_close( sdl_out ); - mlt_tractor_close( tractor ); - mlt_filter_close( filter ); - mlt_multitrack_close( multitrack ); - mlt_producer_close( dv1 ); - mlt_producer_close( dv2 ); + //mlt_consumer_close( sdl_out ); + //mlt_tractor_close( tractor ); + //mlt_filter_close( filter ); + //mlt_filter_close( greyscale ); + //mlt_multitrack_close( multitrack ); + //mlt_producer_close( dv1 ); + //mlt_producer_close( dv2 ); + + mlt_factory_close( ); return 0; } diff --git a/src/tests/dan.c b/src/tests/dan.c index ee76bb01..e8d61263 100644 --- a/src/tests/dan.c +++ b/src/tests/dan.c @@ -1,16 +1,5 @@ -#include "mlt_producer.h" -#include "mlt_consumer.h" -#include "mlt_filter.h" -#include "mlt_tractor.h" -#include "mlt_transition.h" -#include "mlt_multitrack.h" -#include "producer_libdv.h" -#include "filter_deinterlace.h" -#include "consumer_sdl.h" -#include "producer_ppm.h" -#include "producer_pixbuf.h" -#include "transition_composite.h" +#include #include @@ -20,19 +9,21 @@ int main( int argc, char **argv ) char *file1 = NULL; char *file2 = NULL; + mlt_factory_init( "../modules" ); + if ( argc >= 2 ) file1 = argv[ 1 ]; if ( argc >= 3 ) file2 = argv[ 2 ]; // Start the consumer... - mlt_consumer sdl_out = consumer_sdl_init( NULL ); + mlt_consumer sdl_out = mlt_factory_consumer( "sdl", NULL ); // Create the producer(s) - mlt_producer dv1 = producer_libdv_init( file1 ); + mlt_producer dv1 = mlt_factory_producer( "libdv", file1 ); //mlt_producer dv1 = producer_pixbuf_init( file1 ); //mlt_producer dv2 = producer_libdv_init( file2 ); - mlt_producer dv2 = producer_pixbuf_init( file2 ); + mlt_producer dv2 = mlt_factory_producer( "pixbuf", file2 ); // Register producers(s) with a multitrack object mlt_multitrack multitrack = mlt_multitrack_init( ); @@ -40,12 +31,12 @@ int main( int argc, char **argv ) mlt_multitrack_connect( multitrack, dv2, 1 ); // Create a filter and associate it to track 0 - mlt_filter filter = filter_deinterlace_init( NULL ); + mlt_filter filter = mlt_factory_filter( "deinterlace", NULL ); mlt_filter_connect( filter, mlt_multitrack_service( multitrack ), 0 ); mlt_filter_set_in_and_out( filter, 0, 1000 ); // Define a transition - mlt_transition transition = transition_composite_init( NULL ); + mlt_transition transition = mlt_factory_transition( "composite", NULL ); mlt_transition_connect( transition, mlt_filter_service( filter ), 0, 1 ); mlt_transition_set_in_and_out( transition, 0, 1000 ); @@ -61,12 +52,12 @@ int main( int argc, char **argv ) fgets( temp, 132, stdin ); // Close everything... - mlt_consumer_close( sdl_out ); - mlt_tractor_close( tractor ); - mlt_filter_close( filter ); - mlt_multitrack_close( multitrack ); - mlt_producer_close( dv1 ); - mlt_producer_close( dv2 ); + //mlt_consumer_close( sdl_out ); + //mlt_tractor_close( tractor ); + //mlt_filter_close( filter ); + //mlt_multitrack_close( multitrack ); + //mlt_producer_close( dv1 ); + //mlt_producer_close( dv2 ); return 0; }