From f807055abb2be863c01c80d9918a9a6d5a12ddb7 Mon Sep 17 00:00:00 2001 From: tpearson Date: Wed, 24 Feb 2010 18:04:47 +0000 Subject: [PATCH] Added KDE3 version of MLT++ git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/libraries/mlt++@1095629 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- AUTHORS | 8 + CUSTOMISING | 381 +++++++++++++++++++++++++++++ HOWTO | 473 ++++++++++++++++++++++++++++++++++++ LGPL | 165 +++++++++++++ Makefile | 10 + README | 135 ++++++++++ config.mak | 8 + mlt++.sln | 21 ++ mlt++.vcproj | 265 ++++++++++++++++++++ src/Makefile | 61 +++++ src/Mlt.h | 50 ++++ src/MltConsumer.cpp | 129 ++++++++++ src/MltConsumer.h | 56 +++++ src/MltDeque.cpp | 68 ++++++ src/MltDeque.h | 47 ++++ src/MltEvent.cpp | 61 +++++ src/MltEvent.h | 46 ++++ src/MltFactory.cpp | 75 ++++++ src/MltFactory.h | 57 +++++ src/MltField.cpp | 63 +++++ src/MltField.h | 52 ++++ src/MltFilter.cpp | 111 +++++++++ src/MltFilter.h | 54 ++++ src/MltFilteredConsumer.cpp | 118 +++++++++ src/MltFilteredConsumer.h | 52 ++++ src/MltFilteredProducer.cpp | 86 +++++++ src/MltFilteredProducer.h | 49 ++++ src/MltFrame.cpp | 89 +++++++ src/MltFrame.h | 52 ++++ src/MltGeometry.cpp | 100 ++++++++ src/MltGeometry.h | 80 ++++++ src/MltMiracle.cpp | 157 ++++++++++++ src/MltMiracle.h | 58 +++++ src/MltMultitrack.cpp | 85 +++++++ src/MltMultitrack.h | 55 +++++ src/MltParser.cpp | 284 ++++++++++++++++++++++ src/MltParser.h | 68 ++++++ src/MltPlaylist.cpp | 314 ++++++++++++++++++++++++ src/MltPlaylist.h | 108 ++++++++ src/MltProducer.cpp | 191 +++++++++++++++ src/MltProducer.h | 72 ++++++ src/MltProperties.cpp | 261 ++++++++++++++++++++ src/MltProperties.h | 88 +++++++ src/MltPushConsumer.cpp | 146 +++++++++++ src/MltPushConsumer.h | 50 ++++ src/MltResponse.cpp | 72 ++++++ src/MltResponse.h | 45 ++++ src/MltService.cpp | 115 +++++++++ src/MltService.h | 61 +++++ src/MltTokeniser.cpp | 56 +++++ src/MltTokeniser.h | 45 ++++ src/MltTractor.cpp | 158 ++++++++++++ src/MltTractor.h | 66 +++++ src/MltTransition.cpp | 90 +++++++ src/MltTransition.h | 49 ++++ src/config.h | 34 +++ swig/Makefile | 10 + swig/configure | 42 ++++ swig/java/Play.java | 51 ++++ swig/java/Play.sh | 2 + swig/java/build | 34 +++ swig/mltpp.i | 142 +++++++++++ swig/perl/Makefile.PL | 16 ++ swig/perl/build | 3 + swig/perl/play.pl | 43 ++++ swig/python/build | 25 ++ swig/python/play.py | 33 +++ swig/ruby/build | 8 + swig/ruby/miracle.rb | 17 ++ swig/ruby/play.rb | 38 +++ swig/ruby/thumbs.rb | 38 +++ swig/tcl/build | 21 ++ swig/tcl/play.tcl | 17 ++ test/Makefile | 25 ++ test/play.cpp | 14 ++ test/server.cpp | 133 ++++++++++ 76 files changed, 6462 insertions(+) create mode 100644 AUTHORS create mode 100644 CUSTOMISING create mode 100644 HOWTO create mode 100644 LGPL create mode 100644 Makefile create mode 100644 README create mode 100644 config.mak create mode 100644 mlt++.sln create mode 100644 mlt++.vcproj create mode 100644 src/Makefile create mode 100644 src/Mlt.h create mode 100644 src/MltConsumer.cpp create mode 100644 src/MltConsumer.h create mode 100644 src/MltDeque.cpp create mode 100644 src/MltDeque.h create mode 100644 src/MltEvent.cpp create mode 100644 src/MltEvent.h create mode 100644 src/MltFactory.cpp create mode 100644 src/MltFactory.h create mode 100644 src/MltField.cpp create mode 100644 src/MltField.h create mode 100644 src/MltFilter.cpp create mode 100644 src/MltFilter.h create mode 100644 src/MltFilteredConsumer.cpp create mode 100644 src/MltFilteredConsumer.h create mode 100644 src/MltFilteredProducer.cpp create mode 100644 src/MltFilteredProducer.h create mode 100644 src/MltFrame.cpp create mode 100644 src/MltFrame.h create mode 100644 src/MltGeometry.cpp create mode 100644 src/MltGeometry.h create mode 100644 src/MltMiracle.cpp create mode 100644 src/MltMiracle.h create mode 100644 src/MltMultitrack.cpp create mode 100644 src/MltMultitrack.h create mode 100644 src/MltParser.cpp create mode 100644 src/MltParser.h create mode 100644 src/MltPlaylist.cpp create mode 100644 src/MltPlaylist.h create mode 100644 src/MltProducer.cpp create mode 100644 src/MltProducer.h create mode 100644 src/MltProperties.cpp create mode 100644 src/MltProperties.h create mode 100644 src/MltPushConsumer.cpp create mode 100644 src/MltPushConsumer.h create mode 100644 src/MltResponse.cpp create mode 100644 src/MltResponse.h create mode 100644 src/MltService.cpp create mode 100644 src/MltService.h create mode 100644 src/MltTokeniser.cpp create mode 100644 src/MltTokeniser.h create mode 100644 src/MltTractor.cpp create mode 100644 src/MltTractor.h create mode 100644 src/MltTransition.cpp create mode 100644 src/MltTransition.h create mode 100644 src/config.h create mode 100644 swig/Makefile create mode 100755 swig/configure create mode 100644 swig/java/Play.java create mode 100755 swig/java/Play.sh create mode 100755 swig/java/build create mode 100644 swig/mltpp.i create mode 100644 swig/perl/Makefile.PL create mode 100755 swig/perl/build create mode 100755 swig/perl/play.pl create mode 100755 swig/python/build create mode 100755 swig/python/play.py create mode 100755 swig/ruby/build create mode 100755 swig/ruby/miracle.rb create mode 100755 swig/ruby/play.rb create mode 100755 swig/ruby/thumbs.rb create mode 100755 swig/tcl/build create mode 100755 swig/tcl/play.tcl create mode 100644 test/Makefile create mode 100644 test/play.cpp create mode 100644 test/server.cpp diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..437d8c1 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,8 @@ +MLT was developed by: + +Charles Yates +Dan Dennedy + +MLT++ was developed by + +Charles Yates diff --git a/CUSTOMISING b/CUSTOMISING new file mode 100644 index 0000000..7fdce7f --- /dev/null +++ b/CUSTOMISING @@ -0,0 +1,381 @@ +Server Customisation + +Copyright (C) 2005 Ushodaya Enterprises Limited +Authors: Charles Yates +Last Revision: 2005-03-16 + + +INTRODUCTION + + This document describes how miracle can be customised. The emphasis is on + showing simple examples of various aspects of the servers capabilities + rather than on focussing on the MLT++ API. + + +THE BASIC CUSTOM SERVER + + The most basic custom server exposes the entire DVCP protocol and is roughly + equivalent to the miracle server iteself, but in this case, it lacks the + initialisation from /etc/miracle.conf and the port is hardcoded to 5290: + + #include + using namespace std; + + #include + using namespace Mlt; + + int main( int argc, char **argv ) + { + Miracle server( "miracle++", 5290 ); + if ( server.start( ) ) + { + server.execute( "uadd sdl" ); + server.execute( "play u0" ); + server.wait_for_shutdown( ); + } + else + { + cerr << "Failed to start server" << endl; + } + return 0; + } + + Note that after the server is started, this example submits the hard coded + commands specified - further units and property settings can of course be + specified via the DVCP protocol. + + To specify initial DVCP commands from /etc/miracle.conf, it is sufficient to + specify an additional argument in the server constructor. + + The wait_for_shutdown call is not required if the server is integrated in + a user interface application. + + +CUSTOMISATION + + This document focusses on the following areas of customisation: + + * the Miracle server class + * extending the command set + * accessing the units + * the Response object + * handling pushed westley documents + * accessiving events + + +THE MIRACLE SERVER CLASS + + The full public interface of the server is as follows: + + class Miracle : public Properties + { + public: + Miracle( char *name, int port = 5290, char *config = NULL ); + virtual ~Miracle( ); + mlt_properties get_properties( ); + bool start( ); + bool is_running( ); + virtual Response *execute( char *command ); + virtual Response *received( char *command, char *doc ); + virtual Response *push( char *command, Service *service ); + void wait_for_shutdown( ); + static void log_level( int ); + Properties *unit( int ); + }; + + The focus of this document is on the 3 virtual methods (execute, received and + push). Some further information is provided about the unit properties method + and the types of functionality that it provides. + + +EXTENDING THE COMMAND SET + + The simplest customisation is carried out by overriding the the 'execute' + method - the following shows a simple example: + + #include + #include + #include + using namespace std; + + #include + #include + using namespace Mlt; + + class Custom : + public Miracle + { + public: + Custom( char *name = "Custom", int port = 5290, char *config = NULL ) : + Miracle( name, port, config ) + { + } + + Response *execute( char *command ) + { + cerr << "command = " << command << endl; + return Miracle::execute( command ); + } + }; + + int main( int argc, char **argv ) + { + Custom server( "miracle++", 5290 ); + if ( server.start( ) ) + { + server.execute( "uadd sdl" ); + server.execute( "play u0" ); + server.wait_for_shutdown( ); + } + else + { + cerr << "Failed to start server" << endl; + } + return 0; + } + + All this does is output each command and pass control over to the original + implementation. + + When you execute this, you will see the following output: + + (5) Starting server on 5290. + command = uadd sdl + (5) miracle++ version 0.0.1 listening on port 5290 + command = play u0 + (7) Received signal 2 - shutting down. + + Note that all commands except the PUSH are passed through this method before + they are executed and this includes those coming from the main function itself. + + +ACCESSING UNIT PROPERTIES + + A unit consists of two objects - a playlist and a consumer. Your custom + server can access these by obtaining the Properties object associated to a unit + via the 'unit' method. + + As a simple example we can replace our execute method above with the following: + + Response *execute( char *command ) + { + if ( !strcmp( command, "debug" ) ) + { + int i = 0; + while( unit( i ) != NULL ) + unit( i ++ )->debug( ); + return new Response( 200, "Diagnostics output" ); + } + return Miracle::execute( command ); + } + + When this runs and you send a 'debug' command via DVCP, the server will output + some information on stderr, like: + + (5) Starting server on 5290. + (5) Server version 0.0.1 listening on port 5290 + (5) Connection established with localhost (7) + Object: [ ref=3, unit=0, generation=0, constructor=sdl, id=sdl, arg=(nil), + consumer=0x80716a0, playlist=0x807f8a8, root=/, notifier=0x8087c28 ] + (6) localhost "debug" 100 + + You can extract the objects using: + + Playlist playlist( ( mlt_playlist )( unit( i )->get_data( "playlist" ) ) ); + Consumer consumer( ( mlt_consumer )( unit( i )->get_data( "consumer" ) ) ); + + and use the standard MLT++ wrapping methods to interact with them or you can + bypass these and using the C API directly. + + Obviously, this opens a lot of possibilities for the types of editing operations + than can be carried out over the DVCP protocol - for example, you can attach filters + apply mixes/transitions between neighbouring cuts or carry out specific operations + on cuts. + + +THE RESPONSE OBJECT + + The example above doesn't do anything particularly useful - in order to extend + things in more interesting ways, we should be able to carry information back to + the client. In the code above, we introduced the Response object to carry an + error code and a description - it can also be used to carry arbitrary large + blocks of data. + + Response *execute( char *command ) + { + Response *response = NULL; + if ( !strcmp( command, "debug" ) ) + { + response = new Response( 200, "Diagnostics output" ); + for( int i = 0; unit( i ) != NULL; i ++ ) + { + Properties *properties = unit( i ); + stringstream output; + output << string( "Unit " ) << i << endl; + for ( int j = 0; j < properties->count( ); j ++ ) + output << properties->get_name( j ) << " = " << properties->get( j ) << endl; + response->write( output.str( ).c_str( ) ); + } + } + return response == NULL ? Miracle::execute( command ) : response; + } + + Now when you connect to the server via a telnet session, you can access the + 'debug' command as follows: + + $ telnet localhost 5290 + Trying 127.0.0.1... + Connected to localhost (127.0.0.1). + Escape character is '^]'. + 100 VTR Ready + debug + 201 OK + Unit 0 + unit = 0 + generation = 0 + constructor = sdl + id = sdl + arg = + + Note that the '200' return code specified is automatically promoted to a 201 + because of the multiple lines. + + Alternatively, you can invoke response->write as many times as you like - each + string submitted is simply appended to the object in a similar way to writing + to a file or socket. Note that the client doesn't receive anything until the + response is returned from this method (ie: there's currently no support to + stream results back to the client). + + +HANDLING PUSHED DOCUMENTS + + The custom class receives PUSH'd westley either via the received or push + method. + + The default handling is to simply append a pushed document on to the end of + first unit 0. + + You can test this in the server defined above from the command line, for + example: + + $ inigo noise: -consumer valerie:localhost:5290 + + By default, the 'push' method is used - this means that the xml document + received is automatically deserialised by the server itself and then offered + to the push method for handling - an example of this would be: + + Response *push( char *command, Service *service ) + { + Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) ); + Producer producer( *service ); + if ( producer.is_valid( ) && playlist.is_valid( ) ) + { + playlist.lock( ); + playlist.clear( ); + playlist.append( producer ); + playlist.unlock( ); + return new Response( 200, "OK" ); + } + return new Response( 400, "Invalid" ); + } + + With this method, each service pushed into the server will automatically + replace whatever is currently playing. + + Note that the 'received' method is not invoked by default - if you wish to + receive the XML document and carry out any additional processing prior to + processing, you should set the 'push-parser-off' property on the server to 1. + This can be done by placing the following line in your classes constructor: + + set( "push-parser-off", 1 ); + + When this property is set, the received method is used instead of the push - + in this scenario, your implementation is responsible for all handling + of the document. + + To simulate this, you can try the following method: + + Response *received( char *command, char *document ) + { + cerr << document; + Producer producer( "westley-xml", document ); + return push( command, &producer ); + } + + When you push your videos in to the server via the inigo command above (or + from other tools, such as those in the shotcut suite), you will see the xml + in the servers stderr output. If you need to carry out some operations on the + xml document (such as replacing low quality videos used in the editing process + with their original) the received mechanism is the one that you would want to + use. + + +OTHER MANIPULATIONS + + What you do with the received MLT Service is largely up to you. As shown above, + you have flexibility in how the item is scheduled and you can carry out + manipulations on either the xml document and/or the deserialised producer. + + Typically, shotcut and inigo produce 'tractor' objects - these can be easily + manipulated in the push method - for example, to remove a track from the + output, we could do something like: + + Response *push( char *command, Service *service ) + { + Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) ); + Tractor *tractor( *service ); + if ( tractor.is_valid( ) && playlist.is_valid( ) ) + { + // Remove track 2 (NB: tracks are indexed from 0 like everything else) + Producer *producer = tractor.track( 2 ); + Playlist track( producer ); + + // If we have a valid track then hide video and audio + // This is a bit pattern - 1 is video, 2 is audio + if ( track.is_valid( ) ) + track.set( "hide", 3 ); + + // You need to delete the reference to the playlist producer here + delete producer; + + // Play it + playlist.lock( ); + playlist.clear( ); + playlist.append( producer ); + playlist.unlock( ); + return new Response( 200, "OK" ); + } + return new Response( 400, "Invalid" ); + } + + +EVENT HANDLING + + The MLT framework generates events which your custom server can use to do + various runtime manipulations. For the purpose of this document, I'll focus + on 'consumer-frame-render' - this event is fired immediately before a frame + is rendered. + + See example in test/server.cpp + + +DISABLING DVCP + + In some cases, it is desirable to fully disable the entire DVCP command set + and handle the PUSH in an application specific way (for example, the shotcut + applications all do this). The simplest way of doing this is to generate a + response that signifies the rejection of the command. In this example, the + 'shutdown' command is also handled: + + Response *execute( char *command ) + { + if ( !strcmp( command, "shutdown" ) ) + exit( 0 ); + return new Response( 400, "Invalid Command" ); + } + + If you use this method in the code above, your server does nothing - no units + are defined, so even a PUSH will be rejected. + + + diff --git a/HOWTO b/HOWTO new file mode 100644 index 0000000..dbeca9a --- /dev/null +++ b/HOWTO @@ -0,0 +1,473 @@ +INTRODUCTION +------------ + + This document provides a brief tutorial on the use of the mlt++ wrapper + and bindings. + + +Hello World +----------- + + The mlt++ wrapper is a c++ wrapper for the mlt C library. As such, it + provides clean C++ access to the underlying library. + + An example of use is as follows: + + #include + using namespace Mlt; + + int main( void ) + { + Factory::init( ); + Producer p( "pango:", "Hello World" ); + Consumer c( "sdl" ); + c.connect( p ); + c.run( ); + return 0; + } + + This is a fairly typical example of mlt++ usage - create a 'producer' (an + object which produces 'frames'), create a 'consumer' (an object which consumes + frames), connect them together, start the consumer and wait until done (here + we just wait for the user to close the window). + + In this case, we construct a window as a consumer using the 'sdl' consumer + (SDL is a standard portable library which provides platform independent + access to accelerated video display and audio) and use the 'pango' + producer to generate frames with the words 'Hello World' (pango is a + library from the gtk toolkit). + + The main point of this example is to show that mlt uses existing libraries + to provide its functionality - this keeps the framework itself very small. + + Note that mlt is designed to be housed in GUI or server type applications - + typically, applications don't wait around for the consumer to be stopped in + the manner shown. + + So far, we've introduced the Producer and Consumer mlt classes. We'll cover + each of these in more detail later in the tutorial, but for now, we'll + briefly cover the remaining classes. + + +Playlists +--------- + + Another simple class is the Playlist - this is direct extension of Producer + and it allows you to maintain a list of producer objects. + + As a simple example of the Playlist in action, we'll convert the example + above into an application which plays multiple video or audio files. + + #include + using namespace Mlt; + + int main( int argc, char **argv ) + { + Factory::init( ); + Playlist list; + for ( int i = 1; i < argc; i ++ ) + { + Producer p( argv[i] ); + if ( p.is_valid( ) ) + list.append( p ); + } + Consumer c( "sdl" ); + c.connect( list ); + c.run( ); + return 0; + } + + Now you can run the program as: + + ./player *.avi *.mp3 *.jpg etc + + In this case, we construct a playlist by simply appending producers to it. + Notice that although the scope of the Producer is limited to the inner + for loop, we can safely add it to the playlist - this is due to the fact + that all mlt objects maintain reference counts and no object is really + destroyed until all the references are gone. In this case, when the list + object goes out of scope, all the producers we created will automatically + be destroyed. + + +Filters +------- + + So far, we've shown how you can load and play media. We've given a brief + intro to the Playlist container, now it's time to start manipulating + things... + + For the next example, I'll add a 'watermark' to the video - a watermark + is used by broadcasters to brand the channel and normally consists of a + logo of some sort. We'll just use some black text on a partially + transparent red background. + + #include + using namespace Mlt; + + int main( int argc, char **argv ) + { + Factory::init( ); + Playlist list; + for ( int i = 1; i < argc; i ++ ) + { + Producer p( argv[i] ); + if ( p.is_valid( ) ) + list.append( p ); + } + Filter f( "watermark", "pango:" ); + f.set( "producer.text", "MLT++" ); + f.set( "producer.fgcolour", "0x000000ff" ); + f.set( "producer.bgcolour", "0xff000080" ); + list.attach( f ); + Consumer c( "sdl" ); + c.connect( list ); + c.run( ); + return 0; + } + + Notice that the watermark filter reuses the 'pango' producer we showed in the + first example. In fact, you could use any producer here - if you wanted to + use a graphic or a video, you would just construct the filter with a full path + to that as the second argument. + + We manipulate the filter using the set method - this method was also shown + in the first example. + + Finally, we attach the filter to the playlist. This ensure that all frames + that are obtained from the playlist are watermarked. + + +Cuts +---- + + When you add a clip to a playlist, the a cut object is created - this is merely a + wrapper for the producer, spanning the specified in and out points. + + Whenever you retrieve a clip from a playlist, you will always get a cut object. + This allows you to attach filters to a specific part of a producer and should + the position of the cut in the playlist change, then the filter will remain + correctly associated to it. + + A producer and a cut are generally identical in behaviour, but should you need to + distinguish between them, you can use: + + if ( producer.is_cut( ) ) + + and to retrieve the parent of a cut, you can use: + + Producer parent = producer.parent_cut( ); + + Filters that are attached directly to a parent are executed before any filters + attached to the cut. + + +Tractor +------- + + A tractor is an object that allows the manipulation of multiple video and audio + tracks. + + Stepping away from the player example we've been tinkering with for a minute, + let's assume we want to do something like dub a video with some audio. This + a very trivial thing to do: + + Tractor *dub( char *video_file, char *audio_file ) + { + Tractor *tractor = new Tractor( ); + Producer video( video_file ); + Producer audio( audio_file ); + tractor->set_track( video, 0 ); + tractor->set_track( audio, 1 ); + return tractor; + } + + That's all that needs to be done - you can now connect the returned object to a + consumer, or add it to a playlist, or even apply it as a track to another tractor. + + +Transition +---------- + + Let's now assume we want to mix the audio between two tracks - to do this, we + need to introduce the concept of a transition. A transition in mlt is a service + which combines frames from two producers to produce a new frame. + + Tractor *mix( char *video_file, char *audio_file ) + { + Tractor *tractor = new Tractor( ); + Transition mix( "mix" ); + Producer video( video_file ); + Producer audio( audio_file ); + tractor.set_track( video, 0 ); + tractor.set_track( audio, 1 ); + tractor.field.plant_transition( mix, 0, 1 ); + return tractor; + } + + The tractor returned will now mix the audio from the original video and the + audio. + + +Mix +--- + + There is a convenience function which simplifies the process of applying + transitions betwee adjacent cuts on a playlist. This is often preferable + to use over the constuction of your own tractor and transition set up. + + To apply a 25 frame luma transition between the first and second cut on + the playlist, you could use: + + Transition luma; + playlist.mix( 0, 25, luma ); + + +Events +------ + + Typically, applications need to be informed when changes occur in an mlt++ object. + This facilitates application services such as undo/redo management, or project + rendering in a timeline type widget and many other types of operations which an + application needs. + + As an example, consider the following: + + class Westley + { + private: + Consumer consumer; + Tractor &tractor; + public: + Westley( MltTractor &tractor ) : + tractor( tractor ), + consumer( "westley" ) + { + consumer.connect( tractor ); + tractor.listen( tractor, "producer-changed", + ( mlt_listener )Westley::listener ); + } + + static void listener( Properties *tractor, Westley *object ) + { + object->activate( ); + } + + void activate( ) + { + consumer.start( ); + } + }; + + Now, each time the tractor is changed, the westley representation is output to + stderr. + + +Servers and Westley Docs +------------------------ + + One of the key features of MLT is its server capabilities. This feature + allows you to pass westley documents seamlessly from one process to + another and even to different computers on your network. + + The miracle playout server is one such example of an application which + uses this functionality - you can build your own servers into your own + processes with ease. + + A server process would be running as follows: + + #include + using namespace Mlt; + + int main( void ) + { + Miracle miracle( "miracle", 5250 ); + miracle.start( ); + miracle.execute( "uadd sdl" ); + miracle.execute( "play u0" ); + miracle.wait_for_shutdown( ); + return 0; + } + + Typically, when you have an MLT object such as a producer or a playlist, + you can send a westley representation of this to a running server with: + + Conumser valerie( "valerie", "localhost:5250" ); + valerie.connect( producer ); + valerie.start( ); + + The effect of the push will be to append the producer on to the first + unit (u0). + + You can completely customise the miracle server - an example of this + is shown below. + + +That's All Folks... +------------------- + + And that, believe it or not, is a fairly complete summary of the classes you'll + typically be interfacing with in mlt++. Obviously, there's a little more to it + than this - a couple of intrisinc classes have been glossed over (notably, the + Properties and Service base classes). The next section will cover all of the + above, but in much more detail... + + +DIGGING DEEPER +-------------- + + The previous section was designed to give you a whistle stop tour through the major + framework classes. This section will take you through the scenic route. + + +Introducing Base Classes +------------------------ + + Services in mlt are the collective noun for Producers, Filters, Transitions and + Consumer. A Service is also the base class from which all of these classes + extend. It provides the basic connectivity which has been shown throughout the + examples in the previous section. + + Properties are the main way in which we communicate with the Services - + essentially, it provides get/set methods for named values. All services extend + Properties. + + +Properties +---------- + + Properties provide the general mechanism for communicating with Services - + through the Properties interface, we are able to manipulate and serialise + a services state. + + For example, to dump all the properties to stdout, you can use something + like: + + void dump( Properties &properties ) + { + for ( int i = 0; i < properties.count( ); i ++ ) + cout << Properties.get_name( i ) << " = " << Properties.get( i ) << endl; + } + + Note that the properties object handles type conversion, so the following + is acceptable: + + properties.set( "hello", "10.5" ); + int hello_int = properties.get_int( "hello" ); + double hello_double = properties.get_double( "hello" ); + + A couple of convenience methods are provide to examine or serialise property + objects. + + For example: + + properties.debug( ); + + will report all serialisable properties on stderr, in the form: + + Object: [ ref=1, in=0, out=0, track=0, u=75, v=150, _unique_id=15, + mlt_type=filter, mlt_service=sepia ] + + +Services +-------- + + Typically, all the services are constructed via the specific classes + constructor. Often, you will receive Service objects rather than their + specific type. In order to access the extended classes interface, + you will need to create a reference. + + For example, given an arbitrary Service object, you can determine its + type by using the type method - this will return a 'service_type' which + has values of producer_type, filter_type etc. Alternatively, you can + create a wrapping object and check on its validity. + + bool do_we_have_a_producer( Service &service ) + { + Producer producer( service ); + return producer.is_valid( ); + } + + +Events +------ + + +Servers and Westley Docs +------------------------ + + For various reasons, you might want to serialise a producer to a string. + To do this, you just need to specify a property to write to: + + Consumer westley( "westley", "buffer" ); + westley.connect( producer ); + westley.start( ); + buffer = westley.get( "buffer" ); + + You can use any name you want, and you can change it using the "resource" + property. Any name with a '.' in it is considered to be a file. Hence, you + can use a westley consumer to store multiple instances of the same MLT + object - useful if you want to provide undo/redo capabilities in an + editing application. + + Should you receive an xml document as a string, and you want to send it + on to a server, you can use: + + Conumser valerie( "valerie", "localhost:5250" ); + valerie.set( "westley", buffer ); + valerie.start( ); + + If you need to obtain an MLT object from a string: + + Producer producer( "westley-xml", buffer ); + + The following shows a working example of an extended server: + + class ShotcutServer : public Miracle + { + public: + ShotcutServer( char *id, int port ) : + Miracle( id, port ) + { + } + + void set_receive_doc( bool doc ) + { + set( "push-parser-off", doc ); + } + + // Reject all commands other than push/receive + Response *execute( char *command ) + { + valerie_response response = valerie_response_init( ); + valerie_response_set_error( response, 400, "Not OK" ); + return new Response( response ); + } + + // Push document handler + Response *received( char *command, char *doc ) + { + valerie_response response = valerie_response_init( ); + // Use doc in some way and assign Response + if ( doc != NULL ) + valerie_response_set_error( response, 200, "OK" ); + return new Response( response ); + } + + // Push service handler + Response *push( char *command, Service *service ) + { + valerie_response response = valerie_response_init( ); + // Use service in some way and assign Response + if ( service != NULL ) + valerie_response_set_error( response, 200, "OK" ); + return new Response( response ); + } + }; + + NB: Should you be incorporating this into a GUI application, remember that the + execute, received and push methods are invoked from a thread - make sure that + you honour the locking requirements of your GUI toolkit before interacting with + the UI. + + diff --git a/LGPL b/LGPL new file mode 100644 index 0000000..fc8a5de --- /dev/null +++ b/LGPL @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4833cfa --- /dev/null +++ b/Makefile @@ -0,0 +1,10 @@ +include config.mak + +all clean distclean install uninstall: + $(MAKE) DESTDIR=$(DESTDIR) -C src $@ + $(MAKE) -C test $@ + +dist: + [ -d "mlt++-$(version)" ] && rm -rf "mlt++-$(version)" || echo -n + svn export . "mlt++-$(version)" + tar -cvzf "mlt++-$(version).tar.gz" "mlt++-$(version)" diff --git a/README b/README new file mode 100644 index 0000000..24b4d85 --- /dev/null +++ b/README @@ -0,0 +1,135 @@ +MLT++ +----- + + This mlt sub-project provides a C++ wrapping for the MLT library. + +INSTALLATION +------------ + + ./configure [ --prefix=path ] + make + make install + +USAGE +----- + + Use the following definitions in a Makefile to compile and link with mlt++: + + CXXFLAGS=`mlt-config -Wall` + LDFLAGS=-lmlt++ + + Include files for the classes can either be explicitly included, ie: + + #include + etc + + Or you can include all using: + + #include + + All definitions are placed in an Mlt namespace, and adhere closely to the C + naming convention. Mappings always follow the pattern: + + Factory methods: + + mlt_factory_init ==> Mlt::Factory::init + mlt_factory_producer ==> Mlt::Factory::producer + mlt_factory_filter ==> Mlt::Factory::filter + mlt_factory_transition ==> Mlt::Factory::transition + mlt_factory_consumer ==> Mlt::Factory::consumer + mlt_factory_close ==> Mlt::Factory::close + + NB: Factory usage for service construction is optional. + + Types: + + mlt_properties ==> Mlt::Properties + mlt_frame ==> Mlt::Frame + mlt_service ==> Mlt::Service + mlt_producer ==> Mlt::Producer + mlt_filter ==> Mlt::Filter + mlt_transition ==> Mlt::Transition + mlt_consumer ==> Mlt::Consumer + + Methods: + + mlt_type_method ==> Mlt::Type.method + ie: mlt_playlist_append ==> Mlt::Playlist.append + + Parent methods are available directly on children. + + Additionally, you can specify: + + using namespace Mlt; + + To avoid the enforced use of the Mlt:: prefix. + + Enumerators and macros are reused directly from the C library. + +CLASS HIERARCHY +--------------- + + The currently mapped objects are shown in the following hierarchy: + + Factory + Properties + Frame + Service + Consumer + Field + Filter + Multitrack + Producer + Playlist + Tractor + Transition + + An additional set of classes allow apps to behave as, and communicate with, + client/server components - these components provide MLT with unique + possibilties for process to process or system to system communications. + + Miracle + Response + +SPECIAL CASES +------------- + + Care should be taken with wrapper objects. + + Taking, as an example, the C function that returns the immediate consumer of + a service: + + mlt_service mlt_service_consumer( mlt_service ); + + This maps to: + + Mlt::Service *Mlt::Service.consumer( ); + + Note that you get an object back - it is never the original c++ object, but + a wrapping object. This is done to keep consistency with the C api which may + instantiate C instances - therefore it cannot be assumed that a C++ object + exists for all mlt service instances. + + As such, it is mandatory that you delete these objects. The original will + not be affected. However, all other modifications (to properties or its + state of connection) will be reflected in the original object. + + This approach excludes the use of RTTI to determine the real type of the + object - this can only be done by parsing the objects properties. + + Objects may be invalid - always use the is_valid method to check validity + before use. + +LIMITATIONS +----------- + + The mechanisms for the definition of new services are deliberately + excluded from the C++ wrappings - this is done to ensure that service + networks constructed can be serialised and used by existing applications + which are based on the C API (such as miracle). + +SWIG +---- + + Experimental swig bindings based on mlt++ are provided. + diff --git a/config.mak b/config.mak new file mode 100644 index 0000000..ac8f606 --- /dev/null +++ b/config.mak @@ -0,0 +1,8 @@ +version=0.2.5 +prefix=/usr +libdir=/usr/lib +targetos=Linux +LIBSUF=.so +CXXFLAGS+=-pthread -Wall -fPIC -I/usr/include -I/usr/include/mlt -D_REENTRANT +LIBFLAGS=-shared +LDFLAGS+=-L/usr/lib -lmlt -L/usr/lib -lmiracle diff --git a/mlt++.sln b/mlt++.sln new file mode 100644 index 0000000..7daef64 --- /dev/null +++ b/mlt++.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mlt++", "mlt++.vcproj", "{31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}.Debug.ActiveCfg = Debug|Win32 + {31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}.Debug.Build.0 = Debug|Win32 + {31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}.Release.ActiveCfg = Release|Win32 + {31B6CBDB-6A84-4BC7-AACF-A1BCE02444FD}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/mlt++.vcproj b/mlt++.vcproj new file mode 100644 index 0000000..18ed892 --- /dev/null +++ b/mlt++.vcproj @@ -0,0 +1,265 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..2ff92e8 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,61 @@ +include ../config.mak +INSTALL = install + +ifneq ($(targetos), Darwin) +NAME = libmlt++$(LIBSUF) +TARGET = $(NAME).$(version) +LIBFLAGS += -Wl,-soname,$(TARGET) +else +NAME = libmlt++$(LIBSUF) +TARGET = libmlt++.$(version)$(LIBSUF) +LIBFLAGS += -install_name $(libdir)/$(TARGET) +endif + +OBJS = MltConsumer.o \ + MltDeque.o \ + MltEvent.o \ + MltFactory.o \ + MltField.o \ + MltFilter.o \ + MltFilteredConsumer.o \ + MltFrame.o \ + MltGeometry.o \ + MltMiracle.o \ + MltMultitrack.o \ + MltParser.o \ + MltPlaylist.o \ + MltProducer.o \ + MltProperties.o \ + MltPushConsumer.o \ + MltResponse.o \ + MltService.o \ + MltTokeniser.o \ + MltTractor.o \ + MltTransition.o + +SRCS = $(OBJS:.o=.cpp) +HEADERS = config.h Mlt.h $(OBJS:.o=.h) + +all: $(TARGET) + +$(TARGET): $(OBJS) + $(CXX) $(LIBFLAGS) -o $@ $(OBJS) $(LDFLAGS) -L/usr/kde3/lib + ln -sf $(TARGET) $(NAME) + +clean: + $(RM) $(OBJS) $(TARGET) $(NAME) + +distclean: clean + +install: + $(INSTALL) -d "$(DESTDIR)$(libdir)" + $(INSTALL) -m 755 $(TARGET) $(DESTDIR)$(libdir) + ln -sf $(TARGET) $(DESTDIR)$(libdir)/$(NAME) + $(INSTALL) -d "$(DESTDIR)$(prefix)/include/mlt++" + $(INSTALL) -m 644 $(HEADERS) "$(DESTDIR)$(prefix)/include/mlt++" + /sbin/ldconfig || true + +uninstall: + rm -f "$(DESTDIR)$(libdir)/$(TARGET)" + rm -f "$(DESTDIR)$(libdir)/$(NAME)" + rm -rf "$(DESTDIR)$(prefix)/include/mlt++" diff --git a/src/Mlt.h b/src/Mlt.h new file mode 100644 index 0000000..18975fa --- /dev/null +++ b/src/Mlt.h @@ -0,0 +1,50 @@ +/** + * Mlt.h - Convenience header file for all mlt++ objects + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_H_ +#define _MLTPP_H_ + +#include "MltConsumer.h" +#include "MltDeque.h" +#include "MltEvent.h" +#include "MltFactory.h" +#include "MltField.h" +#include "MltFilter.h" +#include "MltFilteredConsumer.h" +#include "MltFrame.h" +#include "MltGeometry.h" +#ifndef WIN32 +#include "MltMiracle.h" +#endif +#include "MltMultitrack.h" +#include "MltParser.h" +#include "MltPlaylist.h" +#include "MltProducer.h" +#include "MltProperties.h" +#include "MltPushConsumer.h" +#ifndef WIN32 +#include "MltResponse.h" +#endif +#include "MltService.h" +#include "MltTokeniser.h" +#include "MltTractor.h" +#include "MltTransition.h" + +#endif diff --git a/src/MltConsumer.cpp b/src/MltConsumer.cpp new file mode 100644 index 0000000..d6d3692 --- /dev/null +++ b/src/MltConsumer.cpp @@ -0,0 +1,129 @@ +/** + * MltConsumer.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include "MltConsumer.h" +#include "MltEvent.h" +using namespace Mlt; + +Consumer::Consumer( ) : + instance( NULL ) +{ + instance = mlt_factory_consumer( NULL, NULL ); +} + +Consumer::Consumer( char *id, char *arg ) : + instance( NULL ) +{ + if ( id == NULL || arg != NULL ) + { + instance = mlt_factory_consumer( id, arg ); + } + else + { + if ( strchr( id, ':' ) ) + { + char *temp = strdup( id ); + char *arg = strchr( temp, ':' ) + 1; + *( arg - 1 ) = '\0'; + instance = mlt_factory_consumer( temp, arg ); + free( temp ); + } + else + { + instance = mlt_factory_consumer( id, NULL ); + } + } +} + +Consumer::Consumer( Service &consumer ) : + instance( NULL ) +{ + if ( consumer.type( ) == consumer_type ) + { + instance = ( mlt_consumer )consumer.get_service( ); + inc_ref( ); + } +} + +Consumer::Consumer( Consumer &consumer ) : + instance( consumer.get_consumer( ) ) +{ + inc_ref( ); +} + +Consumer::Consumer( mlt_consumer consumer ) : + instance( consumer ) +{ + inc_ref( ); +} + +Consumer::~Consumer( ) +{ + mlt_consumer_close( instance ); +} + +mlt_consumer Consumer::get_consumer( ) +{ + return instance; +} + +mlt_service Consumer::get_service( ) +{ + return mlt_consumer_service( get_consumer( ) ); +} + +int Consumer::connect( Service &service ) +{ + return connect_producer( service ); +} + +int Consumer::start( ) +{ + return mlt_consumer_start( get_consumer( ) ); +} + +void Consumer::purge( ) +{ + mlt_consumer_purge( get_consumer( ) ); +} + +int Consumer::stop( ) +{ + return mlt_consumer_stop( get_consumer( ) ); +} + +bool Consumer::is_stopped( ) +{ + return mlt_consumer_is_stopped( get_consumer( ) ) != 0; +} + +int Consumer::run( ) +{ + int ret = start( ); + if ( !is_stopped( ) ) + { + Event *e = setup_wait_for( "consumer-stopped" ); + wait_for( e ); + delete e; + } + return ret; +} diff --git a/src/MltConsumer.h b/src/MltConsumer.h new file mode 100644 index 0000000..77e4d12 --- /dev/null +++ b/src/MltConsumer.h @@ -0,0 +1,56 @@ +/** + * MltConsumer.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_CONSUMER_H_ +#define _MLTPP_CONSUMER_H_ + +#include "config.h" + +#include + +#include "MltService.h" + +namespace Mlt +{ + class Service; + + class MLTPP_DECLSPEC Consumer : public Service + { + private: + mlt_consumer instance; + public: + Consumer( ); + Consumer( char *id , char *service = NULL ); + Consumer( Service &consumer ); + Consumer( Consumer &consumer ); + Consumer( mlt_consumer consumer ); + virtual ~Consumer( ); + virtual mlt_consumer get_consumer( ); + mlt_service get_service( ); + virtual int connect( Service &service ); + int run( ); + int start( ); + void purge( ); + int stop( ); + bool is_stopped( ); + }; +} + +#endif diff --git a/src/MltDeque.cpp b/src/MltDeque.cpp new file mode 100644 index 0000000..89d90d4 --- /dev/null +++ b/src/MltDeque.cpp @@ -0,0 +1,68 @@ +/** + * MltDeque.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltDeque.h" +using namespace Mlt; + +Deque::Deque( ) +{ + deque = mlt_deque_init( ); +} + +Deque::~Deque( ) +{ + mlt_deque_close( deque ); +} + +int Deque::count( ) +{ + return mlt_deque_count( deque ); +} + +int Deque::push_back( void *item ) +{ + return mlt_deque_push_back( deque, item ); +} + +void *Deque::pop_back( ) +{ + return mlt_deque_pop_back( deque ); +} + +int Deque::push_front( void *item ) +{ + return mlt_deque_push_front( deque, item ); +} + +void *Deque::pop_front( ) +{ + return mlt_deque_pop_front( deque ); +} + +void *Deque::peek_back( ) +{ + return mlt_deque_peek_back( deque ); +} + +void *Deque::peek_front( ) +{ + return mlt_deque_peek_front( deque ); +} + diff --git a/src/MltDeque.h b/src/MltDeque.h new file mode 100644 index 0000000..0baf7be --- /dev/null +++ b/src/MltDeque.h @@ -0,0 +1,47 @@ +/** + * MltDeque.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_DEQUE_H +#define _MLTPP_DEQUE_H + +#include "config.h" + +#include + +namespace Mlt +{ + class MLTPP_DECLSPEC Deque + { + private: + mlt_deque deque; + public: + Deque( ); + ~Deque( ); + int count( ); + int push_back( void *item ); + void *pop_back( ); + int push_front( void *item ); + void *pop_front( ); + void *peek_back( ); + void *peek_front( ); + }; +} + +#endif diff --git a/src/MltEvent.cpp b/src/MltEvent.cpp new file mode 100644 index 0000000..d1bba06 --- /dev/null +++ b/src/MltEvent.cpp @@ -0,0 +1,61 @@ +/** + * MltEvent.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltEvent.h" +using namespace Mlt; + + +Event::Event( mlt_event event ) : + instance( event ) +{ + mlt_event_inc_ref( instance ); +} + +Event::Event( Event &event ) : + instance( event.get_event( ) ) +{ + mlt_event_inc_ref( instance ); +} + +Event::~Event( ) +{ + mlt_event_close( instance ); +} + +mlt_event Event::get_event( ) +{ + return instance; +} + +bool Event::is_valid( ) +{ + return instance != NULL; +} + +void Event::block( ) +{ + mlt_event_block( get_event( ) ); +} + +void Event::unblock( ) +{ + mlt_event_unblock( get_event( ) ); +} + diff --git a/src/MltEvent.h b/src/MltEvent.h new file mode 100644 index 0000000..ed44882 --- /dev/null +++ b/src/MltEvent.h @@ -0,0 +1,46 @@ +/** + * MltEvent.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_EVENT_H_ +#define _MLTPP_EVENT_H_ + +#include "config.h" + +#include + +namespace Mlt +{ + class MLTPP_DECLSPEC Event + { + private: + mlt_event instance; + public: + Event( mlt_event ); + Event( Event & ); + ~Event( ); + mlt_event get_event( ); + bool is_valid( ); + void block( ); + void unblock( ); + }; +} + +#endif + diff --git a/src/MltFactory.cpp b/src/MltFactory.cpp new file mode 100644 index 0000000..07a8f06 --- /dev/null +++ b/src/MltFactory.cpp @@ -0,0 +1,75 @@ +/** + * MltFactory.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltFactory.h" +#include "MltProducer.h" +#include "MltFilter.h" +#include "MltTransition.h" +#include "MltConsumer.h" +using namespace Mlt; + +int Factory::init( char *arg ) +{ + return mlt_factory_init( arg ); +} + +Properties *Factory::event_object( ) +{ + return new Properties( mlt_factory_event_object( ) ); +} + +Producer *Factory::producer( char *id, char *arg ) +{ + return new Producer( id, arg ); +} + +Filter *Factory::filter( char *id, char *arg ) +{ + return new Filter( id, arg ); +} + +Transition *Factory::transition( char *id, char *arg ) +{ + return new Transition( id, arg ); +} + +Consumer *Factory::consumer( char *id, char *arg ) +{ + return new Consumer( id, arg ); +} + +#ifdef WIN32 +char *Factory::getenv( const char *name ) +{ + return mlt_getenv( name ); +} + +int Factory::setenv( const char *name, const char *value ) +{ + return mlt_setenv( name, value ); +} +#endif + +void Factory::close( ) +{ + mlt_factory_close( ); +} + + diff --git a/src/MltFactory.h b/src/MltFactory.h new file mode 100644 index 0000000..03adc64 --- /dev/null +++ b/src/MltFactory.h @@ -0,0 +1,57 @@ +/** + * MltFactory.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_FACTORY_H_ +#define _MLTPP_FACTORY_H_ + +#include "config.h" + +#ifdef SWIG +#define MLTPP_DECLSPEC +#endif + +#include + +namespace Mlt +{ + class Properties; + class Producer; + class Filter; + class Transition; + class Consumer; + + class MLTPP_DECLSPEC Factory + { + public: + static int init( char *arg = NULL ); + static Properties *event_object( ); + static Producer *producer( char *id, char *arg = NULL ); + static Filter *filter( char *id, char *arg = NULL ); + static Transition *transition( char *id, char *arg = NULL ); + static Consumer *consumer( char *id, char *arg = NULL ); +#ifdef WIN32 + static char *getenv( const char * ); + static int setenv( const char *, const char * ); +#endif + static void close( ); + }; +} + +#endif diff --git a/src/MltField.cpp b/src/MltField.cpp new file mode 100644 index 0000000..e37a17f --- /dev/null +++ b/src/MltField.cpp @@ -0,0 +1,63 @@ +/** + * MltField.cpp - Field wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltField.h" +#include "MltFilter.h" +#include "MltTransition.h" +using namespace Mlt; + +Field::Field( mlt_field field ) : + instance( field ) +{ + inc_ref( ); +} + +Field::Field( Field &field ) : + instance( field.get_field( ) ) +{ + inc_ref( ); +} + +Field::~Field( ) +{ + mlt_field_close( instance ); +} + +mlt_field Field::get_field( ) +{ + return instance; +} + +mlt_service Field::get_service( ) +{ + return mlt_field_service( get_field( ) ); +} + +int Field::plant_filter( Filter &filter, int track ) +{ + return mlt_field_plant_filter( get_field( ), filter.get_filter( ), track ); +} + +int Field::plant_transition( Transition &transition, int a_track, int b_track ) +{ + return mlt_field_plant_transition( get_field( ), transition.get_transition( ), a_track, b_track ); +} + + diff --git a/src/MltField.h b/src/MltField.h new file mode 100644 index 0000000..cbaca7f --- /dev/null +++ b/src/MltField.h @@ -0,0 +1,52 @@ +/** + * MltField.h - Field wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_FIELD_H_ +#define _MLTPP_FIELD_H_ + +#include "config.h" + +#include + +#include "MltService.h" + +namespace Mlt +{ + class Service; + class Filter; + class Transition; + + class MLTPP_DECLSPEC Field : public Service + { + private: + mlt_field instance; + public: + Field( mlt_field field ); + Field( Field &field ); + virtual ~Field( ); + mlt_field get_field( ); + mlt_service get_service( ); + int plant_filter( Filter &filter, int track = 0 ); + int plant_transition( Transition &transition, int a_track = 0, int b_track = 1 ); + }; +} + +#endif + diff --git a/src/MltFilter.cpp b/src/MltFilter.cpp new file mode 100644 index 0000000..e7d7fb1 --- /dev/null +++ b/src/MltFilter.cpp @@ -0,0 +1,111 @@ +/** + * MltFilter.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include "MltFilter.h" +using namespace Mlt; + +Filter::Filter( char *id, char *arg ) : + instance( NULL ) +{ + if ( arg != NULL ) + { + instance = mlt_factory_filter( id, arg ); + } + else + { + if ( strchr( id, ':' ) ) + { + char *temp = strdup( id ); + char *arg = strchr( temp, ':' ) + 1; + *( arg - 1 ) = '\0'; + instance = mlt_factory_filter( temp, arg ); + free( temp ); + } + else + { + instance = mlt_factory_filter( id, NULL ); + } + } +} + +Filter::Filter( Service &filter ) : + instance( NULL ) +{ + if ( filter.type( ) == filter_type ) + { + instance = ( mlt_filter )filter.get_service( ); + inc_ref( ); + } +} + +Filter::Filter( Filter &filter ) : + instance( filter.get_filter( ) ) +{ + inc_ref( ); +} + +Filter::Filter( mlt_filter filter ) : + instance( filter ) +{ + inc_ref( ); +} + +Filter::~Filter( ) +{ + mlt_filter_close( instance ); +} + +mlt_filter Filter::get_filter( ) +{ + return instance; +} + +mlt_service Filter::get_service( ) +{ + return mlt_filter_service( get_filter( ) ); +} + +int Filter::connect( Service &service, int index ) +{ + return mlt_filter_connect( get_filter( ), service.get_service( ), index ); +} + +void Filter::set_in_and_out( int in, int out ) +{ + mlt_filter_set_in_and_out( get_filter( ), in, out ); +} + +int Filter::get_in( ) +{ + return mlt_filter_get_in( get_filter( ) ); +} + +int Filter::get_out( ) +{ + return mlt_filter_get_out( get_filter( ) ); +} + +int Filter::get_track( ) +{ + return mlt_filter_get_track( get_filter( ) ); +} + diff --git a/src/MltFilter.h b/src/MltFilter.h new file mode 100644 index 0000000..acb8711 --- /dev/null +++ b/src/MltFilter.h @@ -0,0 +1,54 @@ +/** + * MltFilter.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_FILTER_H_ +#define _MLTPP_FILTER_H_ + +#include "config.h" + +#include + +#include "MltService.h" + +namespace Mlt +{ + class Service; + + class MLTPP_DECLSPEC Filter : public Service + { + private: + mlt_filter instance; + public: + Filter( char *id, char *service = NULL ); + Filter( Service &filter ); + Filter( Filter &filter ); + Filter( mlt_filter filter ); + virtual ~Filter( ); + virtual mlt_filter get_filter( ); + mlt_service get_service( ); + int connect( Service &service, int index = 0 ); + void set_in_and_out( int in, int out ); + int get_in( ); + int get_out( ); + int get_track( ); + }; +} + +#endif diff --git a/src/MltFilteredConsumer.cpp b/src/MltFilteredConsumer.cpp new file mode 100644 index 0000000..6a59fb8 --- /dev/null +++ b/src/MltFilteredConsumer.cpp @@ -0,0 +1,118 @@ +/** + * MltFilteredConsumer.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltFilteredConsumer.h" +using namespace Mlt; + +FilteredConsumer::FilteredConsumer( char *id, char *arg ) : + Consumer( id, arg ) +{ + // Create a reference to the first service + first = new Service( *this ); +} + +FilteredConsumer::FilteredConsumer( Consumer &consumer ) : + Consumer( consumer ) +{ + // Create a reference to the first service + first = new Service( *this ); +} + +FilteredConsumer::~FilteredConsumer( ) +{ + // Delete the reference to the first service + delete first; +} + +int FilteredConsumer::connect( Service &service ) +{ + // All producers must connect to the first service, hence the use of the virtual here + return first->connect_producer( service ); +} + +int FilteredConsumer::attach( Filter &filter ) +{ + int error = 0; + if ( filter.is_valid( ) ) + { + Service *producer = first->producer( ); + error = filter.connect( *producer ); + if ( error == 0 ) + { + first->connect_producer( filter ); + delete first; + first = new Service( filter ); + } + delete producer; + } + else + { + error = 1; + } + return error; +} + +int FilteredConsumer::last( Filter &filter ) +{ + int error = 0; + if ( filter.is_valid( ) ) + { + Service *producer = this->producer( ); + error = filter.connect( *producer ); + if ( error == 0 ) + connect_producer( filter ); + delete producer; + } + else + { + error = 1; + } + return error; +} + +int FilteredConsumer::detach( Filter &filter ) +{ + if ( filter.is_valid( ) ) + { + Service *it = new Service( *first ); + while ( it->is_valid( ) && it->get_service( ) != filter.get_service( ) ) + { + Service *consumer = it->consumer( ); + delete it; + it = consumer; + } + if ( it->get_service( ) == filter.get_service( ) ) + { + Service *producer = it->producer( ); + Service *consumer = it->consumer( ); + consumer->connect_producer( *producer ); + Service dummy( NULL ); + it->connect_producer( dummy ); + if ( first->get_service( ) == it->get_service( ) ) + { + delete first; + first = new Service( *consumer ); + } + } + delete it; + } + return 0; +} + diff --git a/src/MltFilteredConsumer.h b/src/MltFilteredConsumer.h new file mode 100644 index 0000000..cd0dc84 --- /dev/null +++ b/src/MltFilteredConsumer.h @@ -0,0 +1,52 @@ +/** + * MltFilteredConsumer.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_FILTERED_CONSUMER_H_ +#define _MLTPP_FILTERED_CONSUMER_H_ + +#include "config.h" + +#include "MltConsumer.h" +#include "MltFilter.h" +#include "MltService.h" + +namespace Mlt +{ + class Consumer; + class Service; + class Filter; + + class MLTPP_DECLSPEC FilteredConsumer : public Consumer + { + private: + Service *first; + public: + FilteredConsumer( char *id, char *arg = NULL ); + FilteredConsumer( Consumer &consumer ); + virtual ~FilteredConsumer( ); + int connect( Service &service ); + int attach( Filter &filter ); + int last( Filter &filter ); + int detach( Filter &filter ); + }; +} + +#endif + diff --git a/src/MltFilteredProducer.cpp b/src/MltFilteredProducer.cpp new file mode 100644 index 0000000..031c8b9 --- /dev/null +++ b/src/MltFilteredProducer.cpp @@ -0,0 +1,86 @@ +/** + * MltFilteredProducer.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltFilteredProducer.h" +using namespace Mlt; + +FilteredProducer::FilteredProducer( char *id, char *arg ) : + Producer( id, arg ) +{ + // Create a reference to the last service + last = new Service( *this ); +} + +FilteredProducer::~FilteredProducer( ) +{ + // Delete the reference to the last service + delete last; +} + +int FilteredProducer::attach( Filter &filter ) +{ + int error = 0; + if ( filter.is_valid( ) ) + { + Service *consumer = last->consumer( ); + filter.connect_producer( *last ); + if ( consumer->is_valid( ) ) + consumer->connect_producer( filter ); + delete consumer; + delete last; + last = new Service( filter ); + } + else + { + error = 1; + } + return error; +} + +int FilteredProducer::detach( Filter &filter ) +{ + if ( filter.is_valid( ) ) + { + Service *it = new Service( *last ); + while ( it->is_valid( ) && it->get_service( ) != filter.get_service( ) ) + { + Service *producer = it->producer( ); + delete it; + it = producer; + } + if ( it->get_service( ) == filter.get_service( ) ) + { + Service *producer = it->producer( ); + Service *consumer = it->consumer( ); + if ( consumer->is_valid( ) ) + consumer->connect_producer( *producer ); + Producer dummy( "colour" ); + dummy.connect_producer( *it ); + if ( last->get_service( ) == it->get_service( ) ) + { + delete last; + last = new Service( *producer ); + } + } + delete it; + } + return 0; +} + diff --git a/src/MltFilteredProducer.h b/src/MltFilteredProducer.h new file mode 100644 index 0000000..578f7c5 --- /dev/null +++ b/src/MltFilteredProducer.h @@ -0,0 +1,49 @@ +/** + * MltFilteredProducer.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_FILTERED_PRODUCER_H_ +#define _MLTPP_FILTERED_PRODUCER_H_ + +#include "config.h" + +#include "MltProducer.h" +#include "MltFilter.h" +#include "MltService.h" + +namespace Mlt +{ + class Producer; + class Service; + class Filter; + + class MLTPP_DECLSPEC FilteredProducer : public Producer + { + private: + Service *last; + public: + FilteredProducer( char *id, char *arg = NULL ); + virtual ~FilteredProducer( ); + int attach( Filter &filter ); + int detach( Filter &filter ); + }; +} + +#endif + diff --git a/src/MltFrame.cpp b/src/MltFrame.cpp new file mode 100644 index 0000000..1970fdc --- /dev/null +++ b/src/MltFrame.cpp @@ -0,0 +1,89 @@ +/** + * MltFrame.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltFrame.h" +#include "MltProducer.h" +using namespace Mlt; + +Frame::Frame( mlt_frame frame ) : + instance( frame ) +{ + inc_ref( ); +} + +Frame::Frame( Frame &frame ) : + instance( frame.get_frame( ) ) +{ + inc_ref( ); +} + +Frame::~Frame( ) +{ + mlt_frame_close( instance ); +} + +mlt_frame Frame::get_frame( ) +{ + return instance; +} + +mlt_properties Frame::get_properties( ) +{ + return mlt_frame_properties( get_frame( ) ); +} + +uint8_t *Frame::get_image( mlt_image_format &format, int &w, int &h, int writable ) +{ + uint8_t *image = NULL; + if ( get_double( "consumer_aspect_ratio" ) == 0.0 ) + set( "consumer_aspect_ratio", 1.0 ); + mlt_frame_get_image( get_frame( ), &image, &format, &w, &h, writable ); + set( "format", format ); + set( "writable", writable ); + return image; +} + +unsigned char *Frame::fetch_image( mlt_image_format f, int w, int h, int writable ) +{ + uint8_t *image = NULL; + if ( get_double( "consumer_aspect_ratio" ) == 0.0 ) + set( "consumer_aspect_ratio", 1.0 ); + mlt_frame_get_image( get_frame( ), &image, &f, &w, &h, writable ); + set( "format", f ); + set( "writable", writable ); + return image; +} + +int16_t *Frame::get_audio( mlt_audio_format &format, int &frequency, int &channels, int &samples ) +{ + int16_t *audio = NULL; + mlt_frame_get_audio( get_frame( ), &audio, &format, &frequency, &channels, &samples ); + return audio; +} + +unsigned char *Frame::get_waveform( int w, int h ) +{ + return mlt_frame_get_waveform( get_frame( ), w, h ); +} + +Producer *Frame::get_original_producer( ) +{ + return new Producer( mlt_frame_get_original_producer( get_frame( ) ) ); +} diff --git a/src/MltFrame.h b/src/MltFrame.h new file mode 100644 index 0000000..45c10f3 --- /dev/null +++ b/src/MltFrame.h @@ -0,0 +1,52 @@ +/** + * MltFilter.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_FRAME_H_ +#define _MLTPP_FRAME_H_ + +#include "config.h" + +#include +#include "MltProperties.h" + +namespace Mlt +{ + class Properties; + class Producer; + + class MLTPP_DECLSPEC Frame : public Properties + { + private: + mlt_frame instance; + public: + Frame( mlt_frame frame ); + Frame( Frame &frame ); + virtual ~Frame( ); + virtual mlt_frame get_frame( ); + mlt_properties get_properties( ); + uint8_t *get_image( mlt_image_format &format, int &w, int &h, int writable = 0 ); + unsigned char *fetch_image( mlt_image_format format, int w, int h, int writable = 0 ); + int16_t *get_audio( mlt_audio_format &format, int &frequency, int &channels, int &samples ); + unsigned char *get_waveform( int w, int h ); + Producer *get_original_producer( ); + }; +} + +#endif diff --git a/src/MltGeometry.cpp b/src/MltGeometry.cpp new file mode 100644 index 0000000..976d681 --- /dev/null +++ b/src/MltGeometry.cpp @@ -0,0 +1,100 @@ +/** + * MltGeometry.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "MltGeometry.h" +using namespace Mlt; + +Geometry::Geometry( char *data, int length, int nw, int nh ) +{ + geometry = mlt_geometry_init( ); + parse( data, length, nw, nh ); +} + +Geometry::~Geometry( ) +{ + mlt_geometry_close( geometry ); +} + +int Geometry::parse( char *data, int length, int nw, int nh ) +{ + return mlt_geometry_parse( geometry, data, length, nw, nh ); +} + +// Fetch a geometry item for an absolute position +int Geometry::fetch( GeometryItem &item, float position ) +{ + return mlt_geometry_fetch( geometry, item.get_item( ), position ); +} + +int Geometry::fetch( GeometryItem *item, float position ) +{ + return mlt_geometry_fetch( geometry, item->get_item( ), position ); +} + +// Specify a geometry item at an absolute position +int Geometry::insert( GeometryItem &item ) +{ + return mlt_geometry_insert( geometry, item.get_item( ) ); +} + +int Geometry::insert( GeometryItem *item ) +{ + return mlt_geometry_insert( geometry, item->get_item( ) ); +} + +// Remove the key at the specified position +int Geometry::remove( int position ) +{ + return mlt_geometry_remove( geometry, position ); +} + +// Get the key at the position or the next following +int Geometry::next_key( GeometryItem &item, int position ) +{ + return mlt_geometry_next_key( geometry, item.get_item( ), position ); +} + +int Geometry::next_key( GeometryItem *item, int position ) +{ + return mlt_geometry_next_key( geometry, item->get_item( ), position ); +} + +int Geometry::prev_key( GeometryItem &item, int position ) +{ + return mlt_geometry_prev_key( geometry, item.get_item( ), position ); +} + +int Geometry::prev_key( GeometryItem *item, int position ) +{ + return mlt_geometry_prev_key( geometry, item->get_item( ), position ); +} + +// Serialise the current geometry +char *Geometry::serialise( int in, int out ) +{ + return mlt_geometry_serialise_cut( geometry, in, out ); +} + +char *Geometry::serialise( ) +{ + return mlt_geometry_serialise( geometry ); +} + diff --git a/src/MltGeometry.h b/src/MltGeometry.h new file mode 100644 index 0000000..7c21dcc --- /dev/null +++ b/src/MltGeometry.h @@ -0,0 +1,80 @@ +/** + * MltGeometry.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_GEOMETRY_H +#define _MLTPP_GEOMETRY_H + +#include "config.h" + +#include + +namespace Mlt +{ + // Just for consistent naming purposes + class MLTPP_DECLSPEC GeometryItem + { + private: + struct mlt_geometry_item_s item; + public: + mlt_geometry_item get_item( ) { return &item; } + bool key( ) { return item.key != 0; } + int frame( ) { return item.frame; } + void frame( int value ) { item.frame = value; } + float x( ) { return item.x; } + void x( float value ) { item.f[0] = 1; item.x = value; } + float y( ) { return item.y; } + void y( float value ) { item.f[1] = 1; item.y = value; } + float w( ) { return item.w; } + void w( float value ) { item.f[2] = 1; item.w = value; } + float h( ) { return item.h; } + void h( float value ) { item.f[3] = 1; item.h = value; } + float mix( ) { return item.mix; } + void mix( float value ) { item.f[4] = 1; item.mix = value; } + }; + + class MLTPP_DECLSPEC Geometry + { + private: + mlt_geometry geometry; + public: + Geometry( char *data = NULL, int length = 0, int nw = -1, int nh = -1 ); + ~Geometry( ); + int parse( char *data, int length, int nw = -1, int nh = -1 ); + // Fetch a geometry item for an absolute position + int fetch( GeometryItem &item, float position ); + int fetch( GeometryItem *item, float position ); + // Specify a geometry item at an absolute position + int insert( GeometryItem &item ); + int insert( GeometryItem *item ); + // Remove the key at the specified position + int remove( int position ); + // Get the key at the position or the next following + int next_key( GeometryItem &item, int position ); + int next_key( GeometryItem *item, int position ); + int prev_key( GeometryItem &item, int position ); + int prev_key( GeometryItem *item, int position ); + // Serialise the current geometry + char *serialise( int in, int out ); + char *serialise( ); + }; +} + +#endif + diff --git a/src/MltMiracle.cpp b/src/MltMiracle.cpp new file mode 100644 index 0000000..04f4d2c --- /dev/null +++ b/src/MltMiracle.cpp @@ -0,0 +1,157 @@ +/** + * MltMiracle.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltMiracle.h" +#include "MltService.h" +#include "MltResponse.h" +using namespace Mlt; + +#include + +static valerie_response mlt_miracle_execute( void *arg, char *command ) +{ + Miracle *miracle = ( Miracle * )arg; + if ( miracle != NULL ) + { + Response *response = miracle->execute( command ); + valerie_response real = valerie_response_clone( response->get_response( ) ); + delete response; + return real; + } + else + { + valerie_response response = valerie_response_init( ); + valerie_response_set_error( response, 500, "Invalid server" ); + return response; + } +} + +static valerie_response mlt_miracle_received( void *arg, char *command, char *doc ) +{ + Miracle *miracle = ( Miracle * )arg; + if ( miracle != NULL ) + { + Response *response = miracle->received( command, doc ); + if ( response != NULL ) + { + valerie_response real = valerie_response_clone( response->get_response( ) ); + delete response; + return real; + } + return NULL; + } + else + { + valerie_response response = valerie_response_init( ); + valerie_response_set_error( response, 500, "Invalid server" ); + return response; + } +} + +static valerie_response mlt_miracle_push( void *arg, char *command, mlt_service service ) +{ + Miracle *miracle = ( Miracle * )arg; + if ( miracle != NULL ) + { + Service input( service ); + Response *response = miracle->push( command, &input ); + valerie_response real = valerie_response_clone( response->get_response( ) ); + delete response; + return real; + } + else + { + valerie_response response = valerie_response_init( ); + valerie_response_set_error( response, 500, "Invalid server" ); + return response; + } +} + +Miracle::Miracle( char *name, int port, char *config ) : + Properties( false ) +{ + server = miracle_server_init( name ); + miracle_server_set_port( server, port ); + miracle_server_set_config( server, config ); +} + +Miracle::~Miracle( ) +{ + miracle_server_close( server ); +} + +mlt_properties Miracle::get_properties( ) +{ + return &server->parent; +} + +bool Miracle::start( ) +{ + if ( miracle_server_execute( server ) == 0 ) + { + _real = server->parser->real; + _execute = server->parser->execute; + _received = server->parser->received; + _push = server->parser->push; + server->parser->real = this; + server->parser->execute = mlt_miracle_execute; + server->parser->received = mlt_miracle_received; + server->parser->push = mlt_miracle_push; + } + return server->shutdown == 0; +} + +bool Miracle::is_running( ) +{ + return server->shutdown == 0; +} + +Response *Miracle::execute( char *command ) +{ + return new Response( _execute( _real, command ) ); +} + +Response *Miracle::received( char *command, char *doc ) +{ + return new Response( _received( _real, command, doc ) ); +} + +Response *Miracle::push( char *command, Service *service ) +{ + return new Response( _push( _real, command, service->get_service( ) ) ); +} + +void Miracle::wait_for_shutdown( ) +{ + struct timespec tm = { 1, 0 }; + while ( !server->shutdown ) + nanosleep( &tm, NULL ); +} + +void Miracle::log_level( int threshold ) +{ + miracle_log_init( log_stderr, threshold ); +} + +Properties *Miracle::unit( int index ) +{ + mlt_properties properties = miracle_server_fetch_unit( server, index ); + return properties != NULL ? new Properties( properties ) : NULL; +} diff --git a/src/MltMiracle.h b/src/MltMiracle.h new file mode 100644 index 0000000..eac9d95 --- /dev/null +++ b/src/MltMiracle.h @@ -0,0 +1,58 @@ +/** + * MltMiracle.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_MIRACLE_H_ +#define _MLTPP_MIRACLE_H_ + +#include +#include +#include "MltService.h" + +namespace Mlt +{ + class Properties; + class Service; + class Response; + + class Miracle : public Properties + { + private: + miracle_server server; + void *_real; + parser_execute _execute; + parser_received _received; + parser_push _push; + public: + Miracle( char *name, int port = 5250, char *config = NULL ); + virtual ~Miracle( ); + mlt_properties get_properties( ); + bool start( ); + bool is_running( ); + virtual Response *execute( char *command ); + virtual Response *received( char *command, char *doc ); + virtual Response *push( char *command, Service *service ); + void wait_for_shutdown( ); + static void log_level( int ); + Properties *unit( int ); + }; +} + +#endif + diff --git a/src/MltMultitrack.cpp b/src/MltMultitrack.cpp new file mode 100644 index 0000000..0b0aca2 --- /dev/null +++ b/src/MltMultitrack.cpp @@ -0,0 +1,85 @@ +/** + * MltMultitrack.h - Multitrack wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltMultitrack.h" +#include "MltProducer.h" +using namespace Mlt; + +Multitrack::Multitrack( mlt_multitrack multitrack ) : + instance( multitrack ) +{ + inc_ref( ); +} + +Multitrack::Multitrack( Service &multitrack ) : + instance( NULL ) +{ + if ( multitrack.type( ) == multitrack_type ) + { + instance = ( mlt_multitrack )multitrack.get_service( ); + inc_ref( ); + } +} + +Multitrack::Multitrack( Multitrack &multitrack ) : + instance( multitrack.get_multitrack( ) ) +{ + inc_ref( ); +} + +Multitrack::~Multitrack( ) +{ + mlt_multitrack_close( instance ); +} + +mlt_multitrack Multitrack::get_multitrack( ) +{ + return instance; +} + +mlt_producer Multitrack::get_producer( ) +{ + return mlt_multitrack_producer( get_multitrack( ) ); +} + +int Multitrack::connect( Producer &producer, int index ) +{ + return mlt_multitrack_connect( get_multitrack( ), producer.get_producer( ), index ); +} + +int Multitrack::clip( mlt_whence whence, int index ) +{ + return mlt_multitrack_clip( get_multitrack( ), whence, index ); +} + +int Multitrack::count( ) +{ + return mlt_multitrack_count( get_multitrack( ) ); +} + +Producer *Multitrack::track( int index ) +{ + return new Producer( mlt_multitrack_track( get_multitrack( ), index ) ); +} + +void Multitrack::refresh( ) +{ + return mlt_multitrack_refresh( get_multitrack( ) ); +} diff --git a/src/MltMultitrack.h b/src/MltMultitrack.h new file mode 100644 index 0000000..a714188 --- /dev/null +++ b/src/MltMultitrack.h @@ -0,0 +1,55 @@ +/** + * MltMultitrack.h - Multitrack wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_MULTITRACK_H_ +#define _MLTPP_MULTITRACK_H_ + +#include "config.h" + +#include + +#include "MltProducer.h" + +namespace Mlt +{ + class Service; + class Producer; + + class MLTPP_DECLSPEC Multitrack : public Producer + { + private: + mlt_multitrack instance; + public: + Multitrack( mlt_multitrack multitrack ); + Multitrack( Service &multitrack ); + Multitrack( Multitrack &multitrack ); + virtual ~Multitrack( ); + mlt_multitrack get_multitrack( ); + mlt_producer get_producer( ); + int connect( Producer &producer, int index ); + int clip( mlt_whence whence, int index ); + int count( ); + Producer *track( int index ); + void refresh( ); + }; +} + +#endif + diff --git a/src/MltParser.cpp b/src/MltParser.cpp new file mode 100644 index 0000000..457fcbf --- /dev/null +++ b/src/MltParser.cpp @@ -0,0 +1,284 @@ +/** + * MltParser.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "Mlt.h" +using namespace Mlt; + +static int on_invalid_cb( mlt_parser self, mlt_service object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Service service( object ); + return parser->on_invalid( &service ); +} + +static int on_unknown_cb( mlt_parser self, mlt_service object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Service service( object ); + return parser->on_unknown( &service ); +} + +static int on_start_producer_cb( mlt_parser self, mlt_producer object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Producer producer( object ); + return parser->on_start_producer( &producer ); +} + +static int on_end_producer_cb( mlt_parser self, mlt_producer object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Producer producer( object ); + return parser->on_end_producer( &producer ); +} + +static int on_start_playlist_cb( mlt_parser self, mlt_playlist object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Playlist playlist( object ); + return parser->on_start_playlist( &playlist ); +} + +static int on_end_playlist_cb( mlt_parser self, mlt_playlist object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Playlist playlist( object ); + return parser->on_end_playlist( &playlist ); +} + +static int on_start_tractor_cb( mlt_parser self, mlt_tractor object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Tractor tractor( object ); + return parser->on_start_tractor( &tractor ); +} + +static int on_end_tractor_cb( mlt_parser self, mlt_tractor object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Tractor tractor( object ); + return parser->on_end_tractor( &tractor ); +} + +static int on_start_multitrack_cb( mlt_parser self, mlt_multitrack object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Multitrack multitrack( object ); + return parser->on_start_multitrack( &multitrack ); +} + +static int on_end_multitrack_cb( mlt_parser self, mlt_multitrack object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Multitrack multitrack( object ); + return parser->on_end_multitrack( &multitrack ); +} + +static int on_start_track_cb( mlt_parser self ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + return parser->on_start_track( ); +} + +static int on_end_track_cb( mlt_parser self ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + return parser->on_end_track( ); +} + +static int on_start_filter_cb( mlt_parser self, mlt_filter object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Filter filter( object ); + return parser->on_start_filter( &filter ); +} + +static int on_end_filter_cb( mlt_parser self, mlt_filter object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Filter filter( object ); + return parser->on_end_filter( &filter ); +} + +static int on_start_transition_cb( mlt_parser self, mlt_transition object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Transition transition( object ); + return parser->on_start_transition( &transition ); +} + +static int on_end_transition_cb( mlt_parser self, mlt_transition object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Transition transition( object ); + return parser->on_end_transition( &transition ); +} + +Parser::Parser( ) : + Properties( false ) +{ + parser = mlt_parser_new( ); + set( "_parser_object", this, 0 ); + parser->on_invalid = on_invalid_cb; + parser->on_unknown = on_unknown_cb; + parser->on_start_producer = on_start_producer_cb; + parser->on_end_producer = on_end_producer_cb; + parser->on_start_playlist = on_start_playlist_cb; + parser->on_end_playlist = on_end_playlist_cb; + parser->on_start_tractor = on_start_tractor_cb; + parser->on_end_tractor = on_end_tractor_cb; + parser->on_start_multitrack = on_start_multitrack_cb; + parser->on_end_multitrack = on_end_multitrack_cb; + parser->on_start_track = on_start_track_cb; + parser->on_end_track = on_end_track_cb; + parser->on_start_filter = on_start_filter_cb; + parser->on_end_filter = on_end_filter_cb; + parser->on_start_transition = on_start_transition_cb; + parser->on_end_transition = on_end_transition_cb; +} + +Parser::~Parser( ) +{ + mlt_parser_close( parser ); +} + +mlt_properties Parser::get_properties( ) +{ + return mlt_parser_properties( parser ); +} + +int Parser::start( Service &service ) +{ + return mlt_parser_start( parser, service.get_service( ) ); +} + +int Parser::on_invalid( Service *object ) +{ + object->debug( "Invalid" ); + return 0; +} + +int Parser::on_unknown( Service *object ) +{ + object->debug( "Unknown" ); + return 0; +} + +int Parser::on_start_producer( Producer *object ) +{ + object->debug( "on_start_producer" ); + return 0; +} + +int Parser::on_end_producer( Producer *object ) +{ + object->debug( "on_end_producer" ); + return 0; +} + +int Parser::on_start_playlist( Playlist *object ) +{ + object->debug( "on_start_playlist" ); + return 0; +} + +int Parser::on_end_playlist( Playlist *object ) +{ + object->debug( "on_end_playlist" ); + return 0; +} + +int Parser::on_start_tractor( Tractor *object ) +{ + object->debug( "on_start_tractor" ); + return 0; +} + +int Parser::on_end_tractor( Tractor *object ) +{ + object->debug( "on_end_tractor" ); + return 0; +} + +int Parser::on_start_multitrack( Multitrack *object ) +{ + object->debug( "on_start_multitrack" ); + return 0; +} + +int Parser::on_end_multitrack( Multitrack *object ) +{ + object->debug( "on_end_multitrack" ); + return 0; +} + +int Parser::on_start_track( ) +{ + fprintf( stderr, "on_start_track\n" ); + return 0; +} + +int Parser::on_end_track( ) +{ + fprintf( stderr, "on_end_track\n" ); + return 0; +} + +int Parser::on_start_filter( Filter *object ) +{ + object->debug( "on_start_filter" ); + return 0; +} + +int Parser::on_end_filter( Filter *object ) +{ + object->debug( "on_end_filter" ); + return 0; +} + +int Parser::on_start_transition( Transition *object ) +{ + object->debug( "on_start_transition" ); + return 0; +} + +int Parser::on_end_transition( Transition *object ) +{ + object->debug( "on_end_transition" ); + return 0; +} + + diff --git a/src/MltParser.h b/src/MltParser.h new file mode 100644 index 0000000..02590c0 --- /dev/null +++ b/src/MltParser.h @@ -0,0 +1,68 @@ +/** + * MltParser.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_PARSER_H_ +#define _MLTPP_PARSER_H_ + +#include "config.h" + +#include +#include "MltProperties.h" + +namespace Mlt +{ + class Properties; + class Service; + class Producer; + class Playlist; + class Tractor; + class Multitrack; + class Filter; + class Transition; + + class MLTPP_DECLSPEC Parser : public Properties + { + private: + mlt_parser parser; + public: + Parser( ); + ~Parser( ); + int start( Service &service ); + virtual mlt_properties get_properties( ); + virtual int on_invalid( Service *object ); + virtual int on_unknown( Service *object ); + virtual int on_start_producer( Producer *object ); + virtual int on_end_producer( Producer *object ); + virtual int on_start_playlist( Playlist *object ); + virtual int on_end_playlist( Playlist *object ); + virtual int on_start_tractor( Tractor *object ); + virtual int on_end_tractor( Tractor *object ); + virtual int on_start_multitrack( Multitrack *object ); + virtual int on_end_multitrack( Multitrack *object ); + virtual int on_start_track( ); + virtual int on_end_track( ); + virtual int on_start_filter( Filter *object ); + virtual int on_end_filter( Filter *object ); + virtual int on_start_transition( Transition *object ); + virtual int on_end_transition( Transition *object ); + }; +} + +#endif diff --git a/src/MltPlaylist.cpp b/src/MltPlaylist.cpp new file mode 100644 index 0000000..5e61e6b --- /dev/null +++ b/src/MltPlaylist.cpp @@ -0,0 +1,314 @@ +/** + * MltPlaylist.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include "MltPlaylist.h" +#include "MltTransition.h" +using namespace Mlt; + +ClipInfo::ClipInfo( ) : + clip( 0 ), + producer( NULL ), + cut( NULL ), + start( 0 ), + resource( NULL ), + frame_in( 0 ), + frame_out( 0 ), + frame_count( 0 ), + length( 0 ), + fps( 0 ), + repeat( 0 ) +{ +} + +ClipInfo::ClipInfo( mlt_playlist_clip_info *info ) : + clip( info->clip ), + producer( new Producer( info->producer ) ), + cut( new Producer( info->cut ) ), + start( info->start ), + resource( strdup( info->resource ) ), + frame_in( info->frame_in ), + frame_out( info->frame_out ), + frame_count( info->frame_count ), + length( info->length ), + fps( info->fps ), + repeat( info->repeat ) +{ +} + +ClipInfo::~ClipInfo( ) +{ + delete producer; + delete cut; + free( resource ); +} + +void ClipInfo::update( mlt_playlist_clip_info *info ) +{ + delete producer; + delete cut; + free( resource ); + clip = info->clip; + producer = new Producer( info->producer ); + cut = new Producer( info->cut ); + start = info->start; + resource = strdup( info->resource ); + frame_in = info->frame_in; + frame_out = info->frame_out; + frame_count = info->frame_count; + length = info->length; + fps = info->fps; + repeat = info->repeat; +} + +Playlist::Playlist( ) : + instance( NULL ) +{ + instance = mlt_playlist_init( ); +} + +Playlist::Playlist( Service &producer ) : + instance( NULL ) +{ + if ( producer.type( ) == playlist_type ) + { + instance = ( mlt_playlist )producer.get_service( ); + inc_ref( ); + } +} + +Playlist::Playlist( Playlist &playlist ) : + instance( playlist.get_playlist( ) ) +{ + inc_ref( ); +} + +Playlist::Playlist( mlt_playlist playlist ) : + instance( playlist ) +{ + inc_ref( ); +} + +Playlist::~Playlist( ) +{ + mlt_playlist_close( instance ); +} + +mlt_playlist Playlist::get_playlist( ) +{ + return instance; +} + +mlt_producer Playlist::get_producer( ) +{ + return mlt_playlist_producer( get_playlist( ) ); +} + +int Playlist::count( ) +{ + return mlt_playlist_count( get_playlist( ) ); +} + +int Playlist::clear( ) +{ + return mlt_playlist_clear( get_playlist( ) ); +} + +int Playlist::append( Producer &producer, int in, int out ) +{ + return mlt_playlist_append_io( get_playlist( ), producer.get_producer( ), in, out ); +} + +int Playlist::blank( int length ) +{ + return mlt_playlist_blank( get_playlist( ), length ); +} + +int Playlist::clip( mlt_whence whence, int index ) +{ + return mlt_playlist_clip( get_playlist( ), whence, index ); +} + +int Playlist::current_clip( ) +{ + return mlt_playlist_current_clip( get_playlist( ) ); +} + +Producer *Playlist::current( ) +{ + return new Producer( mlt_playlist_current( get_playlist( ) ) ); +} + +ClipInfo *Playlist::clip_info( int index, ClipInfo *info ) +{ + mlt_playlist_clip_info clip_info; + mlt_playlist_get_clip_info( get_playlist( ), &clip_info, index ); + if ( info == NULL ) + return new ClipInfo( &clip_info ); + info->update( &clip_info ); + return info; +} + +void Playlist::delete_clip_info( ClipInfo *info ) +{ + delete info; +} + +int Playlist::insert( Producer &producer, int where, int in, int out ) +{ + return mlt_playlist_insert( get_playlist( ), producer.get_producer( ), where, in, out ); +} + +int Playlist::remove( int where ) +{ + return mlt_playlist_remove( get_playlist( ), where ); +} + +int Playlist::move( int from, int to ) +{ + return mlt_playlist_move( get_playlist( ), from, to ); +} + +int Playlist::resize_clip( int clip, int in, int out ) +{ + return mlt_playlist_resize_clip( get_playlist( ), clip, in, out ); +} + +int Playlist::split( int clip, int position ) +{ + return mlt_playlist_split( get_playlist( ), clip, position ); +} + +int Playlist::split_at( int position, bool left ) +{ + return mlt_playlist_split_at( get_playlist( ), position, left ); +} + +int Playlist::join( int clip, int count, int merge ) +{ + return mlt_playlist_join( get_playlist( ), clip, count, merge ); +} + +int Playlist::mix( int clip, int length, Transition *transition ) +{ + return mlt_playlist_mix( get_playlist( ), clip, length, transition == NULL ? NULL : transition->get_transition( ) ); +} + +int Playlist::mix_add( int clip, Transition *transition ) +{ + return mlt_playlist_mix_add( get_playlist( ), clip, transition == NULL ? NULL : transition->get_transition( ) ); +} + +int Playlist::repeat( int clip, int count ) +{ + return mlt_playlist_repeat_clip( get_playlist( ), clip, count ); +} + +Producer *Playlist::get_clip( int clip ) +{ + mlt_producer producer = mlt_playlist_get_clip( get_playlist( ), clip ); + return producer != NULL ? new Producer( producer ) : NULL; +} + +Producer *Playlist::get_clip_at( int position ) +{ + mlt_producer producer = mlt_playlist_get_clip_at( get_playlist( ), position ); + return producer != NULL ? new Producer( producer ) : NULL; +} + +int Playlist::get_clip_index_at( int position ) +{ + return mlt_playlist_get_clip_index_at( get_playlist( ), position ); +} + +bool Playlist::is_mix( int clip ) +{ + return mlt_playlist_clip_is_mix( get_playlist( ), clip ) != 0; +} + +bool Playlist::is_blank( int clip ) +{ + return mlt_playlist_is_blank( get_playlist( ), clip ) != 0; +} + +bool Playlist::is_blank_at( int position ) +{ + return mlt_playlist_is_blank_at( get_playlist( ), position ) != 0; +} + +Producer *Playlist::replace_with_blank( int clip ) +{ + mlt_producer producer = mlt_playlist_replace_with_blank( get_playlist( ), clip ); + Producer *object = producer != NULL ? new Producer( producer ) : NULL; + mlt_producer_close( producer ); + return object; +} + +void Playlist::consolidate_blanks( int keep_length ) +{ + return mlt_playlist_consolidate_blanks( get_playlist( ), keep_length ); +} + +void Playlist::insert_blank( int clip, int length ) +{ + mlt_playlist_insert_blank( get_playlist( ), clip, length ); +} + +void Playlist::pad_blanks( int position, int length, int find ) +{ + mlt_playlist_pad_blanks( get_playlist( ), position, length, find ); +} + +int Playlist::insert_at( int position, Producer *producer, int mode ) +{ + return mlt_playlist_insert_at( get_playlist( ), position, producer->get_producer( ), mode ); +} + +int Playlist::insert_at( int position, Producer &producer, int mode ) +{ + return mlt_playlist_insert_at( get_playlist( ), position, producer.get_producer( ), mode ); +} + +int Playlist::clip_start( int clip ) +{ + return mlt_playlist_clip_start( get_playlist( ), clip ); +} + +int Playlist::blanks_from( int clip, int bounded ) +{ + return mlt_playlist_blanks_from( get_playlist( ), clip, bounded ); +} + +int Playlist::clip_length( int clip ) +{ + return mlt_playlist_clip_length( get_playlist( ), clip ); +} + +int Playlist::remove_region( int position, int length ) +{ + return mlt_playlist_remove_region( get_playlist( ), position, length ); +} + +int Playlist::move_region( int position, int length, int new_position ) +{ + return mlt_playlist_move_region( get_playlist( ), position, length, new_position ); +} + diff --git a/src/MltPlaylist.h b/src/MltPlaylist.h new file mode 100644 index 0000000..2ecf5ff --- /dev/null +++ b/src/MltPlaylist.h @@ -0,0 +1,108 @@ +/** + * MltPlaylist.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_PLAYLIST_H_ +#define _MLTPP_PLAYLIST_H_ + +#include "config.h" + +#include + +#include "MltProducer.h" + +namespace Mlt +{ + class Producer; + class Service; + class Playlist; + class Transition; + + class MLTPP_DECLSPEC ClipInfo + { + public: + ClipInfo( ); + ClipInfo( mlt_playlist_clip_info *info ); + ~ClipInfo( ); + void update( mlt_playlist_clip_info *info ); + int clip; + Producer *producer; + Producer *cut; + int start; + char *resource; + int frame_in; + int frame_out; + int frame_count; + int length; + float fps; + int repeat; + }; + + class MLTPP_DECLSPEC Playlist : public Producer + { + private: + mlt_playlist instance; + public: + Playlist( ); + Playlist( Service &playlist ); + Playlist( Playlist &playlist ); + Playlist( mlt_playlist playlist ); + virtual ~Playlist( ); + virtual mlt_playlist get_playlist( ); + mlt_producer get_producer( ); + int count( ); + int clear( ); + int append( Producer &producer, int in = -1, int out = -1 ); + int blank( int length ); + int clip( mlt_whence whence, int index ); + int current_clip( ); + Producer *current( ); + ClipInfo *clip_info( int index, ClipInfo *info = NULL ); + static void delete_clip_info( ClipInfo *info ); + int insert( Producer &producer, int where, int in = -1, int out = -1 ); + int remove( int where ); + int move( int from, int to ); + int resize_clip( int clip, int in, int out ); + int split( int clip, int position ); + int split_at( int position, bool left = true ); + int join( int clip, int count = 1, int merge = 1 ); + int mix( int clip, int length, Transition *transition = NULL ); + int mix_add( int clip, Transition *transition ); + int repeat( int clip, int count ); + Producer *get_clip( int clip ); + Producer *get_clip_at( int position ); + int get_clip_index_at( int position ); + bool is_mix( int clip ); + bool is_blank( int clip ); + bool is_blank_at( int position ); + void consolidate_blanks( int keep_length = 0 ); + Producer *replace_with_blank( int clip ); + void insert_blank( int clip, int length ); + void pad_blanks( int position, int length, int find = 0 ); + int insert_at( int position, Producer *producer, int mode = 0 ); + int insert_at( int position, Producer &producer, int mode = 0 ); + int clip_start( int clip ); + int clip_length( int clip ); + int blanks_from( int clip, int bounded = 0 ); + int remove_region( int position, int length ); + int move_region( int position, int length, int new_position ); + }; +} + +#endif diff --git a/src/MltProducer.cpp b/src/MltProducer.cpp new file mode 100644 index 0000000..d780165 --- /dev/null +++ b/src/MltProducer.cpp @@ -0,0 +1,191 @@ +/** + * MltProducer.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltProducer.h" +#include "MltFilter.h" +using namespace Mlt; + +Producer::Producer( ) : + instance( NULL ), + parent_( NULL ) +{ +} + +Producer::Producer( char *id, char *service ) : + instance( NULL ), + parent_( NULL ) +{ + if ( id != NULL && service != NULL ) + instance = mlt_factory_producer( id, service ); + else + instance = mlt_factory_producer( "fezzik", id != NULL ? id : service ); +} + +Producer::Producer( Service &producer ) : + instance( NULL ), + parent_( NULL ) +{ + mlt_service_type type = producer.type( ); + if ( type == producer_type || type == playlist_type || + type == tractor_type || type == multitrack_type ) + { + instance = ( mlt_producer )producer.get_service( ); + inc_ref( ); + } +} + +Producer::Producer( mlt_producer producer ) : + instance( producer ), + parent_( NULL ) +{ + inc_ref( ); +} + +Producer::Producer( Producer &producer ) : + instance( producer.get_producer( ) ), + parent_( NULL ) +{ + inc_ref( ); +} + +Producer::Producer( Producer *producer ) : + instance( producer != NULL ? producer->get_producer( ) : NULL ), + parent_( NULL ) +{ + if ( is_valid( ) ) + inc_ref( ); +} + +Producer::~Producer( ) +{ + delete parent_; + mlt_producer_close( instance ); + instance = NULL; +} + +mlt_producer Producer::get_producer( ) +{ + return instance; +} + +mlt_producer Producer::get_parent( ) +{ + return get_producer( ) != NULL && mlt_producer_cut_parent( get_producer( ) ) != NULL ? mlt_producer_cut_parent( get_producer( ) ) : get_producer( ); +} + +Producer &Producer::parent( ) +{ + if ( is_cut( ) && parent_ == NULL ) + parent_ = new Producer( get_parent( ) ); + return parent_ == NULL ? *this : *parent_; +} + +mlt_service Producer::get_service( ) +{ + return mlt_producer_service( get_producer( ) ); +} + +int Producer::seek( int position ) +{ + return mlt_producer_seek( get_producer( ), position ); +} + +int Producer::position( ) +{ + return mlt_producer_position( get_producer( ) ); +} + +int Producer::frame( ) +{ + return mlt_producer_frame( get_producer( ) ); +} + +int Producer::set_speed( double speed ) +{ + return mlt_producer_set_speed( get_producer( ), speed ); +} + +double Producer::get_speed( ) +{ + return mlt_producer_get_speed( get_producer( ) ); +} + +double Producer::get_fps( ) +{ + return mlt_producer_get_fps( get_producer( ) ); +} + +int Producer::set_in_and_out( int in, int out ) +{ + return mlt_producer_set_in_and_out( get_producer( ), in, out ); +} + +int Producer::get_in( ) +{ + return mlt_producer_get_in( get_producer( ) ); +} + +int Producer::get_out( ) +{ + return mlt_producer_get_out( get_producer( ) ); +} + +int Producer::get_length( ) +{ + return mlt_producer_get_length( get_producer( ) ); +} + +int Producer::get_playtime( ) +{ + return mlt_producer_get_playtime( get_producer( ) ); +} + +Producer *Producer::cut( int in, int out ) +{ + mlt_producer producer = mlt_producer_cut( get_producer( ), in, out ); + Producer *result = new Producer( producer ); + mlt_producer_close( producer ); + return result; +} + +bool Producer::is_cut( ) +{ + return mlt_producer_is_cut( get_producer( ) ) != 0; +} + +bool Producer::is_blank( ) +{ + return mlt_producer_is_blank( get_producer( ) ) != 0; +} + +bool Producer::same_clip( Producer &that ) +{ + return mlt_producer_cut_parent( get_producer( ) ) == mlt_producer_cut_parent( that.get_producer( ) ); +} + +bool Producer::runs_into( Producer &that ) +{ + return same_clip( that ) && get_out( ) == ( that.get_in( ) - 1 ); +} + +void Producer::optimise( ) +{ + mlt_producer_optimise( get_producer( ) ); +} diff --git a/src/MltProducer.h b/src/MltProducer.h new file mode 100644 index 0000000..e28459e --- /dev/null +++ b/src/MltProducer.h @@ -0,0 +1,72 @@ +/** + * MltProducer.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_PRODUCER_H_ +#define _MLTPP_PRODUCER_H_ + +#include "config.h" + +#include + +#include "MltService.h" + +namespace Mlt +{ + class Service; + class Filter; + + class MLTPP_DECLSPEC Producer : public Service + { + private: + mlt_producer instance; + Producer *parent_; + public: + Producer( ); + Producer( char *id, char *service = NULL ); + Producer( Service &producer ); + Producer( mlt_producer producer ); + Producer( Producer &producer ); + Producer( Producer *producer ); + virtual ~Producer( ); + virtual mlt_producer get_producer( ); + Producer &parent( ); + mlt_producer get_parent( ); + mlt_service get_service( ); + int seek( int position ); + int position( ); + int frame( ); + int set_speed( double speed ); + double get_speed( ); + double get_fps( ); + int set_in_and_out( int in, int out ); + int get_in( ); + int get_out( ); + int get_length( ); + int get_playtime( ); + Producer *cut( int in = 0, int out = -1 ); + bool is_cut( ); + bool is_blank( ); + bool same_clip( Producer &that ); + bool runs_into( Producer &that ); + void optimise( ); + }; +} + +#endif diff --git a/src/MltProperties.cpp b/src/MltProperties.cpp new file mode 100644 index 0000000..8ee3e5e --- /dev/null +++ b/src/MltProperties.cpp @@ -0,0 +1,261 @@ +/** + * MltProperties.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltProperties.h" +#include "MltEvent.h" +using namespace Mlt; + +Properties::Properties( ) : + instance( NULL ) +{ + instance = mlt_properties_new( ); +} + +Properties::Properties( bool dummy ) : + instance( NULL ) +{ +} + +Properties::Properties( Properties &properties ) : + instance( properties.get_properties( ) ) +{ + inc_ref( ); +} + +Properties::Properties( mlt_properties properties ) : + instance( properties ) +{ + inc_ref( ); +} + +Properties::Properties( const char *file ) : + instance( NULL ) +{ + instance = mlt_properties_load( file ); +} + +Properties::~Properties( ) +{ + mlt_properties_close( instance ); +} + +mlt_properties Properties::get_properties( ) +{ + return instance; +} + +int Properties::inc_ref( ) +{ + return mlt_properties_inc_ref( get_properties( ) ); +} + +int Properties::dec_ref( ) +{ + return mlt_properties_dec_ref( get_properties( ) ); +} + +int Properties::ref_count( ) +{ + return mlt_properties_ref_count( get_properties( ) ); +} + +void Properties::block( void *object ) +{ + mlt_events_block( get_properties( ), object != NULL ? object : get_properties( ) ); +} + +void Properties::unblock( void *object ) +{ + mlt_events_unblock( get_properties( ), object != NULL ? object : get_properties( ) ); +} + +void Properties::fire_event( const char *event ) +{ + mlt_events_fire( get_properties( ), ( char * )event, NULL ); +} + +bool Properties::is_valid( ) +{ + return get_properties( ) != NULL; +} + +int Properties::count( ) +{ + return mlt_properties_count( get_properties( ) ); +} + +char *Properties::get( const char *name ) +{ + return mlt_properties_get( get_properties( ), name ); +} + +int Properties::get_int( const char *name ) +{ + return mlt_properties_get_int( get_properties( ), name ); +} + +double Properties::get_double( const char *name ) +{ + return mlt_properties_get_double( get_properties( ), name ); +} + +void *Properties::get_data( const char *name, int &size ) +{ + return mlt_properties_get_data( get_properties( ), name, &size ); +} + +void *Properties::get_data( const char *name ) +{ + return mlt_properties_get_data( get_properties( ), name, NULL ); +} + +int Properties::set( const char *name, const char *value ) +{ + return mlt_properties_set( get_properties( ), name, value ); +} + +int Properties::set( const char *name, int value ) +{ + return mlt_properties_set_int( get_properties( ), name, value ); +} + +int Properties::set( const char *name, double value ) +{ + return mlt_properties_set_double( get_properties( ), name, value ); +} + +int Properties::set( const char *name, void *value, int size, mlt_destructor destructor, mlt_serialiser serialiser ) +{ + return mlt_properties_set_data( get_properties( ), name, value, size, destructor, serialiser ); +} + +int Properties::pass_values( Properties &that, const char *prefix ) +{ + return mlt_properties_pass( get_properties( ), that.get_properties( ), prefix ); +} + +int Properties::parse( const char *namevalue ) +{ + return mlt_properties_parse( get_properties( ), namevalue ); +} + +char *Properties::get_name( int index ) +{ + return mlt_properties_get_name( get_properties( ), index ); +} + +char *Properties::get( int index ) +{ + return mlt_properties_get_value( get_properties( ), index ); +} + +void *Properties::get_data( int index, int &size ) +{ + return mlt_properties_get_data_at( get_properties( ), index, &size ); +} + +void Properties::mirror( Properties &that ) +{ + mlt_properties_mirror( get_properties( ), that.get_properties( ) ); +} + +int Properties::inherit( Properties &that ) +{ + return mlt_properties_inherit( get_properties( ), that.get_properties( ) ); +} + +int Properties::rename( const char *source, const char *dest ) +{ + return mlt_properties_rename( get_properties( ), source, dest ); +} + +void Properties::dump( FILE *output ) +{ + mlt_properties_dump( get_properties( ), output ); +} + +void Properties::debug( const char *title, FILE *output ) +{ + mlt_properties_debug( get_properties( ), title, output ); +} + +void Properties::load( const char *file ) +{ + mlt_properties properties = mlt_properties_load( file ); + if ( properties != NULL ) + mlt_properties_pass( get_properties( ), properties, "" ); + mlt_properties_close( properties ); +} + +int Properties::save( const char *file ) +{ +#ifdef WIN32 + return mlt_properties_save( get_properties( ), file ); +#else + int error = 0; + FILE *f = fopen( file, "w" ); + if ( f != NULL ) + { + dump( f ); + fclose( f ); + } + else + { + error = 1; + } + return error; +#endif +} + +#if defined( __DARWIN__ ) && GCC_VERSION < 40000 + +Event *Properties::listen( char *id, void *object, void (*listener)( ... ) ) +{ + mlt_event event = mlt_events_listen( get_properties( ), object, id, ( mlt_listener )listener ); + return new Event( event ); +} + +#else + +Event *Properties::listen( char *id, void *object, mlt_listener listener ) +{ + mlt_event event = mlt_events_listen( get_properties( ), object, id, listener ); + return new Event( event ); +} + +#endif + +Event *Properties::setup_wait_for( char *id ) +{ + return new Event( mlt_events_setup_wait_for( get_properties( ), id ) ); +} + +void Properties::delete_event( Event *event ) +{ + delete event; +} + +void Properties::wait_for( Event *event, bool destroy ) +{ + mlt_events_wait_for( get_properties( ), event->get_event( ) ); + if ( destroy ) + mlt_events_close_wait_for( get_properties( ), event->get_event( ) ); +} + diff --git a/src/MltProperties.h b/src/MltProperties.h new file mode 100644 index 0000000..df16375 --- /dev/null +++ b/src/MltProperties.h @@ -0,0 +1,88 @@ +/** + * MltProperties.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_PROPERTIES_H_ +#define _MLTPP_PROPERTIES_H_ + +#include "config.h" + +#include +#include + +namespace Mlt +{ + class Event; + + /** Abstract Properties class. + */ + + class MLTPP_DECLSPEC Properties + { + private: + mlt_properties instance; + public: + Properties( ); + Properties( bool dummy ); + Properties( Properties &properties ); + Properties( mlt_properties properties ); + Properties( const char *file ); + virtual ~Properties( ); + virtual mlt_properties get_properties( ); + int inc_ref( ); + int dec_ref( ); + int ref_count( ); + void block( void *object = NULL ); + void unblock( void *object = NULL ); + void fire_event( const char *event ); + bool is_valid( ); + int count( ); + char *get( const char *name ); + int get_int( const char *name ); + double get_double( const char *name ); + void *get_data( const char *name, int &size ); + void *get_data( const char *name ); + int set( const char *name, const char *value ); + int set( const char *name, int value ); + int set( const char *name, double value ); + int set( const char *name, void *value, int size, mlt_destructor destroy = NULL, mlt_serialiser serial = NULL ); + int pass_values( Properties &that, const char *prefix ); + int parse( const char *namevalue ); + char *get_name( int index ); + char *get( int index ); + void *get_data( int index, int &size ); + void mirror( Properties &that ); + int inherit( Properties &that ); + int rename( const char *source, const char *dest ); + void dump( FILE *output = stderr ); + void debug( const char *title = "Object", FILE *output = stderr ); + void load( const char *file ); + int save( const char *file ); + #if defined( __DARWIN__ ) && GCC_VERSION < 40000 + Event *listen( char *id, void *object, void (*)( ... ) ); + #else + Event *listen( char *id, void *object, mlt_listener ); + #endif + static void delete_event( Event * ); + Event *setup_wait_for( char *id ); + void wait_for( Event *, bool destroy = true ); + }; +} + +#endif diff --git a/src/MltPushConsumer.cpp b/src/MltPushConsumer.cpp new file mode 100644 index 0000000..3aec75e --- /dev/null +++ b/src/MltPushConsumer.cpp @@ -0,0 +1,146 @@ +/** + * MltPushConsumer.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltPushConsumer.h" +#include "MltFilter.h" +using namespace Mlt; + +namespace Mlt +{ + class PushPrivate + { + public: + PushPrivate( ) + { + } + }; +} + +static void filter_destructor( void *arg ) +{ + Filter *filter = ( Filter * )arg; + delete filter; +} + +PushConsumer::PushConsumer( char *id , char *service ) : + Consumer( id, service ), + m_private( new PushPrivate( ) ) +{ + if ( is_valid( ) ) + { + // Set up push mode (known as put mode in mlt) + set( "real_time", 0 ); + set( "put_mode", 1 ); + set( "terminate_on_pause", 0 ); + set( "buffer", 0 ); + + // We might need resize and rescale filters so we'll create them now + // NB: Try to use the best rescaler available here + Filter *resize = new Filter( "resize" ); + Filter *rescale = new Filter( "mcrescale" ); + if ( !rescale->is_valid( ) ) + { + delete rescale; + rescale = new Filter( "gtkrescale" ); + } + if ( !rescale->is_valid( ) ) + { + delete rescale; + rescale = new Filter( "rescale" ); + } + + Filter *convert = new Filter( "avcolour_space" ); + + set( "filter_convert", convert, 0, filter_destructor ); + set( "filter_resize", resize, 0, filter_destructor ); + set( "filter_rescale", rescale, 0, filter_destructor ); + } +} + +PushConsumer::~PushConsumer( ) +{ +} + +void PushConsumer::set_render( int width, int height, double aspect_ratio ) +{ + set( "render_width", width ); + set( "render_height", height ); + set( "render_aspect_ratio", aspect_ratio ); +} + +int PushConsumer::connect( Service &service ) +{ + return -1; +} + +int PushConsumer::push( Frame *frame ) +{ + frame->inc_ref( ); + + // Here we have the option to process the frame at a render resolution (this will + // typically be PAL or NTSC) prior to scaling according to the consumers profile + // This is done to optimise quality, esp. with regard to compositing positions + if ( get_int( "render_width" ) ) + { + // Process the projects render resolution first + mlt_image_format format = mlt_image_yuv422; + int w = get_int( "render_width" ); + int h = get_int( "render_height" ); + frame->set( "consumer_aspect_ratio", get_double( "render_aspect_ratio" ) ); + frame->set( "consumer_deinterlace", get_int( "deinterlace" ) ); + frame->set( "deinterlace_method", get_int( "deinterlace_method" ) ); + frame->set( "rescale.interp", get( "rescale" ) ); + + // Render the frame + frame->get_image( format, w, h ); + + // Now set up the post image scaling + Filter *convert = ( Filter * )get_data( "filter_convert" ); + mlt_filter_process( convert->get_filter( ), frame->get_frame( ) ); + Filter *rescale = ( Filter * )get_data( "filter_rescale" ); + mlt_filter_process( rescale->get_filter( ), frame->get_frame( ) ); + Filter *resize = ( Filter * )get_data( "filter_resize" ); + mlt_filter_process( resize->get_filter( ), frame->get_frame( ) ); + } + + return mlt_consumer_put_frame( ( mlt_consumer )get_service( ), frame->get_frame( ) ); +} + +int PushConsumer::push( Frame &frame ) +{ + return push( &frame ); +} + +int PushConsumer::drain( ) +{ + return 0; +} + +// Convenience function - generates a frame with an image of a given size +Frame *PushConsumer::construct( int size ) +{ + mlt_frame f = mlt_frame_init( ); + Frame *frame = new Frame( f ); + uint8_t *buffer = ( uint8_t * )mlt_pool_alloc( size ); + frame->set( "image", buffer, size, mlt_pool_release ); + mlt_frame_close( f ); + return frame; +} + diff --git a/src/MltPushConsumer.h b/src/MltPushConsumer.h new file mode 100644 index 0000000..7687496 --- /dev/null +++ b/src/MltPushConsumer.h @@ -0,0 +1,50 @@ +/** + * MltPushConsumer.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MLTPP_PUSH_CONSUMER_H +#define MLTPP_PUSH_CONSUMER_H + +#include "config.h" + +#include "MltConsumer.h" + +namespace Mlt +{ + class Frame; + class Service; + class PushPrivate; + + class MLTPP_DECLSPEC PushConsumer : public Consumer + { + private: + PushPrivate *m_private; + public: + PushConsumer( char *id , char *service = NULL ); + virtual ~PushConsumer( ); + void set_render( int width, int height, double aspect_ratio ); + virtual int connect( Service &service ); + int push( Frame *frame ); + int push( Frame &frame ); + int drain( ); + Frame *construct( int ); + }; +} + +#endif diff --git a/src/MltResponse.cpp b/src/MltResponse.cpp new file mode 100644 index 0000000..fa01d3f --- /dev/null +++ b/src/MltResponse.cpp @@ -0,0 +1,72 @@ +/** + * MltResponse.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "MltResponse.h" +using namespace Mlt; + +Response::Response( valerie_response response ) : + _response( response ) +{ +} + +Response::Response( int error, char *message ) : + _response( NULL ) +{ + _response = valerie_response_init( ); + if ( _response != NULL ) + valerie_response_set_error( _response, error, message ); +} + +Response::~Response( ) +{ + valerie_response_close( _response ); +} + +valerie_response Response::get_response( ) +{ + return _response; +} + +int Response::error_code( ) +{ + return valerie_response_get_error_code( get_response( ) ); +} + +char *Response::error_string( ) +{ + return valerie_response_get_error_string( get_response( ) ); +} + +char *Response::get( int index ) +{ + return valerie_response_get_line( get_response( ), index ); +} + +int Response::count( ) +{ + return valerie_response_count( get_response( ) ); +} + +int Response::write( const char *data ) +{ + return valerie_response_write( get_response( ), ( char * )data, strlen( data ) ); +} + diff --git a/src/MltResponse.h b/src/MltResponse.h new file mode 100644 index 0000000..dc5aa10 --- /dev/null +++ b/src/MltResponse.h @@ -0,0 +1,45 @@ +/** + * MltResponse.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_RESPONSE_H_ +#define _MLTPP_RESPONSE_H_ + +#include + +namespace Mlt +{ + class Response + { + private: + valerie_response _response; + public: + Response( valerie_response response ); + Response( int error, char *message ); + ~Response( ); + valerie_response get_response( ); + int error_code( ); + char *error_string( ); + char *get( int ); + int count( ); + int write( const char *data ); + }; +} + +#endif diff --git a/src/MltService.cpp b/src/MltService.cpp new file mode 100644 index 0000000..ce8d4d1 --- /dev/null +++ b/src/MltService.cpp @@ -0,0 +1,115 @@ +/** + * MltService.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "MltService.h" +#include "MltFilter.h" +using namespace Mlt; + +Service::Service( ) : + Properties( false ), + instance( NULL ) +{ +} + +Service::Service( Service &service ) : + Properties( false ), + instance( service.get_service( ) ) +{ + inc_ref( ); +} + +Service::Service( mlt_service service ) : + Properties( false ), + instance( service ) +{ + inc_ref( ); +} + +Service::~Service( ) +{ + mlt_service_close( instance ); +} + +mlt_service Service::get_service( ) +{ + return instance; +} + +mlt_properties Service::get_properties( ) +{ + return mlt_service_properties( get_service( ) ); +} + +void Service::lock( ) +{ + mlt_service_lock( get_service( ) ); +} + +void Service::unlock( ) +{ + mlt_service_unlock( get_service( ) ); +} + +int Service::connect_producer( Service &producer, int index ) +{ + return mlt_service_connect_producer( get_service( ), producer.get_service( ), index ); +} + +Service *Service::producer( ) +{ + return new Service( mlt_service_producer( get_service( ) ) ); +} + +Service *Service::consumer( ) +{ + return new Service( mlt_service_consumer( get_service( ) ) ); +} + +Frame *Service::get_frame( int index ) +{ + mlt_frame frame = NULL; + mlt_service_get_frame( get_service( ), &frame, index ); + Frame *result = new Frame( frame ); + mlt_frame_close( frame ); + return result; +} + +mlt_service_type Service::type( ) +{ + return mlt_service_identify( get_service( ) ); +} + +int Service::attach( Filter &filter ) +{ + return mlt_service_attach( get_service( ), filter.get_filter( ) ); +} + +int Service::detach( Filter &filter ) +{ + return mlt_service_detach( get_service( ), filter.get_filter( ) ); +} + +Filter *Service::filter( int index ) +{ + mlt_filter result = mlt_service_filter( get_service( ), index ); + return result == NULL ? NULL : new Filter( result ); +} + diff --git a/src/MltService.h b/src/MltService.h new file mode 100644 index 0000000..96655f8 --- /dev/null +++ b/src/MltService.h @@ -0,0 +1,61 @@ +/** + * MltService.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_SERVICE_H_ +#define _MLTPP_SERVICE_H_ + +#include "config.h" + +#include + +#include "MltProperties.h" +#include "MltFrame.h" + +namespace Mlt +{ + class Properties; + class Filter; + class Frame; + + class MLTPP_DECLSPEC Service : public Properties + { + private: + mlt_service instance; + public: + Service( ); + Service( Service &service ); + Service( mlt_service service ); + virtual ~Service( ); + virtual mlt_service get_service( ); + void lock( ); + void unlock( ); + virtual mlt_properties get_properties( ); + int connect_producer( Service &producer, int index = 0 ); + Service *consumer( ); + Service *producer( ); + Frame *get_frame( int index = 0 ); + mlt_service_type type( ); + int attach( Filter &filter ); + int detach( Filter &filter ); + Filter *filter( int index ); + }; +} + +#endif diff --git a/src/MltTokeniser.cpp b/src/MltTokeniser.cpp new file mode 100644 index 0000000..09e9c33 --- /dev/null +++ b/src/MltTokeniser.cpp @@ -0,0 +1,56 @@ +/** + * MltTokeniser.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include "MltTokeniser.h" +using namespace Mlt; + +Tokeniser::Tokeniser( char *text, char *delimiter ) +{ + tokens = mlt_tokeniser_init( ); + if ( text != NULL ) + mlt_tokeniser_parse_new( tokens, text, delimiter ); +} + +Tokeniser::~Tokeniser( ) +{ + mlt_tokeniser_close( tokens ); +} + +int Tokeniser::parse( char *text, char *delimiter ) +{ + return mlt_tokeniser_parse_new( tokens, text, delimiter ); +} + +int Tokeniser::count( ) +{ + return mlt_tokeniser_count( tokens ); +} + +char *Tokeniser::get( int index ) +{ + return mlt_tokeniser_get_string( tokens, index ); +} + +char *Tokeniser::input( ) +{ + return mlt_tokeniser_get_input( tokens ); +} + diff --git a/src/MltTokeniser.h b/src/MltTokeniser.h new file mode 100644 index 0000000..556100f --- /dev/null +++ b/src/MltTokeniser.h @@ -0,0 +1,45 @@ +/** + * MltTokeniser.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_TOKENISER_H +#define _MLTPP_TOKENISER_H + +#include "config.h" + +#include + +namespace Mlt +{ + class MLTPP_DECLSPEC Tokeniser + { + private: + mlt_tokeniser tokens; + public: + Tokeniser( char *text = NULL, char *delimiter = " " ); + ~Tokeniser( ); + int parse( char *text, char *delimiter = " " ); + int count( ); + char *get( int index ); + char *input( ); + }; +} + +#endif + diff --git a/src/MltTractor.cpp b/src/MltTractor.cpp new file mode 100644 index 0000000..33f80e7 --- /dev/null +++ b/src/MltTractor.cpp @@ -0,0 +1,158 @@ +/** + * MltTractor.cpp - Tractor wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "MltTractor.h" +#include "MltMultitrack.h" +#include "MltField.h" +#include "MltTransition.h" +#include "MltFilter.h" +#include "MltPlaylist.h" +using namespace Mlt; + +Tractor::Tractor( ) : + instance( mlt_tractor_new( ) ) +{ +} + +Tractor::Tractor( Service &tractor ) : + instance( NULL ) +{ + if ( tractor.type( ) == tractor_type ) + { + instance = ( mlt_tractor )tractor.get_service( ); + inc_ref( ); + } +} + +Tractor::Tractor( mlt_tractor tractor ) : + instance( tractor ) +{ + inc_ref( ); +} + +Tractor::Tractor( Tractor &tractor ) : + instance( tractor.get_tractor( ) ) +{ + inc_ref( ); +} + +Tractor::Tractor( char *id, char *resource ) : + instance( NULL ) +{ + Producer producer( id, resource ); + if ( producer.is_valid( ) && producer.type( ) == tractor_type ) + { + instance = ( mlt_tractor )producer.get_producer( ); + inc_ref( ); + } + else if ( producer.is_valid( ) ) + { + instance = mlt_tractor_new( ); + set_track( producer, 0 ); + } +} + +Tractor::~Tractor( ) +{ + mlt_tractor_close( instance ); +} + +mlt_tractor Tractor::get_tractor( ) +{ + return instance; +} + +mlt_producer Tractor::get_producer( ) +{ + return mlt_tractor_producer( get_tractor( ) ); +} + +Multitrack *Tractor::multitrack( ) +{ + return new Multitrack( mlt_tractor_multitrack( get_tractor( ) ) ); +} + +Field *Tractor::field( ) +{ + return new Field( mlt_tractor_field( get_tractor( ) ) ); +} + +void Tractor::refresh( ) +{ + return mlt_tractor_refresh( get_tractor( ) ); +} + +int Tractor::set_track( Producer &producer, int index ) +{ + return mlt_tractor_set_track( get_tractor( ), producer.get_producer( ), index ); +} + +Producer *Tractor::track( int index ) +{ + mlt_producer producer = mlt_tractor_get_track( get_tractor( ), index ); + return producer != NULL ? new Producer( producer ) : NULL; +} + +int Tractor::count( ) +{ + return mlt_multitrack_count( mlt_tractor_multitrack( get_tractor( ) ) ); +} + +void Tractor::plant_transition( Transition &transition, int a_track, int b_track ) +{ + mlt_field_plant_transition( mlt_tractor_field( get_tractor( ) ), transition.get_transition( ), a_track, b_track ); +} + +void Tractor::plant_transition( Transition *transition, int a_track, int b_track ) +{ + if ( transition != NULL ) + mlt_field_plant_transition( mlt_tractor_field( get_tractor( ) ), transition->get_transition( ), a_track, b_track ); +} + +void Tractor::plant_filter( Filter &filter, int track ) +{ + mlt_field_plant_filter( mlt_tractor_field( get_tractor( ) ), filter.get_filter( ), track ); +} + +void Tractor::plant_filter( Filter *filter, int track ) +{ + mlt_field_plant_filter( mlt_tractor_field( get_tractor( ) ), filter->get_filter( ), track ); +} + +bool Tractor::locate_cut( Producer *producer, int &track, int &cut ) +{ + bool found = false; + + for ( track = 0; producer != NULL && !found && track < count( ); track ++ ) + { + Playlist playlist( ( mlt_playlist )mlt_tractor_get_track( get_tractor( ), track ) ); + for ( cut = 0; !found && cut < playlist.count( ); cut ++ ) + { + Producer *clip = playlist.get_clip( cut ); + found = producer->get_producer( ) == clip->get_producer( ); + delete clip; + } + } + + track --; + cut --; + + return found; +} diff --git a/src/MltTractor.h b/src/MltTractor.h new file mode 100644 index 0000000..27d12a2 --- /dev/null +++ b/src/MltTractor.h @@ -0,0 +1,66 @@ +/** + * MltTractor.h - Tractor wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_TRACTOR_H_ +#define _MLTPP_TRACTOR_H_ + +#include "config.h" + +#include + +#include "MltProducer.h" + +namespace Mlt +{ + class Producer; + class Field; + class Multitrack; + class Transition; + class Filter; + + class MLTPP_DECLSPEC Tractor : public Producer + { + private: + mlt_tractor instance; + public: + Tractor( ); + Tractor( Service &tractor ); + Tractor( mlt_tractor tractor ); + Tractor( Tractor &tractor ); + Tractor( char *id, char *arg = NULL ); + virtual ~Tractor( ); + virtual mlt_tractor get_tractor( ); + mlt_producer get_producer( ); + Multitrack *multitrack( ); + Field *field( ); + void refresh( ); + int set_track( Producer &producer, int index ); + Producer *track( int index ); + int count( ); + void plant_transition( Transition &transition, int a_track = 0, int b_track = 1 ); + void plant_transition( Transition *transition, int a_track = 0, int b_track = 1 ); + void plant_filter( Filter &filter, int track = 0 ); + void plant_filter( Filter *filter, int track = 0 ); + bool locate_cut( Producer *producer, int &track, int &cut ); + }; +} + +#endif + diff --git a/src/MltTransition.cpp b/src/MltTransition.cpp new file mode 100644 index 0000000..935fd32 --- /dev/null +++ b/src/MltTransition.cpp @@ -0,0 +1,90 @@ +/** + * MltTransition.cpp - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include "MltTransition.h" +using namespace Mlt; + +Transition::Transition( char *id, char *arg ) : + instance( NULL ) +{ + if ( arg != NULL ) + { + instance = mlt_factory_transition( id, arg ); + } + else + { + if ( strchr( id, ':' ) ) + { + char *temp = strdup( id ); + char *arg = strchr( temp, ':' ) + 1; + *( arg - 1 ) = '\0'; + instance = mlt_factory_transition( temp, arg ); + free( temp ); + } + else + { + instance = mlt_factory_transition( id, NULL ); + } + } +} + +Transition::Transition( Service &transition ) : + instance( NULL ) +{ + if ( transition.type( ) == transition_type ) + { + instance = ( mlt_transition )transition.get_service( ); + inc_ref( ); + } +} + +Transition::Transition( Transition &transition ) : + instance( transition.get_transition( ) ) +{ + inc_ref( ); +} + +Transition::Transition( mlt_transition transition ) : + instance( transition ) +{ + inc_ref( ); +} + +Transition::~Transition( ) +{ + mlt_transition_close( instance ); +} + +mlt_transition Transition::get_transition( ) +{ + return instance; +} + +mlt_service Transition::get_service( ) +{ + return mlt_transition_service( get_transition( ) ); +} + +void Transition::set_in_and_out( int in, int out ) +{ + mlt_transition_set_in_and_out( get_transition( ), in, out ); +} diff --git a/src/MltTransition.h b/src/MltTransition.h new file mode 100644 index 0000000..81e548a --- /dev/null +++ b/src/MltTransition.h @@ -0,0 +1,49 @@ +/** + * MltTransition.h - MLT Wrapper + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _MLTPP_TRANSITION_H_ +#define _MLTPP_TRANSITION_H_ + +#include "config.h" + +#include +#include "MltService.h" + +namespace Mlt +{ + class Service; + + class MLTPP_DECLSPEC Transition : public Service + { + private: + mlt_transition instance; + public: + Transition( char *id, char *arg = NULL ); + Transition( Service &transition ); + Transition( Transition &transition ); + Transition( mlt_transition transition ); + virtual ~Transition( ); + virtual mlt_transition get_transition( ); + mlt_service get_service( ); + void set_in_and_out( int in, int out ); + }; +} + +#endif diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..8666415 --- /dev/null +++ b/src/config.h @@ -0,0 +1,34 @@ +/** + * config.h - Convenience header file for all mlt++ objects + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef MLTPP_CONFIG_H_ +#define MLTPP_CONFIG_H_ + +#ifdef WIN32 + #ifdef MLTPP_EXPORTS + #define MLTPP_DECLSPEC __declspec( dllexport ) + #else + #define MLTPP_DECLSPEC __declspec( dllimport ) + #endif +#else + #define MLTPP_DECLSPEC +#endif + +#endif diff --git a/swig/Makefile b/swig/Makefile new file mode 100644 index 0000000..26ae9dd --- /dev/null +++ b/swig/Makefile @@ -0,0 +1,10 @@ +SUBDIRS = perl python ruby tcl + +all clean install: + list='$(SUBDIRS)'; \ + for subdir in $$list; do \ + if [ -f $$subdir/Makefile -a -f .$$subdir ] ; \ + then $(MAKE) -C $$subdir $@ || exit 1; \ + fi \ + done + diff --git a/swig/configure b/swig/configure new file mode 100755 index 0000000..953e281 --- /dev/null +++ b/swig/configure @@ -0,0 +1,42 @@ +#!/usr/bin/env sh + +which swig > /dev/null 2>&1 +[ $? != 0 ] && echo "Please install swig" && exit 1 + +which mlt-config > /dev/null 2>&1 +[ $? != 0 ] && echo "Please install mlt" && exit 1 + +if [ "$1" = "all" ] +then languages="perl python ruby tcl" +elif [ "$1" != "" ] +then languages=$* +else echo "Usage: ./configure [ all | language * ]" + exit 0 +fi + +for i in perl python ruby tcl +do + rm -f .$i +done + +for i in $languages +do + echo -n "Configuring $i ... " + if [ -d "$i" ] + then + cd $i && + output=`./build 2>/dev/null` + if [ $? == 0 ] + then echo "OK" + touch ../.$i + elif [ "$output" == "" ] + then + echo "Failed" + else + echo $output + fi + cd .. + else + echo "Unknown" + fi +done diff --git a/swig/java/Play.java b/swig/java/Play.java new file mode 100644 index 0000000..3f6b4c8 --- /dev/null +++ b/swig/java/Play.java @@ -0,0 +1,51 @@ +import net.sourceforge.mltpp.*; + +public class Play { + + static { + System.loadLibrary("mltpp_java"); + } + + public static void main (String[] args) { + + // Start the mlt system + Factory.init( null ); + + // Create the producer + Producer p = new Producer( args[0], null ); + + if ( p.is_valid() ) { + + p.set ("eof", "loop"); + + // Create the consumer + Consumer c = new Consumer("sdl", null); + + // Turn off the default rescaling + c.set("rescale", "none"); + + // Connect the producer to the consumer + c.connect(p); + + // Start the consumer + c.start(); + + // Wait until the user stops the consumer + Object o = new Object(); + while ( !c.is_stopped() ) { + synchronized (o) { + try { + o.wait(1000); + } catch (InterruptedException e) { + // ignored + } + } + } + + // Stop it anyway + c.stop(); + } else { + System.out.println ("Unable to open " + args[0]); + } + } +} diff --git a/swig/java/Play.sh b/swig/java/Play.sh new file mode 100755 index 0000000..3bdc52c --- /dev/null +++ b/swig/java/Play.sh @@ -0,0 +1,2 @@ +#!/bin/env sh +java -Djava.library.path=. -cp .:src_swig Play "$@" diff --git a/swig/java/build b/swig/java/build new file mode 100755 index 0000000..74c81e5 --- /dev/null +++ b/swig/java/build @@ -0,0 +1,34 @@ +#!/usr/bin/env sh + +path=`which java 2> /dev/null` + +if [ $? = 0 ] +then + # Locate the path for the include + path=`dirname $path` + path=`dirname $path` + + # Change this as needed + export JAVA_INCLUDE="-I$path/include -I$path/include/linux" + + ln -sf ../mltpp.i . + + # Invoke swig + mkdir -p src_swig/net/sourceforge/mltpp + swig -c++ -I/usr/local/include/mlt++ `mlt-config --cflags` -java -outdir src_swig/net/sourceforge/mltpp -package net.sourceforge.mltpp mltpp.i || exit $? + + # Compile the wrapper + g++ -D_GNU_SOURCE -c -rdynamic -pthread -I/usr/local/include/mlt++ `mlt-config --cflags` mltpp_wrap.cxx $JAVA_INCLUDE || exit $? + + # Create the module + ld -shared mltpp_wrap.o -lmlt++ -o libmltpp_java.so || exit $? + + # Compile the test + javac `find src_swig -name '*.java'` || exit $? + + export CLASSPATH=`pwd`/src_swig + javac Play.java +else + echo "Java command not found" + exit 1 +fi diff --git a/swig/mltpp.i b/swig/mltpp.i new file mode 100644 index 0000000..7ea9571 --- /dev/null +++ b/swig/mltpp.i @@ -0,0 +1,142 @@ +/** + * mltpp.i - Swig Bindings for mlt++ + * Copyright (C) 2004-2005 Charles Yates + * Author: Charles Yates + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +%module mltpp +%include "carrays.i" +%array_class(unsigned char, unsignedCharArray); + +%{ +#include +%} + +/** These methods return objects which should be gc'd. + */ + +namespace Mlt { +%newobject Factory::producer( char *, char * ); +%newobject Factory::filter( char *, char * ); +%newobject Factory::transition( char *, char * ); +%newobject Factory::consumer( char *, char * ); +%newobject Properties::listen( char *, void *, mlt_listener ); +%newobject Service::producer( ); +%newobject Service::consumer( ); +%newobject Service::get_frame( int ); +%newobject Service::filter( int ); +%newobject Producer::filter( int ); +%newobject Producer::cut( int, int ); +%newobject Playlist::current( ); +%newobject Playlist::clip_info( int ); +%newobject Playlist::get_clip( int ); +%newobject Multitrack::track( int ); +%newobject Tractor::multitrack( ); +%newobject Tractor::field( ); +%newobject Tractor::track( int ); +%newobject Frame::get_original_producer( ); +%newobject Miracle::execute( char * ); +%newobject Miracle::push( char *, Service & ); +%newobject Miracle::unit( int ); +} + +/** Classes to wrap. + */ + +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include +%include + +#if defined(SWIGRUBY) + +%{ + +static void ruby_listener( mlt_properties owner, void *object ); + +class RubyListener +{ + private: + VALUE callback; + Mlt::Event *event; + + public: + RubyListener( Mlt::Properties &properties, char *id, VALUE callback ) : + callback( callback ) + { + event = properties.listen( id, this, ( mlt_listener )ruby_listener ); + } + + ~RubyListener( ) + { + delete event; + } + + void mark( ) + { + ((void (*)(VALUE))(rb_gc_mark))( callback ); + } + + void doit( ) + { + ID method = rb_intern( "call" ); + rb_funcall( callback, method, 0 ); + } +}; + +static void ruby_listener( mlt_properties owner, void *object ) +{ + RubyListener *o = static_cast< RubyListener * >( object ); + o->doit( ); +} + +void markRubyListener( void* p ) +{ + RubyListener *o = static_cast( p ); + o->mark( ); +} + +%} + +// Ruby wrapper +%rename( Listener ) RubyListener; +%markfunc RubyListener "markRubyListener"; + +class RubyListener +{ + public: + RubyListener( Mlt::Properties &properties, char *id, VALUE callback ); +}; + +#endif + diff --git a/swig/perl/Makefile.PL b/swig/perl/Makefile.PL new file mode 100644 index 0000000..4bc0ec6 --- /dev/null +++ b/swig/perl/Makefile.PL @@ -0,0 +1,16 @@ +#!/bin/env perl +use ExtUtils::MakeMaker; + +my $CXX = $ENV{'CXX'} || 'g++'; + +system( "ln -sf ../mltpp.i ." ); +system( "swig -c++ -I../../src `mlt-config --cflags` -perl5 mltpp.i" ); +WriteMakefile( + 'NAME' => 'mltpp', + 'CC' => '${CXX} `mlt-config --cflags` -I../../src', + 'OPTIMIZE' => '-O2 -g -pipe -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -m32 -march=i386', + 'LIBS' => ['-L../../src -lmlt++'], + 'OBJECT' => 'mltpp_wrap.o', + 'DESTDIR' => $ENV{'DESTDIR'}, +); + diff --git a/swig/perl/build b/swig/perl/build new file mode 100755 index 0000000..93e532c --- /dev/null +++ b/swig/perl/build @@ -0,0 +1,3 @@ +#!/bin/sh +perl Makefile.PL || exit 1 +make diff --git a/swig/perl/play.pl b/swig/perl/play.pl new file mode 100755 index 0000000..aae79e3 --- /dev/null +++ b/swig/perl/play.pl @@ -0,0 +1,43 @@ +#!/bin/env perl + +# Import required modules +use mltpp; + +# Not sure why the mltpp::Factory.init method fails... +mltpp::mlt_factory_init( undef ); + +# Create the producer +$p = new mltpp::Producer( $ARGV[0] ); + +if ( $p->is_valid( ) ) +{ + # Loop the video + $p->set( "eof", "loop" ); + + # Create the consumer + $c = new mltpp::FilteredConsumer( "sdl" ); + + # Turn of the default rescaling + $c->set( "rescale", "none" ); + + # Connect the producer to the consumer + $c->connect( $p ); + + $e = $c->setup_wait_for( "consumer-stopped" ); + + # Start the consumer + $c->start; + + # Wait until the user stops the consumer + $c->wait_for( $e ); + + $e = undef; + $c = undef; + $p = undef; +} +else +{ + print "Unable to open $ARGV[0]\n"; +} + +mltpp::mlt_factory_close( ); diff --git a/swig/python/build b/swig/python/build new file mode 100755 index 0000000..17ec48e --- /dev/null +++ b/swig/python/build @@ -0,0 +1,25 @@ +#!/bin/sh + +path=`which python 2> /dev/null` + +if [ $? == 0 ] +then + # Change this as needed + export PYTHON_INCLUDE=`python -c "import sys;print \"%s/include/python%d.%d\"%(sys.prefix,sys.version_info[0],sys.version_info[1])"` + + [ ! -d "$PYTHON_INCLUDE" ] && echo python development missing && exit 1 + + ln -sf ../mltpp.i . + + # Invoke swig + swig -c++ -I../../src `mlt-config --cflags` -python mltpp.i || exit $? + + # Compile the wrapper + g++ -D_GNU_SOURCE -c -rdynamic -pthread `mlt-config --cflags` -I$PYTHON_INCLUDE mltpp_wrap.cxx || exit $? + + # Create the module + ld -shared mltpp_wrap.o -L../../src -lmlt++ -o _mltpp.so || exit $? +else + echo Python not installed. + exit 1 +fi diff --git a/swig/python/play.py b/swig/python/play.py new file mode 100755 index 0000000..70be84d --- /dev/null +++ b/swig/python/play.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python + +# Import required modules +import mltpp +import time +import sys + +# Start the mlt system +mltpp.Factory.init( ) + +# Create the producer +p = mltpp.Producer( sys.argv[1] ) + +if p: + # Create the consumer + c = mltpp.Consumer( "sdl" ) + + # Turn off the default rescaling + c.set( "rescale", "none" ) + + # Connect the producer to the consumer + c.connect( p ) + + # Start the consumer + c.start( ) + + # Wait until the user stops the consumer + while c.is_stopped( ) == 0: + time.sleep( 1 ) +else: + # Diagnostics + print "Unable to open ", sys.argv[ 1 ] + diff --git a/swig/ruby/build b/swig/ruby/build new file mode 100755 index 0000000..46f9cc1 --- /dev/null +++ b/swig/ruby/build @@ -0,0 +1,8 @@ +#!/usr/bin/env ruby +require 'mkmf' +system( "ln -sf ../mltpp.i mltpp.i" ) +system( "swig -c++ -ruby -I../../src `mlt-config --cflags` mltpp.i" ) +$CFLAGS += " -I../../src `mlt-config --cflags`" +$LDFLAGS += " -L../../src -lmlt++" +create_makefile('mltpp') +system( 'make' ) diff --git a/swig/ruby/miracle.rb b/swig/ruby/miracle.rb new file mode 100755 index 0000000..2b5afc0 --- /dev/null +++ b/swig/ruby/miracle.rb @@ -0,0 +1,17 @@ +require 'mltpp' + +def command + puts "command" +end + +def push + puts "push" +end + +miracle = Mltpp::Miracle.new( "miracle-ruby", 5260 ) +miracle.start +miracle.execute( "uadd sdl" ) +listener = Mltpp::Listener.new( miracle, "command-received", method( :command ) ) +listener = Mltpp::Listener.new( miracle, "push-received", method( :push ) ) +miracle.wait_for_shutdown + diff --git a/swig/ruby/play.rb b/swig/ruby/play.rb new file mode 100755 index 0000000..9577e4e --- /dev/null +++ b/swig/ruby/play.rb @@ -0,0 +1,38 @@ +#!/usr/bin/env ruby + +# Import required modules +require 'mltpp' + +# Create the mlt system +Mltpp::Factory::init + +# Get and check the argument +file = ARGV.shift +raise "Usage: test.rb file" if file.nil? + +# Create the producer +producer = Mltpp::Factory::producer( file ) +raise "Unable to load #{file}" if !producer.is_valid + +# Create the consumer +consumer = Mltpp::Consumer.new( "sdl" ) +raise "Unable to open sdl consumer" if !consumer.is_valid + +# Turn off the default rescaling +consumer.set( "rescale", "none" ) + +# Set up a 'wait for' event +event = consumer.setup_wait_for( "consumer-stopped" ) + +# Start the consumer +consumer.start + +# Connect the producer to the consumer +consumer.connect( producer ) + +# Wait until the user stops the consumer +consumer.wait_for( event ) + +# Clean up consumer +consumer.stop + diff --git a/swig/ruby/thumbs.rb b/swig/ruby/thumbs.rb new file mode 100755 index 0000000..9e28782 --- /dev/null +++ b/swig/ruby/thumbs.rb @@ -0,0 +1,38 @@ +#!/usr/bin/env ruby + +# Required modules +require 'mltpp' + +# Create the mlt system +Mltpp::Factory::init + +# Get and check the argument +file = ARGV.shift +name = ARGV.shift +size = ARGV.shift +size = "192x144" if size.nil? +raise "Usage: thumbs.rb file name [ size ]" if file.nil? || name.nil? + +# Create the producer +producer = Mltpp::Producer.new( file ) +raise "Unable to load #{file}" if !producer.is_valid + +# Construct the playlist +playlist = Mltpp::Playlist.new( ) + +# Get the out point +out = producer.get_int( "out" ); + +# Calculate position of frames +[ 0, 0.25, 0.5, 0.75, 1 ].each { |x| playlist.append( producer, x*out, x*out ) } + +# Create the thumb nail generator +generator = Mltpp::Consumer.new( "avformat", "#{name}%d.jpg" ) +generator.set( "real_time", "0" ) +generator.set( "progressive", "1" ) +generator.set( "size", size ) + +# Connect the consumer +generator.connect( playlist ); +generator.run + diff --git a/swig/tcl/build b/swig/tcl/build new file mode 100755 index 0000000..548d3db --- /dev/null +++ b/swig/tcl/build @@ -0,0 +1,21 @@ +#!/bin/sh + +path=`which tclsh 2>/dev/null` + +if [ "$path" != "" ] +then + ln -sf ../mltpp.i . + + # Invoke swig + swig -c++ -I../../src `mlt-config --cflags` -tcl mltpp.i || exit 1 + + # Compile the wrapper + g++ -D_GNU_SOURCE -c -rdynamic -pthread -I../../src `mlt-config --cflags` mltpp_wrap.cxx || exit 1 + + # Create the module + ld -shared mltpp_wrap.o -L../../src -lmlt++ -o mltpp.so || exit 1 +else + echo "Unable to locate tclsh." + exit 1 +fi + diff --git a/swig/tcl/play.tcl b/swig/tcl/play.tcl new file mode 100755 index 0000000..5180b93 --- /dev/null +++ b/swig/tcl/play.tcl @@ -0,0 +1,17 @@ +#!/bin/env tclsh + +load mltpp.so +mltpp.Factory.init +set arg1 [lindex $argv 0] +set p [factory_producer fezzik $arg1] +set c [factory_consumer sdl ""] +set r [mlt_consumer_properties $c] +mlt_properties_set $r "rescale" "none" +consumer_connect $c $p +mlt_consumer_start $c +while { ![mlt_consumer_is_stopped $c] } { + after 1000 +} +mlt_consumer_close $c +mlt_producer_close $p +factory_close diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..b05717c --- /dev/null +++ b/test/Makefile @@ -0,0 +1,25 @@ +include ../config.mak + +CXXFLAGS+=-Wall -g `mlt-config --cflags` -I ../src +LDFLAGS+=-L../src -lmlt++ -lmiracle -lvalerie `mlt-config --libs` -L/usr/kde3/lib +CC=c++ + +all: play server + +play: play.o + +play.o: play.cpp + +server: server.o + +server.o: server.cpp + +clean: + $(RM) play play.o + $(RM) server server.o + +distclean: clean + +install: + +uninstall: diff --git a/test/play.cpp b/test/play.cpp new file mode 100644 index 0000000..459875d --- /dev/null +++ b/test/play.cpp @@ -0,0 +1,14 @@ + +#include +using namespace Mlt; + +int main( int argc, char **argv ) +{ + Factory::init( NULL ); + Producer producer( argv[ 1 ] ); + Consumer consumer; + consumer.set( "rescale", "none" ); + consumer.connect( producer ); + consumer.run( ); + return 0; +} diff --git a/test/server.cpp b/test/server.cpp new file mode 100644 index 0000000..be2214c --- /dev/null +++ b/test/server.cpp @@ -0,0 +1,133 @@ +#include +#include +#include +#include +using namespace std; + +#include +using namespace Mlt; + +class Custom : public Miracle +{ + private: + Event *event; + + public: + Custom( char *name = "Custom", int port = 5290, char *config = NULL ) : + Miracle( name, port, config ), + event( NULL ) + { + // Ensure that we receive the westley document before it's deserialised + set( "push-parser-off", 1 ); + } + + virtual ~Custom( ) + { + delete event; + } + + // Optional step - receive the westley document and do something with it + Response *received( char *command, char *document ) + { + cerr << document << endl; + Producer producer( "westley-xml", document ); + return push( command, &producer ); + } + + // Push handling - clear the playlist, append, seek to beginning and play + Response *push( char *command, Service *service ) + { + Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) ); + Producer producer( *service ); + if ( producer.is_valid( ) && playlist.is_valid( ) ) + { + playlist.lock( ); + playlist.clear( ); + playlist.append( producer ); + playlist.seek( 0 ); + playlist.set_speed( 1 ); + playlist.unlock( ); + return new Response( 200, "OK" ); + } + return new Response( 400, "Invalid" ); + } + + // Custom command execution + Response *execute( char *command ) + { + Response *response = NULL; + + if ( !strcmp( command, "debug" ) ) + { + // Example of a custom command + response = new Response( 200, "Diagnostics output" ); + for( int i = 0; unit( i ) != NULL; i ++ ) + { + Properties *properties = unit( i ); + stringstream output; + output << string( "Unit " ) << i << endl; + for ( int j = 0; j < properties->count( ); j ++ ) + output << properties->get_name( j ) << " = " << properties->get( j ) << endl; + response->write( output.str( ).c_str( ) ); + } + } + else + { + // Use the default command processing + response = Miracle::execute( command ); + } + + // If no event exists and the first unit has been added... + if ( event == NULL && unit( 0 ) != NULL ) + { + // Set up the event handling + Consumer consumer( ( mlt_consumer )( unit( 0 )->get_data( "consumer" ) ) ); + event = consumer.listen( "consumer-frame-render", this, ( mlt_listener )frame_render ); + + // In this custom case, we'll loop everything on the unit + Playlist playlist( ( mlt_playlist )( unit( 0 )->get_data( "playlist" ) ) ); + playlist.set( "eof", "loop" ); + } + + return response; + } + + // Callback for frame render notification + static void frame_render( mlt_consumer consumer, Custom *self, mlt_frame frame_ptr ) + { + Frame frame( frame_ptr ); + self->frame_render_event( frame ); + } + + // Remove all supers and attributes + void frame_render_event( Frame &frame ) + { + // Fetch the c double ended queue structure + mlt_deque deque = ( mlt_deque )frame.get_data( "data_queue" ); + + // While the deque isn't empty + while( deque != NULL && mlt_deque_peek_back( deque ) != NULL ) + { + // Fetch the c properties structure + mlt_properties cprops = ( mlt_properties )mlt_deque_pop_back( deque ); + + // For fun, convert it to c++ and output it :-) + Properties properties( cprops ); + properties.debug( ); + + // Wipe it + mlt_properties_close( cprops ); + } + } +}; + +int main( int argc, char **argv ) +{ + Custom server( "Server" ); + server.start( ); + server.execute( "uadd sdl" ); + server.execute( "play u0" ); + server.wait_for_shutdown( ); + return 0; +} +