]> git.sesse.net Git - mlt/blobdiff - docs/framework.txt
Mlt Ref Counts and Playlist split/join
[mlt] / docs / framework.txt
index e00d192a1a9d35a198bb1d5279d5188484afb7d3..4ffff1f5e595408e4f23fd66555d8353b4330ac3 100644 (file)
@@ -1,3 +1,10 @@
+Framework Documentation
+
+Copyright (C) 2004 Ushodaya Enterprises Limited
+Author: Charles Yates <charles.yates@pandora.be>
+Last Revision: 2004-03-20
+
+
 MLT FRAMEWORK
 -------------
 
@@ -7,7 +14,7 @@ Preamble:
        it provides a pluggable architecture for the inclusion of new audio/video 
        sources, filters, transitions and playback devices.
 
-       The MLT framework provides the structure and utility functionality on which
+       The framework provides the structure and utility functionality on which
        all of the MLT applications and services are defined. 
 
        On its own, the framework provides little more than 'abstract classes' and
@@ -16,8 +23,8 @@ Preamble:
 
        This document is split roughly into 3 sections. The first section provides a
        basic overview of MLT, the second section shows how it's used and the final
-       section shows shows structure and design, with an emphasis on how the system
-       is extended.
+       section shows structure and design, with an emphasis on how the system is 
+       extended.
 
 
 Target Audience:
@@ -75,7 +82,7 @@ Structure and Flow:
        A typical consumer requests MLT Frame objects from the producer, does 
        something with them and when finished with a frame, closes it. 
        
-        /\  A common confusion with the producer/consumer terminoligy used here is 
+        /\  A common confusion with the producer/consumer terminology used here is 
        /!!\ that a consumer may 'produce' something. For example, the libdv consumer
        \!!/ produces DV and the libdv producer seems to consume DV. However, the
         \/  naming conventions refer only to producers and consumers of MLT Frames.
@@ -253,6 +260,8 @@ Factories:
        +------------------+------------------------------------+------------------+
        |MLT_CONSUMER      |The default consumer                |"sdl" or other    |
        +------------------+------------------------------------+------------------+
+       |MLT_TEST_CARD     |The default test card producer      |any producer      |
+       +------------------+------------------------------------+------------------+
 
        These values are initialised from the environment variables of the same
        name.
@@ -290,15 +299,11 @@ Playlists:
        Let's assume that we're adapting the Hello World example, and wish to queue
        a number of files for playout, ie:
 
-               hello *.avi
+           hello *.avi
 
        Instead of invoking mlt_factory_producer directly, we'll create a new
        function called create_playlist. This function is responsible for creating
-       the playlist, creating each producer, appending to the playlist and ensuring
-       that all the producers are cleaned up when the playlist is destroyed. The
-       last point is important - a close on the playlist won't explicitly these 
-       producers. In this example, we use unique "data" properties with destructors
-       to ensure closing.
+       the playlist, creating each producer and appending to the playlist.
 
        mlt_producer create_playlist( int argc, char **argv )
        {
@@ -312,26 +317,28 @@ Playlists:
            int i = 0;
            for ( i = 1; i < argc; i ++ )
            {
-               // Definie the unique key
-               char key[ 256 ];
-
                // Create the producer
                mlt_producer producer = mlt_factory_producer( NULL, argv[ i ] );
 
                // Add it to the playlist
                mlt_playlist_append( playlist, producer );
 
-               // Create a unique key for this producer
-               sprintf( key, "producer%d", i );
-
-               // Now we need to ensure the producers are destroyed
-               mlt_properties_set_data( properties, key, producer, 0, ( mlt_destructor )mlt_producer_close, NULL );
+                       // Close the producer (see below)
+                       mlt_producer_close( producer );
            }
 
            // Return the playlist as a producer
            return mlt_playlist_producer( playlist );
        }
 
+       Notice that we close the producer after the append. Actually, what we're 
+       doing is closing our reference to it - the playlist creates its own reference
+       to the producer on append and insert, and it will close its reference 
+       when the playlist is destroyed[*].
+
+       Note also that if you append multiple instances of the same producer, it 
+       will create multiple references to it.
+
        Now all we need do is to replace these lines in the main function:
 
            // Create a normalised producer
@@ -344,6 +351,10 @@ Playlists:
 
        and we have a means to play multiple clips.
 
+       [*] This reference functionality was introduced in mlt 0.1.2 - it is 100%
+       compatable with the early mechanism of registering the reference and 
+       destructor with the properties of the playlist object.
+
 
 Filters:
 
@@ -373,14 +384,14 @@ Filters:
        properties can be set as needed.
 
        The additional argument in the filter connection is an important one as it
-       dicates the 'track' on which the filter operates. For basic producers and
+       dictates the 'track' on which the filter operates. For basic producers and
        playlists, there's only one track (0), and as you will see in the next
        section, even multiple tracks have a single track output.
 
 
 Multiple Tracks and Transitions:
 
-       MLT's approach to mutliple tracks is governed by two requirements:
+       MLT's approach to multiple tracks is governed by two requirements:
 
        1) The need for a consumer and producer to communicate with one another via
        a single frame;
@@ -396,8 +407,9 @@ Multiple Tracks and Transitions:
                           +------------------------------+
 
        The overlapping areas of track 0 and 1 would (presumably) have some kind of
-       transition - without a transition, the frames from a1 and a2 would be shown 
-       during the areas of overlap.
+       transition - without a transition, the frames from b1 and b2 would be shown 
+       during the areas of overlap (ie: by default, the higher numbered track takes 
+       precedence over the lower numbered track). 
 
        MLT has a multitrack object, but it is not a producer in the sense that it
        can be connected directly to a consumer and everything will work correctly.
@@ -416,7 +428,7 @@ Multiple Tracks and Transitions:
        evenly, the correct frame is output and that we have 'producer like'
        behaviour.
 
-       Thus, a mulitrack is conceptually 'pulled' by a tractor as shown here:
+       Thus, a multitrack is conceptually 'pulled' by a tractor as shown here:
 
        +----------+
        |multitrack|
@@ -434,16 +446,16 @@ Multiple Tracks and Transitions:
        +----------+
 
        With a combination of the two, we can now connect multitracks to consumers.
-       The first non-test card will be retrieved and passed on. 
+       The last non-test card will be retrieved and passed on. 
 
        The tracks can be producers, playlists, or even other tractors. 
 
-       Now we wish to insert filters and transitions between the mulitrack and the
+       Now we wish to insert filters and transitions between the multitrack and the
        tractor. We can do this directly by inserting filters directly between the
        tractor and the multitrack, but this involves a lot of connecting and
        reconnecting left and right producers and consumers, and it seemed only fair
        that we should be able to automate that process. 
-       
+
        So in keeping with our agricultural theme, the concept of the 'field' was 
        born. We 'plant' filters and transitions in the field and the tractor pulls 
        the multitrack (think of a combine harvester :-)) over the field and 
@@ -529,7 +541,9 @@ Multiple Tracks and Transitions:
            mlt_properties_set_position( properties, "in", 0 );
            mlt_properties_set_position( properties, "out", length - 1 );
            mlt_properties_set_position( properties, "length", length );
-       
+           mlt_properties_set_int( properties, "a_track", 0 );
+           mlt_properties_set_int( properties, "b_track", 1 );
+
            // Now set the properties on the transition
            properties = mlt_transition_properties( transition );
            mlt_properties_set_position( properties, "in", 0 );
@@ -567,13 +581,16 @@ Multiple Tracks and Transitions:
        and we have a means to play multiple clips with a horribly obtrusive
        watermark - just what the world needed, right? ;-)
 
+       Incidentally, the same thing could be achieved with the more trivial
+       watermark filter inserted between the producer and the consumer.
+
 
 SECTION 3 - STRUCTURE AND DESIGN
 --------------------------------
 
-Class Heirachy:
+Class Hierarchy:
 
-       The mlt framework consists of an OO class heirachy which consists of the
+       The mlt framework consists of an OO class hierarchy which consists of the
        following public classes and abstractions:
 
        mlt_properties
@@ -643,7 +660,7 @@ mlt_properties:
        too.
 
        Steps 6 and 7 demonstrate that the properties object handles deserialisation
-       from strings. The string value of "50" is set, the integer value of 50 is
+       from strings. The string value of "0" is set, the integer value of 0 is
        retrieved.
 
        Steps 8 and 9 demonstrate that the properties object handles serialisation
@@ -652,7 +669,6 @@ mlt_properties:
        To show all the name/value pairs in a properties, it is possible to iterate
        through them:
 
-           int i = 0;
            for ( i = 0; i < mlt_properties_count( properties ); i ++ )
                printf( "%s = %s\n", mlt_properties_get_name( properties, i ),
                                     mlt_properties_get_value( properties, i ) );
@@ -729,8 +745,10 @@ mlt_deque:
        * Reverse Polish Notation (RPN) image and audio operations
        * memory pooling
 
-       The queuing operations are used in typical frame based consumers to allow
-       buffering.
+       The queuing operations are used in:
+       
+       * the consumer base class;
+       * consumer implementations may require further queues.
 
 
 mlt_pool:
@@ -904,7 +922,7 @@ mlt_frame:
        +------------------+------------------------------------+------------------+
        |samples           |The samples of the audio            |                  |
        +------------------+------------------------------------+------------------+
-       |aspect_ratio      |The aspect ratio of the image       |double            |
+       |aspect_ratio      |The sample aspect ratio of the image|double            |
        +------------------+------------------------------------+------------------+
        |test_image        |Used to indicate no image available |0 or 1            |
        +------------------+------------------------------------+------------------+
@@ -923,8 +941,8 @@ mlt_frame:
        |rescale.interp    |Use this scale method for test image|"string"          |
        +------------------+------------------------------------+------------------+
 
-       While most of these are mainly self explainatory, the normalised_width and
-       normalised_height values require a little explaination. These are required
+       While most of these are mainly self explanatory, the normalised_width and
+       normalised_height values require a little explanation. These are required
        to ensure that effects are consistently handled as PAL or NTSC, regardless 
        of the consumers or producers width/height image request. 
 
@@ -958,6 +976,7 @@ mlt_frame:
        void *mlt_frame_pop_audio( mlt_frame this );
        void mlt_frame_close( mlt_frame this );
 
+
 mlt_service:
 
        The service base class extends properties and allows 0 to m inputs and 0 to
@@ -991,8 +1010,7 @@ mlt_service:
        void mlt_service_close( mlt_service this );
 
        Typically, only direct descendents of services need invoke these methods and
-       developers are encouraged to use those extensions when definining new
-       services.
+       developers are encouraged to use those extensions when defining new services. 
 
 
 mlt_producer:
@@ -1040,6 +1058,7 @@ mlt_producer:
 
        The public interface is defined by the following functions:
 
+       mlt_producer mlt_producer_new( );
        int mlt_producer_init( mlt_producer this, void *child );
        mlt_service mlt_producer_service( mlt_producer this );
        mlt_properties mlt_producer_properties( mlt_producer this );
@@ -1057,46 +1076,6 @@ mlt_producer:
        void mlt_producer_prepare_next( mlt_producer this );
        void mlt_producer_close( mlt_producer this );
 
-       For the sake of discussion here, we'll assume that someone wants to provide
-       a new producer which simply generates green frames and silent audio :-) -
-       we'll call the producer 'green'.
-
-       // Forward reference
-       static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int index );
-
-       mlt_producer producer_green( void *arg )
-       {
-               // Create a new producer
-               mlt_producer this = mlt_producer_new( );
-
-               // Check that we were allocated a new producer
-               if ( this != NULL )
-               {
-                       // Get the service 
-                       mlt_service service = mlt_producer_service( this );
-
-                       // We need to override the get_frame method
-                       service->get_frame = producer_get_frame;
-               }
-
-               // Return this producer
-               return this;
-       }
-
-       static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int index )
-       {
-               // Create a new frame
-               *frame = mlt_frame_init( );
-
-               // Specify the get_image
-               mlt_frame_push_get_image( *frame, producer_get_image );
-
-               // Specify the get_audio
-               mlt_frame_push_audio( *frame, producer_get_audio );
-
-               // Return that all was successful
-               return 0;
-       }
 
 mlt_filter:
 
@@ -1178,7 +1157,3 @@ mlt_playlist:
        void mlt_playlist_close( mlt_playlist this );
 
 mlt_tractor:
-
-
-mlt_factory
-