]> git.sesse.net Git - mlt/commitdiff
Removal of timecodes, consumer libdv, serialisation of inigo
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 14 Jan 2004 11:44:44 +0000 (11:44 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Wed, 14 Jan 2004 11:44:44 +0000 (11:44 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@74 d19143bc-622f-0410-bfdd-b5b2a6649095

82 files changed:
docs/testing-20040110.txt
mlt/docs/testing-20040110.txt
mlt/src/framework/mlt_consumer.c
mlt/src/framework/mlt_factory.c
mlt/src/framework/mlt_field.c
mlt/src/framework/mlt_field.h
mlt/src/framework/mlt_filter.c
mlt/src/framework/mlt_filter.h
mlt/src/framework/mlt_frame.c
mlt/src/framework/mlt_frame.h
mlt/src/framework/mlt_multitrack.c
mlt/src/framework/mlt_multitrack.h
mlt/src/framework/mlt_playlist.c
mlt/src/framework/mlt_playlist.h
mlt/src/framework/mlt_producer.c
mlt/src/framework/mlt_producer.h
mlt/src/framework/mlt_properties.c
mlt/src/framework/mlt_properties.h
mlt/src/framework/mlt_property.c
mlt/src/framework/mlt_property.h
mlt/src/framework/mlt_tractor.c
mlt/src/framework/mlt_tractor.h
mlt/src/framework/mlt_transition.c
mlt/src/framework/mlt_transition.h
mlt/src/framework/mlt_types.h
mlt/src/inigo/inigo.c
mlt/src/miracle/miracle_unit.c
mlt/src/modules/core/producer_ppm.c
mlt/src/modules/core/transition_composite.c
mlt/src/modules/core/transition_luma.c
mlt/src/modules/dv/Makefile
mlt/src/modules/dv/configure
mlt/src/modules/dv/consumer_libdv.c [new file with mode: 0644]
mlt/src/modules/dv/consumer_libdv.h [new file with mode: 0644]
mlt/src/modules/dv/factory.c
mlt/src/modules/dv/producer_libdv.c
mlt/src/modules/ffmpeg/filter_ffmpeg_dub.c
mlt/src/modules/ffmpeg/producer_ffmpeg.c
mlt/src/modules/gtk2/producer_pango.c
mlt/src/modules/gtk2/producer_pixbuf.c
mlt/src/modules/inigo/producer_inigo.c
mlt/src/modules/sdl/consumer_sdl.c
src/framework/mlt_consumer.c
src/framework/mlt_factory.c
src/framework/mlt_field.c
src/framework/mlt_field.h
src/framework/mlt_filter.c
src/framework/mlt_filter.h
src/framework/mlt_frame.c
src/framework/mlt_frame.h
src/framework/mlt_multitrack.c
src/framework/mlt_multitrack.h
src/framework/mlt_playlist.c
src/framework/mlt_playlist.h
src/framework/mlt_producer.c
src/framework/mlt_producer.h
src/framework/mlt_properties.c
src/framework/mlt_properties.h
src/framework/mlt_property.c
src/framework/mlt_property.h
src/framework/mlt_tractor.c
src/framework/mlt_tractor.h
src/framework/mlt_transition.c
src/framework/mlt_transition.h
src/framework/mlt_types.h
src/inigo/inigo.c
src/miracle/miracle_unit.c
src/modules/core/producer_ppm.c
src/modules/core/transition_composite.c
src/modules/core/transition_luma.c
src/modules/dv/Makefile
src/modules/dv/configure
src/modules/dv/consumer_libdv.c [new file with mode: 0644]
src/modules/dv/consumer_libdv.h [new file with mode: 0644]
src/modules/dv/factory.c
src/modules/dv/producer_libdv.c
src/modules/ffmpeg/filter_ffmpeg_dub.c
src/modules/ffmpeg/producer_ffmpeg.c
src/modules/gtk2/producer_pango.c
src/modules/gtk2/producer_pixbuf.c
src/modules/inigo/producer_inigo.c
src/modules/sdl/consumer_sdl.c

index 235fd72c8d90da12f5cf3cf274d77606560a7c34..16c41fa7801e47a8eb65394f1ed01006ad85e5ba 100644 (file)
@@ -26,10 +26,8 @@ Incorrect Behaviour
 killall miracle does not work. requires killall -HUP
 STOP does not play the test card (white silence) (=pause)
 USTA when stopped reports "paused"
-REW when stopped does not rewind to the beginning of the clip.
 CLEAN removes all clips (as opposed to leaving the currently playing one)
 USET eof=pause is partially supported
-SIN/SOUT do not leave the unit in a paused state
 
 
 Different Intentional Behaviour
index 235fd72c8d90da12f5cf3cf274d77606560a7c34..16c41fa7801e47a8eb65394f1ed01006ad85e5ba 100644 (file)
@@ -26,10 +26,8 @@ Incorrect Behaviour
 killall miracle does not work. requires killall -HUP
 STOP does not play the test card (white silence) (=pause)
 USTA when stopped reports "paused"
-REW when stopped does not rewind to the beginning of the clip.
 CLEAN removes all clips (as opposed to leaving the currently playing one)
 USET eof=pause is partially supported
-SIN/SOUT do not leave the unit in a paused state
 
 
 Different Intentional Behaviour
index f263a205c8afaa85eaa840e2cb026c1c0e5a725a..5ff7f5f73f39f4cfb28cdd28bec1351b9840b658 100644 (file)
@@ -63,8 +63,15 @@ int mlt_consumer_connect( mlt_consumer this, mlt_service producer )
 
 void mlt_consumer_close( mlt_consumer this )
 {
-       if ( this->close != NULL )
-               this->close( this );
+       // Get the childs close function
+       void ( *consumer_close )( ) = this->close;
+
+       // Make sure it only gets called once
+       this->close = NULL;
+
+       // Call the childs close if available
+       if ( consumer_close != NULL )
+               consumer_close( this );
        else
                mlt_service_close( &this->parent );
 }
index 9795770ba430f94ac293b4e3b6689bf37087d687..9223178994163a2542f7d7395862c80fdfd77b55 100644 (file)
@@ -19,9 +19,8 @@
  */
 
 #include "config.h"
-#include "mlt_factory.h"
+#include "mlt.h"
 #include "mlt_repository.h"
-#include "mlt_properties.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -41,22 +40,26 @@ static mlt_repository consumers = NULL;
 
 int mlt_factory_init( char *prefix )
 {
-       // If no directory is specified, default to install directory
-       if ( prefix == NULL )
-               prefix = PREFIX_DATA;
-
-       // Store the prefix for later retrieval
-       mlt_prefix = strdup( prefix );
-
-       // Create the object list.
-       object_list = calloc( sizeof( struct mlt_properties_s ), 1 );
-       mlt_properties_init( object_list, NULL );
-
-       // Create a repository for each service type
-       producers = mlt_repository_init( object_list, prefix, "producers.dat", "mlt_create_producer" );
-       filters = mlt_repository_init( object_list, prefix, "filters.dat", "mlt_create_filter" );
-       transitions = mlt_repository_init( object_list, prefix, "transitions.dat", "mlt_create_transition" );
-       consumers = mlt_repository_init( object_list, prefix, "consumers.dat", "mlt_create_consumer" );
+       // Only initialise once
+       if ( mlt_prefix == NULL )
+       {
+               // If no directory is specified, default to install directory
+               if ( prefix == NULL )
+                       prefix = PREFIX_DATA;
+
+               // Store the prefix for later retrieval
+               mlt_prefix = strdup( prefix );
+
+               // Create the object list.
+               object_list = calloc( sizeof( struct mlt_properties_s ), 1 );
+               mlt_properties_init( object_list, NULL );
+
+               // Create a repository for each service type
+               producers = mlt_repository_init( object_list, prefix, "producers.dat", "mlt_create_producer" );
+               filters = mlt_repository_init( object_list, prefix, "filters.dat", "mlt_create_filter" );
+               transitions = mlt_repository_init( object_list, prefix, "transitions.dat", "mlt_create_transition" );
+               consumers = mlt_repository_init( object_list, prefix, "consumers.dat", "mlt_create_consumer" );
+       }
 
        return 0;
 }
@@ -74,7 +77,14 @@ const char *mlt_factory_prefix( )
 
 mlt_producer mlt_factory_producer( char *service, void *input )
 {
-       return ( mlt_producer )mlt_repository_fetch( producers, service, input );
+       mlt_producer obj = mlt_repository_fetch( producers, service, input );
+       if ( obj != NULL )
+       {
+               mlt_properties properties = mlt_producer_properties( obj );
+               mlt_properties_set( properties, "mlt_type", "producer" );
+               mlt_properties_set( properties, "mlt_service", service );
+       }
+       return obj;
 }
 
 /** Fetch a filter from the repository.
@@ -82,7 +92,14 @@ mlt_producer mlt_factory_producer( char *service, void *input )
 
 mlt_filter mlt_factory_filter( char *service, void *input )
 {
-       return ( mlt_filter )mlt_repository_fetch( filters, service, input );
+       mlt_filter obj = mlt_repository_fetch( filters, service, input );
+       if ( obj != NULL )
+       {
+               mlt_properties properties = mlt_filter_properties( obj );
+               mlt_properties_set( properties, "mlt_type", "filter" );
+               mlt_properties_set( properties, "mlt_service", service );
+       }
+       return obj;
 }
 
 /** Fetch a transition from the repository.
@@ -90,7 +107,14 @@ mlt_filter mlt_factory_filter( char *service, void *input )
 
 mlt_transition mlt_factory_transition( char *service, void *input )
 {
-       return ( mlt_transition )mlt_repository_fetch( transitions, service, input );
+       mlt_transition obj = mlt_repository_fetch( transitions, service, input );
+       if ( obj != NULL )
+       {
+               mlt_properties properties = mlt_transition_properties( obj );
+               mlt_properties_set( properties, "mlt_type", "transition" );
+               mlt_properties_set( properties, "mlt_service", service );
+       }
+       return obj;
 }
 
 /** Fetch a consumer from the repository
@@ -98,7 +122,14 @@ mlt_transition mlt_factory_transition( char *service, void *input )
 
 mlt_consumer mlt_factory_consumer( char *service, void *input )
 {
-       return ( mlt_consumer )mlt_repository_fetch( consumers, service, input );
+       mlt_consumer obj = mlt_repository_fetch( consumers, service, input );
+       if ( obj != NULL )
+       {
+               mlt_properties properties = mlt_consumer_properties( obj );
+               mlt_properties_set( properties, "mlt_type", "consumer" );
+               mlt_properties_set( properties, "mlt_service", service );
+       }
+       return obj;
 }
 
 /** Close the factory.
@@ -106,12 +137,16 @@ mlt_consumer mlt_factory_consumer( char *service, void *input )
 
 void mlt_factory_close( )
 {
-       mlt_repository_close( producers );
-       mlt_repository_close( filters );
-       mlt_repository_close( transitions );
-       mlt_repository_close( consumers );
-       mlt_properties_close( object_list );
-       free( mlt_prefix );
-       free( object_list );
+       if ( mlt_prefix != NULL )
+       {
+               mlt_repository_close( producers );
+               mlt_repository_close( filters );
+               mlt_repository_close( transitions );
+               mlt_repository_close( consumers );
+               mlt_properties_close( object_list );
+               free( mlt_prefix );
+               free( object_list );
+               mlt_prefix = NULL;
+       }
 }
 
index a54d97e19e1cf4672672efc3702461d0b36d3833..8a7f51f47f2595e1c75c5fce47d63858dc6734bc 100644 (file)
@@ -89,6 +89,14 @@ mlt_multitrack mlt_field_multitrack( mlt_field this )
        return this->multitrack;
 }
 
+/** Get the tractor.
+*/
+
+mlt_tractor mlt_field_tractor( mlt_field this )
+{
+       return this->tractor;
+}
+
 /** Get the properties associated to this field.
 */
 
index 6fef29606890b9174f36f2f669aeddc4f33f3c77..d84d0cc09a5b0882d3f89b2ea98e32519d01f13d 100644 (file)
@@ -25,6 +25,7 @@
 
 extern mlt_field mlt_field_init( );
 extern mlt_service mlt_field_service( mlt_field this );
+extern mlt_tractor mlt_field_tractor( mlt_field this );
 extern mlt_multitrack mlt_field_multitrack( mlt_field this );
 extern mlt_properties mlt_field_properties( mlt_field this );
 extern int mlt_field_plant_filter( mlt_field this, mlt_filter that, int track );
index 9c0a295234443da8b29cf4105fe6313eb04f6e8c..6e39e7971a04185e5e4b5abfe4d52b30d8b7117b 100644 (file)
@@ -45,8 +45,8 @@ int mlt_filter_init( mlt_filter this, void *child )
                service->get_frame = filter_get_frame;
 
                // Default in, out, track properties
-               mlt_properties_set_timecode( properties, "in", 0 );
-               mlt_properties_set_timecode( properties, "out", 0 );
+               mlt_properties_set_position( properties, "in", 0 );
+               mlt_properties_set_position( properties, "out", 0 );
                mlt_properties_set_int( properties, "track", 0 );
 
                return 0;
@@ -80,8 +80,8 @@ int mlt_filter_connect( mlt_filter this, mlt_service producer, int index )
        {
                mlt_properties properties = mlt_service_properties( &this->parent );
                this->producer = producer;
-               mlt_properties_set_timecode( properties, "in", 0 );
-               mlt_properties_set_timecode( properties, "out", 0 );
+               mlt_properties_set_position( properties, "in", 0 );
+               mlt_properties_set_position( properties, "out", 0 );
                mlt_properties_set_int( properties, "track", index );
        }
        
@@ -91,11 +91,11 @@ int mlt_filter_connect( mlt_filter this, mlt_service producer, int index )
 /** Tune the in/out points.
 */
 
-void mlt_filter_set_in_and_out( mlt_filter this, mlt_timecode in, mlt_timecode out )
+void mlt_filter_set_in_and_out( mlt_filter this, mlt_position in, mlt_position out )
 {
        mlt_properties properties = mlt_service_properties( &this->parent );
-       mlt_properties_set_timecode( properties, "in", in );
-       mlt_properties_set_timecode( properties, "out", out );
+       mlt_properties_set_position( properties, "in", in );
+       mlt_properties_set_position( properties, "out", out );
 }
 
 /** Return the track that this filter is operating on.
@@ -110,19 +110,19 @@ int mlt_filter_get_track( mlt_filter this )
 /** Get the in point.
 */
 
-mlt_timecode mlt_filter_get_in( mlt_filter this )
+mlt_position mlt_filter_get_in( mlt_filter this )
 {
        mlt_properties properties = mlt_service_properties( &this->parent );
-       return mlt_properties_get_timecode( properties, "in" );
+       return mlt_properties_get_position( properties, "in" );
 }
 
 /** Get the out point.
 */
 
-mlt_timecode mlt_filter_get_out( mlt_filter this )
+mlt_position mlt_filter_get_out( mlt_filter this )
 {
        mlt_properties properties = mlt_service_properties( &this->parent );
-       return mlt_properties_get_timecode( properties, "out" );
+       return mlt_properties_get_position( properties, "out" );
 }
 
 /** Process the frame.
@@ -156,8 +156,8 @@ static int filter_get_frame( mlt_service service, mlt_frame_ptr frame, int index
                {
                        if ( !mlt_frame_is_test_card( *frame ) )
                        {
-                               mlt_timecode timecode = mlt_frame_get_timecode( *frame );
-                               if ( timecode >= in && ( out == 0 || timecode < out ) )
+                               mlt_position position = mlt_frame_get_position( *frame );
+                               if ( position >= in && ( out == 0 || position < out ) )
                                        *frame = filter_process( this, *frame );
                        }
                        return 0;
index e3f0f74dccdb4586dacb0b0a1a2e97627a325644..edaf6f626b30d2d160d2211bb7a5f6f2be3536a1 100644 (file)
@@ -51,10 +51,10 @@ extern int mlt_filter_init( mlt_filter this, void *child );
 extern mlt_service mlt_filter_service( mlt_filter this );
 extern mlt_properties mlt_filter_properties( mlt_filter this );
 extern int mlt_filter_connect( mlt_filter this, mlt_service producer, int index );
-extern void mlt_filter_set_in_and_out( mlt_filter this, mlt_timecode in, mlt_timecode out );
+extern void mlt_filter_set_in_and_out( mlt_filter this, mlt_position in, mlt_position out );
 extern int mlt_filter_get_track( mlt_filter this );
-extern mlt_timecode mlt_filter_get_in( mlt_filter this );
-extern mlt_timecode mlt_filter_get_out( mlt_filter this );
+extern mlt_position mlt_filter_get_in( mlt_filter this );
+extern mlt_position mlt_filter_get_out( mlt_filter this );
 extern void mlt_filter_close( mlt_filter );
 
 #endif
index a51fb7e68896e60e903843c81c73a7e674db5f8e..cb26ee944abf93738b744768b1f7464e8afe467b 100644 (file)
@@ -53,7 +53,7 @@ mlt_frame mlt_frame_init( )
                mlt_properties_init( properties, this );
 
                // Set default properties on the frame
-               mlt_properties_set_timecode( properties, "timecode", 0.0 );
+               mlt_properties_set_position( properties, "position", 0.0 );
                mlt_properties_set_data( properties, "image", NULL, 0, NULL, NULL );
                mlt_properties_set_int( properties, "width", 720 );
                mlt_properties_set_int( properties, "height", 576 );
@@ -98,22 +98,22 @@ int mlt_frame_set_aspect_ratio( mlt_frame this, double value )
        return mlt_properties_set_double( properties, "aspect_ratio", value );
 }
 
-/** Get the timecode of this frame.
+/** Get the position of this frame.
 */
 
-mlt_timecode mlt_frame_get_timecode( mlt_frame this )
+mlt_position mlt_frame_get_position( mlt_frame this )
 {
        mlt_properties properties = mlt_frame_properties( this );
-       return mlt_properties_get_timecode( properties, "timecode" );
+       return mlt_properties_get_position( properties, "position" );
 }
 
-/** Set the timecode of this frame.
+/** Set the position of this frame.
 */
 
-int mlt_frame_set_timecode( mlt_frame this, mlt_timecode value )
+int mlt_frame_set_position( mlt_frame this, mlt_position value )
 {
        mlt_properties properties = mlt_frame_properties( this );
-       return mlt_properties_set_timecode( properties, "timecode", value );
+       return mlt_properties_set_position( properties, "position", value );
 }
 
 /** Stack a get_image callback.
@@ -709,7 +709,7 @@ int mlt_frame_mix_audio( mlt_frame this, mlt_frame that, float weight, int16_t *
        int i, j;
 
        mlt_frame_get_audio( this, &p_dest, format, &frequency_dest, &channels_dest, &samples_dest );
-       //fprintf( stderr, "frame dest samples %d channels %d timecode %f\n", samples_dest, channels_dest, mlt_properties_get_timecode( mlt_frame_properties( this ), "timecode" ) );
+       //fprintf( stderr, "frame dest samples %d channels %d position %f\n", samples_dest, channels_dest, mlt_properties_get_position( mlt_frame_properties( this ), "position" ) );
        mlt_frame_get_audio( that, &p_src, format, &frequency_src, &channels_src, &samples_src );
        //fprintf( stderr, "frame src  samples %d channels %d\n", samples_src, channels_src );
        if ( channels_src > 6 )
index 175df0acf5c8a6b53cf4a29fea03132260b73319..58476d546d1816c621a7152a44575b567ca582d2 100644 (file)
@@ -70,8 +70,8 @@ extern mlt_properties mlt_frame_properties( mlt_frame this );
 extern int mlt_frame_is_test_card( mlt_frame this );
 extern double mlt_frame_get_aspect_ratio( mlt_frame this );
 extern int mlt_frame_set_aspect_ratio( mlt_frame this, double value );
-extern mlt_timecode mlt_frame_get_timecode( mlt_frame this );
-extern int mlt_frame_set_timecode( mlt_frame this, mlt_timecode value );
+extern mlt_position mlt_frame_get_position( mlt_frame this );
+extern int mlt_frame_set_position( mlt_frame this, mlt_position value );
 
 extern int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable );
 extern uint8_t *mlt_frame_get_alpha_mask( mlt_frame this );
index 893cef5f6b9c457cdb8751172c42253f917e9cbd..47bc271d1e421a4d7ff4ba4b3f46ba2897b0b3ed 100644 (file)
@@ -96,7 +96,7 @@ mlt_properties mlt_multitrack_properties( mlt_multitrack this )
        return mlt_service_properties( mlt_multitrack_service( this ) );
 }
 
-/** Initialise timecode related information.
+/** Initialise position related information.
 */
 
 void mlt_multitrack_refresh( mlt_multitrack this )
@@ -107,7 +107,7 @@ void mlt_multitrack_refresh( mlt_multitrack this )
        mlt_properties properties = mlt_multitrack_properties( this );
 
        // We need to ensure that the multitrack reports the longest track as its length
-       mlt_timecode length = 0;
+       mlt_position length = 0;
 
        // We need to ensure that fps are the same on all services
        double fps = 0;
@@ -146,8 +146,8 @@ void mlt_multitrack_refresh( mlt_multitrack this )
        }
 
        // Update multitrack properties now - we'll not destroy the in point here
-       mlt_properties_set_timecode( properties, "length", length );
-       mlt_properties_set_timecode( properties, "out", length );
+       mlt_properties_set_position( properties, "length", length );
+       mlt_properties_set_position( properties, "out", length );
        mlt_properties_set_double( properties, "fps", fps );
 }
 
@@ -208,10 +208,10 @@ int mlt_multitrack_connect( mlt_multitrack this, mlt_producer producer, int trac
        0.0, 1.0, b0.0, 0.1, b1.1, 1.1, 0.1, 0.2, [out of playlist2], [out of playlist1]
 */
 
-mlt_timecode mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index )
+mlt_position mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index )
 {
        int first = 1;
-       mlt_timecode position = 0;
+       mlt_position position = 0;
        int i = 0;
 
        // Loop through each of the tracks
@@ -232,7 +232,7 @@ mlt_timecode mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int in
                        // We only consider playlists
                        if ( playlist != NULL )
                        {
-                               // Locate the smallest timecode
+                               // Locate the smallest position
                                if ( first )
                                {
                                        // First position found
@@ -244,13 +244,17 @@ mlt_timecode mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int in
                                else
                                {
                                        // Obtain the clip position in this playlist
-                                       mlt_timecode position2 = mlt_playlist_clip( playlist, whence, index );
+                                       //mlt_position position2 = mlt_playlist_clip( playlist, whence, index );
 
                                        // If this position is prior to the first, then use it
-                                       if ( position2 < position )
-                                               position = position2;
+                                       //if ( position2 < position )
+                                               //position = position2;
                                }
                        }
+                       else
+                       {
+                               fprintf( stderr, "track %d isn't a playlist\n", index );
+                       }
                }
        }
 
@@ -293,11 +297,11 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int ind
                // Get the producer for this track
                mlt_producer producer = this->list[ index ];
 
-               // Obtain the current timecode
+               // Obtain the current position
                uint64_t position = mlt_producer_frame( parent );
 
                // Make sure we're at the same point
-               mlt_producer_seek_frame( producer, position );
+               mlt_producer_seek( producer, position );
 
                // Get the frame from the producer
                mlt_service_get_frame( mlt_producer_service( producer ), frame, 0 );
@@ -313,8 +317,8 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int ind
                // Generate a test frame
                *frame = mlt_frame_init( );
 
-               // Update timecode on the frame we're creating
-               mlt_frame_set_timecode( *frame, mlt_producer_position( parent ) );
+               // Update position on the frame we're creating
+               mlt_frame_set_position( *frame, mlt_producer_position( parent ) );
 
                // Move on to the next frame
                if ( index >= this->count )
index 83f34dd71cb8036ee9622a0a22c513f6779c17e9..3f6d8d9ad603285bed2b4f723189bfeaa71f6454 100644 (file)
@@ -31,7 +31,7 @@ extern mlt_producer mlt_multitrack_producer( mlt_multitrack this );
 extern mlt_service mlt_multitrack_service( mlt_multitrack this );
 extern mlt_properties mlt_multitrack_properties( mlt_multitrack this );
 extern int mlt_multitrack_connect( mlt_multitrack this, mlt_producer producer, int track );
-extern mlt_timecode mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index );
+extern mlt_position mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index );
 extern void mlt_multitrack_close( mlt_multitrack this );
 
 #endif
index 519585ce3b8e9664ae046546ffae26dad08967ac..921bbd5e44da3372997d8a286e997fca0b4ade62 100644 (file)
 typedef struct
 {
        mlt_producer producer;
-       int64_t frame_in;
-       int64_t frame_out;
-       int64_t frame_count;
-       mlt_timecode playtime;
+       mlt_position frame_in;
+       mlt_position frame_out;
+       mlt_position frame_count;
 }
 playlist_entry;
 
@@ -111,13 +110,16 @@ mlt_properties mlt_playlist_properties( mlt_playlist this )
        return mlt_producer_properties( &this->parent );
 }
 
+/** Refresh the playlist after a clip has been changed.
+*/
+
 static int mlt_playlist_virtual_refresh( mlt_playlist this )
 {
        int i = 0;
 
        // Get the fps of the first producer
        double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "first_fps" );
-       mlt_timecode playtime = 0;
+       mlt_position frame_count = 0;
 
        for ( i = 0; i < this->count; i ++ )
        {
@@ -139,15 +141,15 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
                        mlt_properties_set_double( mlt_producer_properties( producer ), "fps", fps );
                }
 
-               // Update the playtime for this clip
-               playtime += this->list[ i ]->playtime;
+               // Update the frame_count for this clip
+               frame_count += this->list[ i ]->frame_count;
        }
 
        // Refresh all properties
        mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", fps );
        mlt_properties_set_double( mlt_playlist_properties( this ), "fps", fps == 0 ? 25 : fps );
-       mlt_properties_set_timecode( mlt_playlist_properties( this ), "length", playtime );
-       mlt_properties_set_timecode( mlt_playlist_properties( this ), "out", playtime );
+       mlt_properties_set_position( mlt_playlist_properties( this ), "length", frame_count );
+       mlt_properties_set_position( mlt_playlist_properties( this ), "out", frame_count );
 
        return 0;
 }
@@ -155,11 +157,8 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
 /** Append to the virtual playlist.
 */
 
-static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, int64_t in, int64_t out )
+static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_position in, mlt_position out )
 {
-       double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "fps" );
-       double playtime = ( double )( out - in + 1 ) / fps;
-
        // Check that we have room
        if ( this->count >= this->size )
        {
@@ -175,7 +174,6 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer
        this->list[ this->count ]->frame_in = in;
        this->list[ this->count ]->frame_out = out;
        this->list[ this->count ]->frame_count = out - in + 1;
-       this->list[ this->count ]->playtime = playtime;
 
        mlt_producer_set_speed( producer, 0 );
 
@@ -193,21 +191,27 @@ static mlt_producer mlt_playlist_virtual_seek( mlt_playlist this )
        mlt_producer producer = NULL;
 
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode pos = mlt_producer_position( &this->parent );
-       int64_t position = mlt_producer_frame_position( &this->parent, pos );
+       mlt_position position = mlt_producer_frame( &this->parent );
+
+       // Total number of frames
        int64_t total = 0;
 
+       // Get the properties
        mlt_properties properties = mlt_playlist_properties( this );
+
+       // Get the eof handling
        char *eof = mlt_properties_get( properties, "eof" );
 
-       // Loop through the virtual playlist
+       // Index for the main loop
        int i = 0;
 
+       // Loop for each producer until found
        for ( i = 0; i < this->count; i ++ )
        {
                // Increment the total
                total += this->list[ i ]->frame_count;
 
+               // Check if the position indicates that we have found the clip
                if ( position < this->list[ i ]->frame_count )
                {
                        // Found it, now break
@@ -225,47 +229,43 @@ static mlt_producer mlt_playlist_virtual_seek( mlt_playlist this )
        if ( producer != NULL )
        {
                position += this->list[ i ]->frame_in;
-               position += mlt_producer_frame_position( producer, mlt_producer_get_in( producer ) );
-               mlt_producer_seek_frame( producer, position );
+               mlt_producer_seek( producer, position );
        }
        else if ( !strcmp( eof, "pause" ) && total > 0 )
        {
                playlist_entry *entry = this->list[ this->count - 1 ];
                mlt_producer this_producer = mlt_playlist_producer( this );
-               mlt_producer_seek_frame( this_producer, total - 1 );
+               mlt_producer_seek( this_producer, total - 1 - mlt_producer_get_in( this_producer ) );
                producer = entry->producer;
-               position = mlt_producer_frame_position( producer, mlt_producer_get_in( producer ) );
-               mlt_producer_seek_frame( producer, position + entry->frame_out );
+               mlt_producer_seek( producer, entry->frame_out );
                mlt_producer_set_speed( this_producer, 0 );
-               mlt_producer_set_speed( producer, 0 );
        }
        else if ( !strcmp( eof, "loop" ) && total > 0 )
        {
                playlist_entry *entry = this->list[ 0 ];
                mlt_producer this_producer = mlt_playlist_producer( this );
-               mlt_producer_seek_frame( this_producer, 0 );
+               mlt_producer_seek( this_producer, 0 );
                producer = entry->producer;
-               position = entry->frame_in;
-               position += mlt_producer_frame_position( producer, mlt_producer_get_in( producer ) );
-               mlt_producer_seek_frame( producer, position );
+               mlt_producer_seek( producer, entry->frame_in );
        }
        else
        {
-               mlt_producer_seek( mlt_playlist_producer( this ), 0 );
                producer = &this->blank;
        }
 
        return producer;
 }
 
+/** Invoked when a producer indicates that it has prematurely reached its end.
+*/
+
 static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
 {
        // Default producer to blank
        mlt_producer producer = &this->blank;
 
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode pos = mlt_producer_position( &this->parent );
-       int64_t position = mlt_producer_frame_position( &this->parent, pos );
+       mlt_position position = mlt_producer_frame( &this->parent );
 
        // Loop through the virtual playlist
        int i = 0;
@@ -288,9 +288,9 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
        // Seek in real producer to relative position
        if ( i < this->count )
        {
-               // Update the playtime for the changed clip (hmmm)
-               this->list[ i ]->frame_count = position + 1;
-               this->list[ i ]->frame_out = position - this->list[ i ]->frame_in;
+               // Update the frame_count for the changed clip (hmmm)
+               this->list[ i ]->frame_out = position;
+               this->list[ i ]->frame_count = this->list[ i ]->frame_out - this->list[ i ]->frame_in + 1;
 
                // Refresh the playlist
                mlt_playlist_virtual_refresh( this );
@@ -299,11 +299,13 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
        return producer;
 }
 
+/** Obtain the current clips index.
+*/
+
 int mlt_playlist_current_clip( mlt_playlist this )
 {
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode pos = mlt_producer_position( &this->parent );
-       int64_t position = mlt_producer_frame_position( &this->parent, pos );
+       mlt_position position = mlt_producer_frame( &this->parent );
 
        // Loop through the virtual playlist
        int i = 0;
@@ -325,6 +327,9 @@ int mlt_playlist_current_clip( mlt_playlist this )
        return i;
 }
 
+/** Obtain the current clips producer.
+*/
+
 mlt_producer mlt_playlist_current( mlt_playlist this )
 {
        int i = mlt_playlist_current_clip( this );
@@ -334,10 +339,10 @@ mlt_producer mlt_playlist_current( mlt_playlist this )
                return &this->blank;
 }
 
-/** Get the timecode which corresponds to the start of the next clip.
+/** Get the position which corresponds to the start of the next clip.
 */
 
-mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index )
+mlt_position mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index )
 {
        int64_t position = 0;
        int absolute_clip = index;
@@ -365,11 +370,11 @@ mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index
        else if ( absolute_clip > this->count )
                absolute_clip = this->count;
 
-       // Now determine the timecode
+       // Now determine the position
        for ( i = 0; i < absolute_clip; i ++ )
                position += this->list[ i ]->frame_count;
 
-       return mlt_producer_time( &this->parent, position );
+       return position;
 }
 
 int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index )
@@ -384,10 +389,8 @@ int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info,
                info->start = mlt_playlist_clip( this, mlt_whence_relative_start, index );
                info->resource = mlt_properties_get( properties, "resource" );
                info->frame_in = this->list[ index ]->frame_in;
-               info->in = mlt_producer_time( producer, info->frame_in );
                info->frame_out = this->list[ index ]->frame_out;
-               info->out = mlt_producer_time( producer, info->frame_out );
-               info->playtime = this->list[ index ]->playtime;
+               info->frame_count = this->list[ index ]->frame_count;
                info->length = mlt_producer_get_length( producer );
                info->fps = mlt_producer_get_fps( producer );
        }
@@ -418,43 +421,34 @@ int mlt_playlist_clear( mlt_playlist this )
 int mlt_playlist_append( mlt_playlist this, mlt_producer producer )
 {
        // Append to virtual list
-       int64_t in = mlt_producer_frame_position( producer, mlt_producer_get_in( producer ) );
-       int64_t out = mlt_producer_frame_position( producer, mlt_producer_get_out( producer ) );
-       return mlt_playlist_virtual_append( this, producer, 0, out - in );
+       return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) - 1 );
 }
 
 /** Append a producer to the playlist with in/out points.
 */
 
-int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in, double out )
+int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, mlt_position in, mlt_position out )
 {
        // Append to virtual list
        if ( in != -1 && out != -1 )
-       {
-               int64_t fin = mlt_producer_frame_position( producer, in );
-               int64_t fout = mlt_producer_frame_position( producer, out );
-               return mlt_playlist_virtual_append( this, producer, fin, fout );
-       }
+               return mlt_playlist_virtual_append( this, producer, in, out );
        else
-       {
                return mlt_playlist_append( this, producer );
-       }
 }
 
 /** Append a blank to the playlist of a given length.
 */
 
-int mlt_playlist_blank( mlt_playlist this, mlt_timecode length )
+int mlt_playlist_blank( mlt_playlist this, mlt_position length )
 {
        // Append to the virtual list
-       int64_t fout = mlt_producer_frame_position( &this->blank, length );
-       return mlt_playlist_virtual_append( this, &this->blank, 0, fout );
+       return mlt_playlist_virtual_append( this, &this->blank, 0, length );
 }
 
 /** Insert a producer into the playlist.
 */
 
-int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_timecode in, mlt_timecode out )
+int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_position in, mlt_position out )
 {
        return 0;
 }
@@ -469,7 +463,10 @@ int mlt_playlist_move( mlt_playlist this, int from, int to )
        return 0;
 }
 
-int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_timecode in, mlt_timecode out )
+/** Resize the current clip.
+*/
+
+int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_position in, mlt_position out )
 {
        int error = clip < 0 || clip >= this->count;
        if ( error == 0 )
@@ -479,23 +476,19 @@ int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_timecode in, mlt_
 
                if ( in <= -1 )
                        in = 0;
-               if ( out <= -1 || out >= mlt_producer_get_out( producer ) )
-                       out = mlt_producer_get_out( producer );
+               if ( out <= -1 || out >= mlt_producer_get_playtime( producer ) )
+                       out = mlt_producer_get_playtime( producer ) - 1;
 
                if ( out < in )
                {
-                       mlt_timecode t = in;
+                       mlt_position t = in;
                        in = out;
                        out = t;
                }
 
-               int64_t fin = mlt_producer_frame_position( producer, in );
-               int64_t fout = mlt_producer_frame_position( producer, out );
-
-               entry->frame_in = fin;
-               entry->frame_out = fout;
-               entry->frame_count = fout - fin + 1;
-               entry->playtime = out - in;
+               entry->frame_in = in;
+               entry->frame_out = out;
+               entry->frame_count = out - in + 1;
                mlt_playlist_virtual_refresh( this );
        }
        return error;
@@ -529,8 +522,8 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                notifier( argument );
        }
 
-       // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       // Update position on the frame we're creating
+       mlt_frame_set_position( *frame, mlt_producer_frame( producer ) );
 
        // Position ourselves on the next frame
        mlt_producer_prepare_next( producer );
index 8cdcccef8b38a3cd9be648340a3a33a626e50243..dd88959309acc80791bf8895f5b8776c80e4b8ac 100644 (file)
 typedef struct
 {
        mlt_producer producer;
-       mlt_timecode start;
+       mlt_position start;
        char *resource;
-       mlt_timecode in;
-       int64_t frame_in;
-       mlt_timecode out;
-       int64_t frame_out;
-       mlt_timecode playtime;
-       mlt_timecode length;
+       mlt_position frame_in;
+       mlt_position frame_out;
+       mlt_position frame_count;
+       mlt_position length;
        float fps;
 }
 mlt_playlist_clip_info;
@@ -51,16 +49,16 @@ extern mlt_properties mlt_playlist_properties( mlt_playlist this );
 extern int mlt_playlist_count( mlt_playlist this );
 extern int mlt_playlist_clear( mlt_playlist this );
 extern int mlt_playlist_append( mlt_playlist this, mlt_producer producer );
-extern int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in, double out );
-extern int mlt_playlist_blank( mlt_playlist this, mlt_timecode length );
-extern mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index );
+extern int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, mlt_position in, mlt_position out );
+extern int mlt_playlist_blank( mlt_playlist this, mlt_position length );
+extern mlt_position mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index );
 extern int mlt_playlist_current_clip( mlt_playlist this );
 extern mlt_producer mlt_playlist_current( mlt_playlist this );
 extern int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index );
-extern int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_timecode in, mlt_timecode out );
+extern int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_position in, mlt_position out );
 extern int mlt_playlist_remove( mlt_playlist this, int where );
 extern int mlt_playlist_move( mlt_playlist this, int from, int to );
-extern int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_timecode in, mlt_timecode out );
+extern int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_position in, mlt_position out );
 extern void mlt_playlist_close( mlt_playlist this );
 
 #endif
index 278d9026957b9455183024663a65c405bbfc11b3..c874243548cf7a529cdd95d40ae63accdcc521d4 100644 (file)
@@ -53,14 +53,13 @@ int mlt_producer_init( mlt_producer this, void *child )
 
                // Set the default properties
                mlt_properties_set( properties, "mlt_type", "mlt_producer" );
-               mlt_properties_set_timecode( properties, "position", 0.0 );
+               mlt_properties_set_position( properties, "position", 0.0 );
                mlt_properties_set_double( properties, "frame", 0 );
                mlt_properties_set_double( properties, "fps", 25.0 );
                mlt_properties_set_double( properties, "speed", 1.0 );
-               mlt_properties_set_timecode( properties, "in", 0.0 );
-               mlt_properties_set_timecode( properties, "out", 36000.0 );
-               mlt_properties_set_timecode( properties, "length", 36000.0 );
-               mlt_properties_set_int( properties, "known_length", 1 );
+               mlt_properties_set_position( properties, "in", 0.0 );
+               mlt_properties_set_position( properties, "out", 179999 );
+               mlt_properties_set_position( properties, "length", 180000 );
                mlt_properties_set_double( properties, "aspect_ratio", 4.0 / 3.0 );
                mlt_properties_set( properties, "log_id", "multitrack" );
 
@@ -87,92 +86,64 @@ mlt_properties mlt_producer_properties( mlt_producer this )
        return mlt_service_properties( &this->parent );
 }
 
-/** Convert frame position to timecode.
+/** Convert frame position to position.
 */
 
-mlt_timecode mlt_producer_time( mlt_producer this, int64_t frame )
+/*
+mlt_position mlt_producer_time( mlt_producer this, int64_t frame )
 {
        if ( frame < 0 )
                return -1;
        else
-               return ( mlt_timecode )frame / mlt_producer_get_fps( this );
+               return ( mlt_position )frame / mlt_producer_get_fps( this );
 }
+*/
 
-/** Convert timecode to frame position.
+/** Convert position to frame position.
 */
 
-int64_t mlt_producer_frame_position( mlt_producer this, mlt_timecode position )
+/*
+int64_t mlt_producer_frame_position( mlt_producer this, mlt_position position )
 {
        if ( position < 0 )
                return -1;
        else
                return ( int64_t )( floor( position * mlt_producer_get_fps( this ) + 0.5 ) );
 }
+*/
 
-/** Seek to a specified time code.
+/** Seek to a specified position.
 */
 
-int mlt_producer_seek( mlt_producer this, mlt_timecode timecode )
+int mlt_producer_seek( mlt_producer this, mlt_position position )
 {
        // Check bounds
-       if ( timecode < 0 )
-               timecode = 0;
-       if ( timecode > mlt_producer_get_playtime( this ) )
-               timecode = mlt_producer_get_playtime( this );
+       if ( position < 0 )
+               position = 0;
+       else if ( position > mlt_producer_get_playtime( this ) )
+               position = mlt_producer_get_playtime( this ) - 1;
 
        // Set the position
-       mlt_properties_set_timecode( mlt_producer_properties( this ), "position", timecode );
+       mlt_properties_set_position( mlt_producer_properties( this ), "position", position );
 
        // Calculate the absolute frame
-       double frame = ( mlt_producer_get_in( this ) + timecode ) * mlt_producer_get_fps( this );
-       mlt_properties_set_double( mlt_producer_properties( this ), "frame", floor( frame + 0.5 ) );
-
-       return 0;
-}
-
-/** Seek to a specified absolute frame.
-*/
-
-int mlt_producer_seek_frame( mlt_producer this, int64_t frame )
-{
-       // Calculate the time code
-       double timecode = ( frame / mlt_producer_get_fps( this ) ) - mlt_producer_get_in( this );
-
-       // If timecode is invalid, then seek on time
-       if ( frame < 0 || timecode < 0 )
-       {
-               // Seek to the in point
-               mlt_producer_seek( this, 0 );
-       }
-       else if ( timecode > mlt_producer_get_playtime( this ) )
-       {
-               // Seek to the out point
-               mlt_producer_seek( this, mlt_producer_get_playtime( this ) );
-       }
-       else
-       {
-               // Set the position
-               mlt_properties_set_timecode( mlt_producer_properties( this ), "position", timecode );
-
-               // Set the absolute frame
-               mlt_properties_set_double( mlt_producer_properties( this ), "frame", frame );
-       }
+       mlt_properties_set_position( mlt_producer_properties( this ), "frame", mlt_producer_get_in( this ) + position );
 
        return 0;
 }
 
-/** Get the current time code.
+/** Get the current position (relative to in point).
 */
 
-mlt_timecode mlt_producer_position( mlt_producer this )
+mlt_position mlt_producer_position( mlt_producer this )
 {
-       return mlt_properties_get_timecode( mlt_producer_properties( this ), "position" );
+       return mlt_properties_get_position( mlt_producer_properties( this ), "position" );
 }
 
-/** Get the current frame.
+/** Get the current position (relative to start of producer).
 */
 
-uint64_t mlt_producer_frame( mlt_producer this )
+mlt_position mlt_producer_frame( mlt_producer this )
 {
        return mlt_properties_get_double( mlt_producer_properties( this ), "frame" );
 }
@@ -204,32 +175,30 @@ double mlt_producer_get_fps( mlt_producer this )
 /** Set the in and out points.
 */
 
-int mlt_producer_set_in_and_out( mlt_producer this, mlt_timecode in, mlt_timecode out )
+int mlt_producer_set_in_and_out( mlt_producer this, mlt_position in, mlt_position out )
 {
        // Correct ins and outs if necessary
        if ( in < 0 )
                in = 0;
-       if ( in > mlt_producer_get_length( this ) )
+       else if ( in > mlt_producer_get_length( this ) )
                in = mlt_producer_get_length( this );
+
        if ( out < 0 )
                out = 0;
-       if ( out > mlt_producer_get_length( this ) )
+       else if ( out > mlt_producer_get_length( this ) )
                out = mlt_producer_get_length( this );
 
        // Swap ins and outs if wrong
        if ( out < in )
        {
-               mlt_timecode t = in;
+               mlt_position t = in;
                in = out;
                out = t;
        }
 
        // Set the values
-       mlt_properties_set_timecode( mlt_producer_properties( this ), "in", in );
-       mlt_properties_set_timecode( mlt_producer_properties( this ), "out", out );
-
-       // Seek to the in point
-       mlt_producer_seek( this, 0 );
+       mlt_properties_set_position( mlt_producer_properties( this ), "in", in );
+       mlt_properties_set_position( mlt_producer_properties( this ), "out", out );
 
        return 0;
 }
@@ -237,33 +206,33 @@ int mlt_producer_set_in_and_out( mlt_producer this, mlt_timecode in, mlt_timecod
 /** Get the in point.
 */
 
-mlt_timecode mlt_producer_get_in( mlt_producer this )
+mlt_position mlt_producer_get_in( mlt_producer this )
 {
-       return mlt_properties_get_timecode( mlt_producer_properties( this ), "in" );
+       return mlt_properties_get_position( mlt_producer_properties( this ), "in" );
 }
 
 /** Get the out point.
 */
 
-mlt_timecode mlt_producer_get_out( mlt_producer this )
+mlt_position mlt_producer_get_out( mlt_producer this )
 {
-       return mlt_properties_get_timecode( mlt_producer_properties( this ), "out" );
+       return mlt_properties_get_position( mlt_producer_properties( this ), "out" );
 }
 
 /** Get the total play time.
 */
 
-mlt_timecode mlt_producer_get_playtime( mlt_producer this )
+mlt_position mlt_producer_get_playtime( mlt_producer this )
 {
-       return mlt_producer_get_out( this ) - mlt_producer_get_in( this );
+       return mlt_producer_get_out( this ) - mlt_producer_get_in( this ) + 1;
 }
 
 /** Get the total length of the producer.
 */
 
-mlt_timecode mlt_producer_get_length( mlt_producer this )
+mlt_position mlt_producer_get_length( mlt_producer this )
 {
-       return mlt_properties_get_timecode( mlt_producer_properties( this ), "length" );
+       return mlt_properties_get_position( mlt_producer_properties( this ), "length" );
 }
 
 /** Prepare for next frame.
@@ -271,7 +240,7 @@ mlt_timecode mlt_producer_get_length( mlt_producer this )
 
 void mlt_producer_prepare_next( mlt_producer this )
 {
-       mlt_producer_seek_frame( this, mlt_producer_frame( this ) + mlt_producer_get_speed( this ) );
+       mlt_producer_seek( this, mlt_producer_frame( this ) + mlt_producer_get_speed( this ) );
 }
 
 /** Get a frame.
@@ -287,26 +256,24 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind
        {
                // Get the frame from the implementation
                result = this->get_frame( this, frame, index );
-
-               mlt_properties frame_properties = mlt_frame_properties( *frame );
-               double speed = mlt_producer_get_speed( this );
-               mlt_properties_set_double( frame_properties, "speed", speed );
        }
        else
        {
                // Generate a test frame
                *frame = mlt_frame_init( );
 
-               // Set the timecode
-               result = mlt_frame_set_timecode( *frame, mlt_producer_position( this ) );
+               // Set the position
+               result = mlt_frame_set_position( *frame, mlt_producer_position( this ) );
 
-               // Calculate the next timecode
+               // Calculate the next position
                mlt_producer_prepare_next( this );
        }
 
-       // Copy the fps of the producer onto the frame
+       // Copy the fps and speed of the producer onto the frame
        mlt_properties properties = mlt_frame_properties( *frame );
        mlt_properties_set_double( properties, "fps", mlt_producer_get_fps( this ) );
+       double speed = mlt_producer_get_speed( this );
+       mlt_properties_set_double( properties, "speed", speed );
 
        return 0;
 }
index 52976524f8fb5e5d840f9c6c7d9ac8a027ff8a69..7e748c0f7b69e0b0c8b18ec042fab2c782ebc279 100644 (file)
@@ -43,23 +43,23 @@ struct mlt_producer_s
 /** Public final methods
 */
 
+//extern double mlt_producer_convert_position_to_time( mlt_producer this, int64_t frame );
+//extern mlt_position mlt_producer_convert_time_to_position( mlt_producer this, double time );
+
 extern int mlt_producer_init( mlt_producer this, void *child );
 extern mlt_service mlt_producer_service( mlt_producer this );
 extern mlt_properties mlt_producer_properties( mlt_producer this );
-extern mlt_timecode mlt_producer_time( mlt_producer this, int64_t frame );
-extern int64_t mlt_producer_frame_position( mlt_producer this, mlt_timecode position );
-extern int mlt_producer_seek( mlt_producer this, mlt_timecode timecode );
-extern int mlt_producer_seek_frame( mlt_producer this, int64_t frame );
-extern mlt_timecode mlt_producer_position( mlt_producer this );
-extern uint64_t mlt_producer_frame( mlt_producer this );
+extern int mlt_producer_seek( mlt_producer this, mlt_position position );
+extern mlt_position mlt_producer_position( mlt_producer this );
+extern mlt_position mlt_producer_frame( mlt_producer this );
 extern int mlt_producer_set_speed( mlt_producer this, double speed );
 extern double mlt_producer_get_speed( mlt_producer this );
 extern double mlt_producer_get_fps( mlt_producer this );
-extern int mlt_producer_set_in_and_out( mlt_producer this, mlt_timecode in, mlt_timecode out );
-extern mlt_timecode mlt_producer_get_in( mlt_producer this );
-extern mlt_timecode mlt_producer_get_out( mlt_producer this );
-extern mlt_timecode mlt_producer_get_playtime( mlt_producer this );
-extern mlt_timecode mlt_producer_get_length( mlt_producer this );
+extern int mlt_producer_set_in_and_out( mlt_producer this, mlt_position in, mlt_position out );
+extern mlt_position mlt_producer_get_in( mlt_producer this );
+extern mlt_position mlt_producer_get_out( mlt_producer this );
+extern mlt_position mlt_producer_get_playtime( mlt_producer this );
+extern mlt_position mlt_producer_get_length( mlt_producer this );
 extern void mlt_producer_prepare_next( mlt_producer this );
 extern void mlt_producer_close( mlt_producer this );
 
index 679d97ad06f701ad8471478f01891b9ca581bd9f..d047da0c2ae503d23fd2c32d64695ca5e3e6717b 100644 (file)
@@ -285,16 +285,16 @@ int mlt_properties_set_double( mlt_properties this, char *name, double value )
 /** Get a value associated to the name.
 */
 
-mlt_timecode mlt_properties_get_timecode( mlt_properties this, char *name )
+mlt_position mlt_properties_get_position( mlt_properties this, char *name )
 {
        mlt_property value = mlt_properties_find( this, name );
-       return value == NULL ? 0 : mlt_property_get_timecode( value );
+       return value == NULL ? 0 : mlt_property_get_position( value );
 }
 
 /** Set a value associated to the name.
 */
 
-int mlt_properties_set_timecode( mlt_properties this, char *name, mlt_timecode value )
+int mlt_properties_set_position( mlt_properties this, char *name, mlt_position value )
 {
        int error = 1;
 
@@ -303,7 +303,7 @@ int mlt_properties_set_timecode( mlt_properties this, char *name, mlt_timecode v
 
        // Set it if not NULL
        if ( property != NULL )
-               error = mlt_property_set_timecode( property, value );
+               error = mlt_property_set_position( property, value );
 
        return error;
 }
index 540b7aec540a500486921e1905c18b1926367219..2cacc9f8d5bf07538c5fae040e3a013b9c85e470 100644 (file)
@@ -48,8 +48,8 @@ extern int mlt_properties_get_int( mlt_properties this, char *name );
 extern int mlt_properties_set_int( mlt_properties this, char *name, int value );
 extern double mlt_properties_get_double( mlt_properties this, char *name );
 extern int mlt_properties_set_double( mlt_properties this, char *name, double value );
-extern mlt_timecode mlt_properties_get_timecode( mlt_properties this, char *name );
-extern int mlt_properties_set_timecode( mlt_properties this, char *name, mlt_timecode value );
+extern mlt_position mlt_properties_get_position( mlt_properties this, char *name );
+extern int mlt_properties_set_position( mlt_properties this, char *name, mlt_position value );
 extern int mlt_properties_set_data( mlt_properties this, char *name, void *value, int length, mlt_destructor, mlt_serialiser );
 extern void *mlt_properties_get_data( mlt_properties this, char *name, int *length );
 extern int mlt_properties_count( mlt_properties this );
index f471b180eda698132dbf073300d63ed2597991e9..0a475299d34855770d8a8fdb32eac6fd127a5dba 100644 (file)
@@ -73,14 +73,14 @@ int mlt_property_set_double( mlt_property this, double value )
        return 0;
 }
 
-/** Set a timecode on this property.
+/** Set a position on this property.
 */
 
-int mlt_property_set_timecode( mlt_property this, mlt_timecode value )
+int mlt_property_set_position( mlt_property this, mlt_position value )
 {
        mlt_property_clear( this );
-       this->types = mlt_prop_timecode;
-       this->prop_timecode = value;
+       this->types = mlt_prop_position;
+       this->prop_position = value;
        return 0;
 }
 
@@ -132,8 +132,8 @@ int mlt_property_get_int( mlt_property this )
                return this->prop_int;
        else if ( this->types & mlt_prop_double )
                return ( int )this->prop_double;
-       else if ( this->types & mlt_prop_timecode )
-               return ( int )this->prop_timecode;
+       else if ( this->types & mlt_prop_position )
+               return ( int )this->prop_position;
        else if ( this->types & mlt_prop_int64 )
                return ( int )this->prop_int64;
        else if ( this->types & mlt_prop_string )
@@ -150,8 +150,8 @@ double mlt_property_get_double( mlt_property this )
                return this->prop_double;
        else if ( this->types & mlt_prop_int )
                return ( double )this->prop_int;
-       else if ( this->types & mlt_prop_timecode )
-               return ( double )this->prop_timecode;
+       else if ( this->types & mlt_prop_position )
+               return ( double )this->prop_position;
        else if ( this->types & mlt_prop_int64 )
                return ( double )this->prop_int64;
        else if ( this->types & mlt_prop_string )
@@ -159,21 +159,21 @@ double mlt_property_get_double( mlt_property this )
        return 0;
 }
 
-/** Get a timecode from this property.
+/** Get a position from this property.
 */
 
-mlt_timecode mlt_property_get_timecode( mlt_property this )
+mlt_position mlt_property_get_position( mlt_property this )
 {
-       if ( this->types & mlt_prop_timecode )
-               return this->prop_timecode;
+       if ( this->types & mlt_prop_position )
+               return this->prop_position;
        else if ( this->types & mlt_prop_int )
-               return ( mlt_timecode )this->prop_int;
+               return ( mlt_position )this->prop_int;
        else if ( this->types & mlt_prop_double )
-               return ( mlt_timecode )this->prop_double;
+               return ( mlt_position )this->prop_double;
        else if ( this->types & mlt_prop_int64 )
-               return ( mlt_timecode )this->prop_int64;
+               return ( mlt_position )this->prop_int64;
        else if ( this->types & mlt_prop_string )
-               return ( mlt_timecode )atof( this->prop_string );
+               return ( mlt_position )atol( this->prop_string );
        return 0;
 }
 
@@ -188,10 +188,10 @@ int64_t mlt_property_get_int64( mlt_property this )
                return ( int64_t )this->prop_int;
        else if ( this->types & mlt_prop_double )
                return ( int64_t )this->prop_double;
-       else if ( this->types & mlt_prop_timecode )
-               return ( int64_t )this->prop_timecode;
+       else if ( this->types & mlt_prop_position )
+               return ( int64_t )this->prop_position;
        else if ( this->types & mlt_prop_string )
-               return ( int64_t )atof( this->prop_string );
+               return ( int64_t )atol( this->prop_string );
        return 0;
 }
 
@@ -215,11 +215,11 @@ char *mlt_property_get_string( mlt_property this )
                        this->prop_string = malloc( 32 );
                        sprintf( this->prop_string, "%e", this->prop_double );
                }
-               else if ( this->types & mlt_prop_timecode )
+               else if ( this->types & mlt_prop_position )
                {
                        this->types |= mlt_prop_string;
                        this->prop_string = malloc( 32 );
-                       sprintf( this->prop_string, "%e", this->prop_timecode );
+                       sprintf( this->prop_string, "%lld", this->prop_position );
                }
                else if ( this->types & mlt_prop_int64 )
                {
index 6b0def55d781c7dbf0d50342843a05c1a328aa3c..3f59ad27e630c68b032e73bfd226545f79c9100e 100644 (file)
@@ -31,7 +31,7 @@ typedef enum
        mlt_prop_none = 0,
        mlt_prop_int = 1,
        mlt_prop_string = 2,
-       mlt_prop_timecode = 4,
+       mlt_prop_position = 4,
        mlt_prop_double = 8,
        mlt_prop_data = 16,
        mlt_prop_int64 = 32
@@ -48,7 +48,7 @@ typedef struct mlt_property_s
 
        // Atomic type handling
        int prop_int;
-       mlt_timecode prop_timecode;
+       mlt_position prop_position;
        double prop_double;
        int64_t prop_int64;
 
@@ -70,13 +70,13 @@ extern mlt_property mlt_property_init( );
 extern void mlt_property_clear( mlt_property this );
 extern int mlt_property_set_int( mlt_property this, int value );
 extern int mlt_property_set_double( mlt_property this, double value );
-extern int mlt_property_set_timecode( mlt_property this, mlt_timecode value );
+extern int mlt_property_set_position( mlt_property this, mlt_position value );
 extern int mlt_property_set_uint64( mlt_property this, uint64_t value );
 extern int mlt_property_set_string( mlt_property this, char *value );
 extern int mlt_property_set_data( mlt_property this, void *value, int length, mlt_destructor destructor, mlt_serialiser serialiser );
 extern int mlt_property_get_int( mlt_property this );
 extern double mlt_property_get_double( mlt_property this );
-extern mlt_timecode mlt_property_get_timecode( mlt_property this );
+extern mlt_position mlt_property_get_position( mlt_property this );
 extern int64_t mlt_property_get_int64( mlt_property this );
 extern char *mlt_property_get_string( mlt_property this );
 extern void *mlt_property_get_data( mlt_property this, int *length );
index f4b77c460c98a4e85c88859b896fe992478a9e47..6c02230f2548e5a9d4cf79ae141f3086ba0b112e 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "mlt_tractor.h"
 #include "mlt_frame.h"
+#include "mlt_multitrack.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 
 struct mlt_tractor_s
 {
-       struct mlt_service_s parent;
+       struct mlt_producer_s parent;
        mlt_service producer;
 };
 
 /** Forward references to static methods.
 */
 
-static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int track );
+static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int track );
 
 /** Constructor for the tractor.
 
@@ -50,10 +51,10 @@ mlt_tractor mlt_tractor_init( )
        mlt_tractor this = calloc( sizeof( struct mlt_tractor_s ), 1 );
        if ( this != NULL )
        {
-               mlt_service service = &this->parent;
-               if ( mlt_service_init( service, this ) == 0 )
+               mlt_producer producer = &this->parent;
+               if ( mlt_producer_init( producer, this ) == 0 )
                {
-                       service->get_frame = service_get_frame;
+                       producer->get_frame = producer_get_frame;
                }
                else
                {
@@ -68,22 +69,36 @@ mlt_tractor mlt_tractor_init( )
 */
 
 mlt_service mlt_tractor_service( mlt_tractor this )
+{
+       return mlt_producer_service( &this->parent );
+}
+
+/** Get the producer object associated to the tractor.
+*/
+
+mlt_producer mlt_tractor_producer( mlt_tractor this )
 {
        return &this->parent;
 }
 
+/** Get the properties object associated to the tractor.
+*/
+
+mlt_properties mlt_tractor_properties( mlt_tractor this )
+{
+       return mlt_producer_properties( &this->parent );
+}
+
 /** Connect the tractor.
 */
 
 int mlt_tractor_connect( mlt_tractor this, mlt_service producer )
 {
-       int ret = mlt_service_connect_producer( &this->parent, producer, 0 );
+       int ret = mlt_service_connect_producer( mlt_tractor_service( this ), producer, 0 );
 
+       // This is the producer we're going to connect to
        if ( ret == 0 )
-       {
-               // This is the producer we're going to connect to
                this->producer = producer;
-       }
 
        return ret;
 }
@@ -93,7 +108,7 @@ int mlt_tractor_connect( mlt_tractor this, mlt_service producer )
        TODO: This should be reading a pump being populated by the thread...
 */
 
-static int service_get_frame( mlt_service parent, mlt_frame_ptr frame, int track )
+static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int track )
 {
        mlt_tractor this = parent->child;
 
@@ -105,6 +120,25 @@ static int service_get_frame( mlt_service parent, mlt_frame_ptr frame, int track
                int done = 0;
                mlt_frame temp;
 
+               // Get the properties of the parent producer
+               mlt_properties properties = mlt_producer_properties( parent );
+
+               // Try to obtain the multitrack associated to the tractor
+               mlt_multitrack multitrack = mlt_properties_get_data( properties, "multitrack", NULL );
+
+               // If we don't have one, we're in trouble... 
+               if ( multitrack != NULL )
+               {
+                       mlt_producer target = mlt_multitrack_producer( multitrack );
+                       mlt_producer_seek( target, mlt_producer_frame( parent ) );
+                       mlt_producer_set_speed( target, mlt_producer_get_speed( parent ) );
+                       mlt_producer_set_in_and_out( parent, mlt_producer_get_in( target ), mlt_producer_get_out( target ) );
+               }
+               else
+               {
+                       fprintf( stderr, "tractor without a multitrack!!\n" );
+               }
+
                // Loop through each of the tracks we're harvesting
                for ( i = 0; !done; i ++ )
                {
@@ -133,6 +167,9 @@ static int service_get_frame( mlt_service parent, mlt_frame_ptr frame, int track
                        }
                }
 
+               // Prepare the next frame
+               mlt_producer_prepare_next( parent );
+
                // Indicate our found status
                return 0;
        }
@@ -149,7 +186,7 @@ static int service_get_frame( mlt_service parent, mlt_frame_ptr frame, int track
 
 void mlt_tractor_close( mlt_tractor this )
 {
-       mlt_service_close( &this->parent );
+       mlt_producer_close( &this->parent );
        free( this );
 }
 
index 28a6071b786ea9699ead97cfc7c770620d096932..b6576ecc523179cc85b417f0c559f66530518f74 100644 (file)
@@ -25,6 +25,8 @@
 
 extern mlt_tractor mlt_tractor_init( );
 extern mlt_service mlt_tractor_service( mlt_tractor this );
+extern mlt_producer mlt_tractor_producer( mlt_tractor this );
+extern mlt_properties mlt_tractor_properties( mlt_tractor this );
 extern int mlt_tractor_connect( mlt_tractor this, mlt_service service );
 extern void mlt_tractor_close( mlt_tractor this );
 
index de416a8177b9cc67d4aff8bbf521b47da7a69825..50715501dea486ca2cf0072dedcd33d18bf82bfb 100644 (file)
@@ -46,8 +46,8 @@ int mlt_transition_init( mlt_transition this, void *child )
 
                service->get_frame = transition_get_frame;
 
-               mlt_properties_set_timecode( properties, "in", 0 );
-               mlt_properties_set_timecode( properties, "out", 0 );
+               mlt_properties_set_position( properties, "in", 0 );
+               mlt_properties_set_position( properties, "out", 0 );
                mlt_properties_set_int( properties, "a_track", 0 );
                mlt_properties_set_int( properties, "b_track", 1 );
 
@@ -91,11 +91,11 @@ int mlt_transition_connect( mlt_transition this, mlt_service producer, int a_tra
 /** Set the in and out points.
 */
 
-void mlt_transition_set_in_and_out( mlt_transition this, mlt_timecode in, mlt_timecode out )
+void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_position out )
 {
        mlt_properties properties = mlt_transition_properties( this );
-       mlt_properties_set_timecode( properties, "in", in );
-       mlt_properties_set_timecode( properties, "out", out );
+       mlt_properties_set_position( properties, "in", in );
+       mlt_properties_set_position( properties, "out", out );
 }
 
 /** Get the index of the a track.
@@ -119,19 +119,19 @@ int mlt_transition_get_b_track( mlt_transition this )
 /** Get the in point.
 */
 
-mlt_timecode mlt_transition_get_in( mlt_transition this )
+mlt_position mlt_transition_get_in( mlt_transition this )
 {
        mlt_properties properties = mlt_transition_properties( this );
-       return mlt_properties_get_timecode( properties, "in" );
+       return mlt_properties_get_position( properties, "in" );
 }
 
 /** Get the out point.
 */
 
-mlt_timecode mlt_transition_get_out( mlt_transition this )
+mlt_position mlt_transition_get_out( mlt_transition this )
 {
        mlt_properties properties = mlt_transition_properties( this );
-       return mlt_properties_get_timecode( properties, "out" );
+       return mlt_properties_get_position( properties, "out" );
 }
 
 /** Process the frame.
@@ -183,8 +183,8 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i
 
        int a_track = mlt_properties_get_int( properties, "a_track" );
        int b_track = mlt_properties_get_int( properties, "b_track" );
-       mlt_timecode in = mlt_properties_get_timecode( properties, "in" );
-       mlt_timecode out = mlt_properties_get_timecode( properties, "out" );
+       mlt_position in = mlt_properties_get_position( properties, "in" );
+       mlt_position out = mlt_properties_get_position( properties, "out" );
 
        // Fetch a and b frames together...
        if ( ( index == a_track || index == b_track ) &&
@@ -198,8 +198,8 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i
        if ( index == a_track )
        {
                // Determine if we're in the right time zone
-               mlt_timecode timecode = mlt_frame_get_timecode( this->a_frame );
-               if ( timecode >= in && timecode < out )
+               mlt_position position = mlt_frame_get_position( this->a_frame );
+               if ( position >= in && position < out )
                {
                        // Process the transition
                        *frame = transition_process( this, this->a_frame, this->b_frame );
@@ -225,8 +225,8 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i
                }
                else
                {
-                       mlt_timecode timecode = mlt_frame_get_timecode( this->b_frame );
-                       if ( timecode >= in && timecode < out )
+                       mlt_position position = mlt_frame_get_position( this->b_frame );
+                       if ( position >= in && position < out )
                        {
                                // We're in the zone, but the 'a frame' has not been requested yet
                                *frame = mlt_frame_init( );
index 7ac765c33a721580f000e615a1c4d8e4e04f3205..c297bdbcdbbd1ab7888bda34cdcad860a4030e79 100644 (file)
@@ -55,11 +55,11 @@ extern int mlt_transition_init( mlt_transition this, void *child );
 extern mlt_service mlt_transition_service( mlt_transition this );
 extern mlt_properties mlt_transition_properties( mlt_transition this );
 extern int mlt_transition_connect( mlt_transition this, mlt_service producer, int a_track, int b_track );
-extern void mlt_transition_set_in_and_out( mlt_transition this, mlt_timecode in, mlt_timecode out );
+extern void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_position out );
 extern int mlt_transition_get_a_track( mlt_transition this );
 extern int mlt_transition_get_b_track( mlt_transition this );
-extern mlt_timecode mlt_transition_get_in( mlt_transition this );
-extern mlt_timecode mlt_transition_get_out( mlt_transition this );
+extern mlt_position mlt_transition_get_in( mlt_transition this );
+extern mlt_position mlt_transition_get_out( mlt_transition this );
 extern void mlt_transition_close( mlt_transition this );
 
 #endif
index b100f18f40fd289cee13d533a055eb35c229fc06..162602f6f1f8ebb8ed68f352deee2435bb2d7161 100644 (file)
@@ -31,7 +31,7 @@ typedef enum
 }
 mlt_whence;
 
-typedef double mlt_timecode;
+typedef int64_t mlt_position;
 typedef struct mlt_frame_s *mlt_frame, **mlt_frame_ptr;
 typedef struct mlt_properties_s *mlt_properties;
 typedef struct mlt_service_s *mlt_service;
index 2dbda0e64850ac2f9021ea2a5ac49d4232d41cc1..fa76e647b44998af6a68177e105c41aa836d7485 100644 (file)
@@ -50,43 +50,57 @@ static void transport_action( mlt_producer producer, char *value )
                        case '9':
                                mlt_producer_set_speed( producer, 10 );
                                break;
+                       case 'd':
+                               if ( multitrack != NULL )
+                               {
+                                       int i = 0;
+                                       mlt_position last = -1;
+                                       for ( i = 0; 1; i ++ )
+                                       {
+                                               mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_start, i );
+                                               if ( time == last )
+                                                       break;
+                                               last = time;
+                                               fprintf( stderr, "%d: %lld\n", i, time );
+                                       }
+                               }
+                               break;
+
                        case 'g':
                                if ( multitrack != NULL )
                                {
-                                       mlt_timecode time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 0 );
+                                       mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 0 );
                                        mlt_producer_seek( producer, time );
                                }
                                break;
                        case 'h':
                                if ( multitrack != NULL )
                                {
-                                       mlt_producer producer = mlt_multitrack_producer( multitrack );
-                                       int64_t position = mlt_producer_frame_position( producer, mlt_producer_position( producer ) );
+                                       mlt_position position = mlt_producer_position( producer );
                                        mlt_producer_set_speed( producer, 0 );
-                                       mlt_producer_seek_frame( producer, position - 1 >= 0 ? position - 1 : 0 );
+                                       mlt_producer_seek( producer, position - 1 >= 0 ? position - 1 : 0 );
                                }
                                break;
                        case 'j':
                                if ( multitrack != NULL )
                                {
-                                       mlt_timecode time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 1 );
+                                       mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 1 );
                                        mlt_producer_seek( producer, time );
                                }
                                break;
                        case 'k':
                                if ( multitrack != NULL )
                                {
-                                       mlt_timecode time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, -1 );
+                                       mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, -1 );
                                        mlt_producer_seek( producer, time );
                                }
                                break;
                        case 'l':
                                if ( multitrack != NULL )
                                {
-                                       mlt_producer producer = mlt_multitrack_producer( multitrack );
-                                       int64_t position = mlt_producer_frame_position( producer, mlt_producer_position( producer ) );
+                                       mlt_position position = mlt_producer_position( producer );
                                        mlt_producer_set_speed( producer, 0 );
-                                       mlt_producer_seek_frame( producer, position + 1 );
+                                       mlt_producer_seek( producer, position + 1 );
                                }
                                break;
                }
index 479ed71355c077ba7c46569683fa1ccc9745c7cd..a1043df4ee1f20888eb0461e94d71a03139cdcc6 100644 (file)
@@ -218,7 +218,6 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response )
        mlt_properties properties = unit->properties;
        int generation = mlt_properties_get_int( properties, "generation" );
        mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
-       mlt_producer producer = mlt_playlist_producer( playlist );
 
        valerie_response_printf( response, 1024, "%d\n", generation );
                
@@ -230,8 +229,8 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response )
                                                                 i, info.resource, 
                                                                 info.frame_in, 
                                                                 info.frame_out,
-                                                                mlt_producer_frame_position( producer, info.playtime )
-                                                                mlt_producer_frame_position( producer, info.length )
+                                                                info.frame_count
+                                                                info.length
                                                                 info.fps );
        }
 }
@@ -257,7 +256,7 @@ valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, int64_t in,
        {
                mlt_properties properties = unit->properties;
                mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
-               mlt_playlist_append_io( playlist, instance, mlt_producer_time( instance, in ), mlt_producer_time( instance, out ) );
+               mlt_playlist_append_io( playlist, instance, in, out );
                miracle_log( LOG_DEBUG, "loaded clip %s", clip );
                miracle_unit_status_communicate( unit );
                return valerie_ok;
@@ -274,7 +273,7 @@ valerie_error_code miracle_unit_insert( miracle_unit unit, char *clip, int index
        {
                mlt_properties properties = unit->properties;
                mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
-               mlt_playlist_insert( playlist, instance, index, mlt_producer_time( instance, in ), mlt_producer_time( instance, out ) );
+               mlt_playlist_insert( playlist, instance, index, in, out );
                miracle_log( LOG_DEBUG, "inserted clip %s at %d", clip, index );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
@@ -330,7 +329,7 @@ valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, int64_t i
        {
                mlt_properties properties = unit->properties;
                mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
-               mlt_playlist_append_io( playlist, instance, mlt_producer_time( instance, in ), mlt_producer_time( instance, out ) );
+               mlt_playlist_append_io( playlist, instance, in, out );
                miracle_log( LOG_DEBUG, "appended clip %s", clip );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
@@ -424,13 +423,13 @@ int miracle_unit_get_status( miracle_unit unit, valerie_status status )
                        status->fps = mlt_producer_get_fps( producer );
                        status->in = info.frame_in;
                        status->out = info.frame_out;
-                       status->position = mlt_producer_frame_position( producer, mlt_producer_position( clip ) );
-                       status->length = mlt_producer_frame_position( producer, mlt_producer_get_length( clip ) );
+                       status->position = mlt_producer_position( clip );
+                       status->length = mlt_producer_get_length( clip );
                        strncpy( status->tail_clip, info.resource, sizeof( status->tail_clip ) );
                        status->tail_in = info.frame_in;
                        status->tail_out = info.frame_out;
-                       status->tail_position = mlt_producer_frame_position( producer, mlt_producer_position( clip ) );
-                       status->tail_length = mlt_producer_frame_position( producer, mlt_producer_get_length( clip ) );
+                       status->tail_position = mlt_producer_position( clip );
+                       status->tail_length = mlt_producer_get_length( clip );
                        status->clip_index = mlt_playlist_current_clip( playlist );
                        status->seek_flag = 1;
                }
@@ -477,7 +476,7 @@ void miracle_unit_change_position( miracle_unit unit, int clip, int64_t position
 
        if ( mlt_playlist_get_clip_info( playlist, &info, clip ) == 0 )
        {
-               int64_t frame_start = mlt_producer_frame_position( info.producer, info.start );
+               int64_t frame_start = info.start;
                int64_t frame_offset = position;
 
                if ( frame_offset < 0 )
@@ -487,7 +486,7 @@ void miracle_unit_change_position( miracle_unit unit, int clip, int64_t position
                if ( frame_offset >= info.frame_out )
                        frame_offset = info.frame_out;
                
-               mlt_producer_seek_frame( producer, frame_start + frame_offset - info.frame_in );
+               mlt_producer_seek( producer, frame_start + frame_offset - info.frame_in );
        }
 
        miracle_unit_status_communicate( unit );
@@ -516,8 +515,8 @@ int miracle_unit_set_clip_in( miracle_unit unit, int index, int64_t position )
 
        if ( error == 0 )
        {
-               mlt_timecode in = mlt_producer_time( info.producer, position );
-               error = mlt_playlist_resize_clip( playlist, index, in, info.out );
+               miracle_unit_play( unit, 0 );
+               error = mlt_playlist_resize_clip( playlist, index, position, info.frame_out );
                update_generation( unit );
                miracle_unit_change_position( unit, index, 0 );
        }
@@ -537,8 +536,8 @@ int miracle_unit_set_clip_out( miracle_unit unit, int index, int64_t position )
 
        if ( error == 0 )
        {
-               mlt_timecode out = mlt_producer_time( info.producer, position );
-               error = mlt_playlist_resize_clip( playlist, index, info.in, out );
+               miracle_unit_play( unit, 0 );
+               error = mlt_playlist_resize_clip( playlist, index, info.frame_in, position );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
                miracle_unit_change_position( unit, index, -1 );
@@ -555,8 +554,8 @@ void miracle_unit_step( miracle_unit unit, int64_t offset )
        mlt_properties properties = unit->properties;
        mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
        mlt_producer producer = mlt_playlist_producer( playlist );
-       mlt_timecode position = mlt_producer_position( producer );
-       mlt_producer_seek_frame( producer, mlt_producer_frame_position( producer, position ) + offset );
+       mlt_position position = mlt_producer_frame( producer );
+       mlt_producer_seek( producer, position + offset );
 }
 
 /** Set the unit's clip mode regarding in and out points.
index b508654bc09af3b29979562020bf87b51704c684..c929d2572e7dc7de4dcb512297bfcb712755a68a 100644 (file)
@@ -249,7 +249,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        ( *frame )->get_audio = producer_get_audio;
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
        // Calculate the next timecode
        mlt_producer_prepare_next( producer );
index 7bcdfa9fbcdd80a3126c63d72ec58a5393bb28b5..c2ba62dd862a08e761f2c8dca7b00622eb219066 100644 (file)
@@ -44,32 +44,42 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form
        // Get the b frame from the stack
        mlt_frame b_frame = mlt_frame_pop_frame( this );
 
-       // Get the properties of the b frame
-       mlt_properties b_props = mlt_frame_properties( b_frame );
-
-       // Arbitrary composite defaults
-       int x = 0;
-       int y = 0;
-       double mix = 1.0;
-
-       // Override from b frame properties if provided
-       if ( mlt_properties_get( b_props, "x" ) != NULL )
-               x = mlt_properties_get_int( b_props, "x" );
-       if ( mlt_properties_get( b_props, "y" ) != NULL )
-               y = mlt_properties_get_int( b_props, "y" );
-       if ( mlt_properties_get( b_props, "mix" ) != NULL )
-               mix = mlt_properties_get_double( b_props, "mix" );
-
-       // Composite the b_frame on the a_frame
-       mlt_frame_composite_yuv( this, b_frame, x, y, mix );
-
-       // Extract the a_frame image info
-       *width = mlt_properties_get_int( a_props, "width" );
-       *height = mlt_properties_get_int( a_props, "height" );
-       *image = mlt_properties_get_data( a_props, "image", NULL );
-
-       // Close the b_frame
-       mlt_frame_close( b_frame );
+       if ( b_frame != NULL )
+       {
+               // Get the properties of the b frame
+               mlt_properties b_props = mlt_frame_properties( b_frame );
+
+               // Arbitrary composite defaults
+               int x = 0;
+               int y = 0;
+               double mix = 1.0;
+
+               // Override from b frame properties if provided
+               if ( mlt_properties_get( b_props, "x" ) != NULL )
+                       x = mlt_properties_get_int( b_props, "x" );
+               if ( mlt_properties_get( b_props, "y" ) != NULL )
+                       y = mlt_properties_get_int( b_props, "y" );
+               if ( mlt_properties_get( b_props, "mix" ) != NULL )
+                       mix = mlt_properties_get_double( b_props, "mix" );
+
+               // Composite the b_frame on the a_frame
+               mlt_frame_composite_yuv( this, b_frame, x, y, mix );
+
+               // Extract the a_frame image info
+               *width = mlt_properties_get_int( a_props, "width" );
+               *height = mlt_properties_get_int( a_props, "height" );
+               *image = mlt_properties_get_data( a_props, "image", NULL );
+
+               // Close the b_frame
+               mlt_frame_close( b_frame );
+       }
+       else if ( a_props != NULL )
+       {
+               // Extract the a_frame image info
+               *width = mlt_properties_get_int( a_props, "width" );
+               *height = mlt_properties_get_int( a_props, "height" );
+               *image = mlt_properties_get_data( a_props, "image", NULL );
+       }
 
        return 0;
 }
index a3ae3dc7796090a8a392a16966a139da226125f1..71c823805092b1b6d77fb49c951bf1ee2e80eeff 100644 (file)
@@ -339,9 +339,9 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram
        }
 
        // Determine the time position of this frame in the transition duration
-       mlt_timecode in = mlt_transition_get_in( transition );
-       mlt_timecode out = mlt_transition_get_out( transition );
-       mlt_timecode time = mlt_frame_get_timecode( b_frame );
+       mlt_position in = mlt_transition_get_in( transition );
+       mlt_position out = mlt_transition_get_out( transition );
+       mlt_position time = mlt_frame_get_position( b_frame );
        double pos = ( time - in ) / ( out - in );
        
        // Set the b frame properties
index 218f85bcea272672aa19d9ec0854cc8f4a3a89f1..f3aac3ce4402d5c296cfbebb0709204a2fe884e6 100644 (file)
@@ -2,7 +2,8 @@
 TARGET = ../libmltdv.so
 
 OBJS = factory.o \
-          producer_libdv.o 
+          producer_libdv.o \
+          consumer_libdv.o
 
 CFLAGS = -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread
 
index 876897c2b907fe6d733b92a7b459897020fda75b..94532672a283d7b6d9265ad60964c2ef78bbf3b7 100755 (executable)
@@ -7,5 +7,9 @@ cat << EOF >> ../producers.dat
 libdv                  libmltdv.so
 EOF
 
+cat << EOF >> ../consumers.dat
+libdv                  libmltdv.so
+EOF
+
 fi
 
diff --git a/mlt/src/modules/dv/consumer_libdv.c b/mlt/src/modules/dv/consumer_libdv.c
new file mode 100644 (file)
index 0000000..07bd6e6
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * producer_libdv.c -- a DV encoder based on libdv
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+// Local header files
+#include "consumer_libdv.h"
+
+// mlt Header files
+#include <framework/mlt_frame.h>
+
+// System header files
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+// libdv header files
+#include <libdv/dv.h>
+
+// Forward references.
+static int consumer_encode_video( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame );
+static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame );
+static void consumer_output( mlt_consumer this, uint8_t *dv_frame, int size, mlt_frame frame );
+static void *consumer_thread( void *arg );
+static void consumer_close( mlt_consumer this );
+
+/** Initialise the dv consumer.
+*/
+
+mlt_consumer consumer_libdv_init( char *arg )
+{
+       // Allocate the consumer
+       mlt_consumer this = calloc( 1, sizeof( struct mlt_consumer_s ) );
+
+       // If memory allocated and initialises without error
+       if ( this != NULL && mlt_consumer_init( this, NULL ) == 0 )
+       {
+               // Get properties from the consumer
+               mlt_properties properties = mlt_consumer_properties( this );
+
+               // Allocate a thread
+               pthread_t *thread = calloc( 1, sizeof( pthread_t ) );
+
+               // Assign close callback
+               this->close = consumer_close;
+
+               // Assign all properties
+               if ( arg == NULL || !strcmp( arg, "PAL" ) )
+                       mlt_properties_set_double( properties, "fps", 25 );
+               else
+                       mlt_properties_set_double( properties, "fps", 29.97 );
+
+               mlt_properties_set_data( properties, "thread", thread, sizeof( pthread_t ), free, NULL );
+               mlt_properties_set_data( properties, "video", consumer_encode_video, 0, NULL, NULL );
+               mlt_properties_set_data( properties, "audio", consumer_encode_audio, 0, NULL, NULL );
+               mlt_properties_set_data( properties, "output", consumer_output, 0, NULL, NULL );
+
+               // Create the thread (this should not happen immediately)
+               mlt_properties_set_int( properties, "running", 1 );
+               pthread_create( thread, NULL, consumer_thread, this );
+       }
+       else
+       {
+               // Clean up in case of init failure
+               free( this );
+               this = NULL;
+       }
+
+       // Return this
+       return this;
+}
+
+/** Get or create a new libdv encoder.
+*/
+
+static dv_encoder_t *libdv_get_encoder( mlt_consumer this, mlt_frame frame )
+{
+       // Get the properties of the consumer
+       mlt_properties this_properties = mlt_consumer_properties( this );
+
+       // Obtain the dv_encoder
+       dv_encoder_t *encoder = mlt_properties_get_data( this_properties, "dv_encoder", NULL );
+
+       // Construct one if we don't have one
+       if ( encoder == NULL )
+       {
+               // Get the fps of the consumer (for now - should be from frame)
+               double fps = mlt_properties_get_double( this_properties, "fps" );
+
+               // Create the encoder
+               encoder = dv_encoder_new( fps != 25, 0, 0 );
+
+               // Encoder settings
+               encoder->isPAL = fps = 25;
+               encoder->is16x9 = 0;
+               encoder->vlc_encode_passes = 1;
+               encoder->static_qno = 0;
+               encoder->force_dct = DV_DCT_AUTO;
+
+               // Store the encoder on the properties
+               mlt_properties_set_data( this_properties, "dv_encoder", encoder, 0, ( mlt_destructor )dv_encoder_free, NULL );
+
+               // Convenience for image dimensions
+               mlt_properties_set_int( this_properties, "width", 720 );
+               mlt_properties_set_int( this_properties, "height", fps == 25 ? 576 : 480 );
+       }
+
+       // Return the encoder
+       return encoder;
+}
+
+
+/** The libdv encode video method.
+*/
+
+static int consumer_encode_video( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame )
+{
+       // Obtain the dv_encoder
+       dv_encoder_t *encoder = libdv_get_encoder( this, frame );
+
+       // Get the properties of the consumer
+       mlt_properties this_properties = mlt_consumer_properties( this );
+
+       // This will hold the size of the dv frame
+       int size = 0;
+
+       // If we get an encoder, then encode the image
+       if ( encoder != NULL )
+       {
+               // Specify desired image properties
+               mlt_image_format fmt = mlt_image_yuv422;
+               int width = mlt_properties_get_int( this_properties, "width" );
+               int height = mlt_properties_get_int( this_properties, "height" );
+               uint8_t *image = NULL;
+
+               // Get the image
+               mlt_frame_get_image( frame, &image, &fmt, &width, &height, 0 );
+
+               // Check that we get what we expected
+               if ( fmt != mlt_image_yuv422 || 
+                        width != mlt_properties_get_int( this_properties, "width" ) ||
+                        height != mlt_properties_get_int( this_properties, "height" ) ||
+                        image == NULL )
+               {
+                       // We should try to recover here
+                       fprintf( stderr, "We have a problem houston...\n" );
+               }
+               else
+               {
+                       // Calculate the size of the dv frame
+                       size = height == 576 ? frame_size_625_50 : frame_size_525_60;
+               }
+
+               // Process the frame
+               if ( size != 0 )
+               {
+                       // Encode the image
+                       dv_encode_full_frame( encoder, &image, e_dv_color_yuv, dv_frame );
+               }
+       }
+       
+       return size;
+}
+
+/** The libdv encode audio method.
+*/
+
+static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame )
+{
+       // Get the properties of the consumer
+       mlt_properties this_properties = mlt_consumer_properties( this );
+
+       // Obtain the dv_encoder
+       dv_encoder_t *encoder = libdv_get_encoder( this, frame );
+
+       // Only continue if we have an encoder
+       if ( encoder != NULL )
+       {
+               // Get the frame count
+               int count = mlt_properties_get_int( this_properties, "count" );
+
+               // Default audio args
+               mlt_audio_format fmt = mlt_audio_pcm;
+               int channels = 2;
+               int frequency = 48000;
+               int samples = mlt_sample_calculator( mlt_properties_get_double( this_properties, "fps" ), frequency, count );
+               int16_t *pcm = NULL;
+
+               // Get the frame number
+               time_t start = time( NULL );
+               int height = mlt_properties_get_int( this_properties, "height" );
+               int is_pal = height == 576;
+               int is_wide = 0;
+
+               // Temporary - audio buffer allocation
+               int16_t *audio_buffers[ 4 ];
+               int i = 0;
+               int j = 0;
+               for ( i = 0 ; i < 4; i ++ )
+                       audio_buffers[ i ] = malloc( 2 * DV_AUDIO_MAX_SAMPLES );
+
+               // Get the audio
+               mlt_frame_get_audio( frame, &pcm, &fmt, &frequency, &channels, &samples );
+
+               // Inform the encoder of the number of audio samples
+               encoder->samples_this_frame = samples;
+
+               // Fill the audio buffers correctly
+               for ( i = 0; i < samples; i ++ )
+                       for ( j = 0; j < channels; j++ )
+                               audio_buffers[ j ][ i ] = *pcm ++;
+
+               // Encode audio on frame
+               dv_encode_full_audio( encoder, audio_buffers, channels, frequency, dv_frame );
+
+               // Specify meta data on the frame
+               dv_encode_metadata( dv_frame, is_pal, is_wide, &start, count );
+               dv_encode_timecode( dv_frame, is_pal, count );
+
+               // Update properties
+               mlt_properties_set_int( this_properties, "count", ++ count );
+
+               // Temporary - free audio buffers
+               for ( i = 0 ; i < 4; i ++ )
+                       free( audio_buffers[ i ] );
+       }
+}
+
+/** The libdv output method.
+*/
+
+static void consumer_output( mlt_consumer this, uint8_t *dv_frame, int size, mlt_frame frame )
+{
+       fwrite( dv_frame, size, 1, stdout );
+       fflush( stdout );
+}
+
+/** The main thread - the argument is simply the consumer.
+*/
+
+static void *consumer_thread( void *arg )
+{
+       // Map the argument to the object
+       mlt_consumer this = arg;
+
+       // Get the properties
+       mlt_properties properties = mlt_consumer_properties( this );
+
+       // Get the handling methods
+       int ( *video )( mlt_consumer, uint8_t *, mlt_frame ) = mlt_properties_get_data( properties, "video", NULL );
+       int ( *audio )( mlt_consumer, uint8_t *, mlt_frame ) = mlt_properties_get_data( properties, "audio", NULL );
+       int ( *output )( mlt_consumer, uint8_t *, int, mlt_frame ) = mlt_properties_get_data( properties, "output", NULL );
+
+       // Allocate a single PAL frame for encoding
+       uint8_t *dv_frame = malloc( frame_size_625_50 );
+
+       // Get the service associated to the consumer
+       mlt_service service = mlt_consumer_service( this );
+
+       // Define a frame pointer
+       mlt_frame frame;
+
+       // Loop while running
+       while( mlt_properties_get_int( properties, "running" ) )
+       {
+               // Get the frame
+               if ( mlt_service_get_frame( service, &frame, 0 ) == 0 )
+               {
+                       // Encode the image
+                       int size = video( this, dv_frame, frame );
+
+                       // Encode the audio
+                       if ( size > 0 )
+                               audio( this, dv_frame, frame );
+
+                       // Output the frame
+                       output( this, dv_frame, size, frame );
+
+                       // Close the frame
+                       mlt_frame_close( frame );
+               }
+       }
+
+       // Tidy up
+       free( dv_frame );
+
+       return NULL;
+}
+
+/** Close the consumer.
+*/
+
+static void consumer_close( mlt_consumer this )
+{
+       // Get the properties
+       mlt_properties properties = mlt_consumer_properties( this );
+
+       // Get the thread
+       pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL );
+
+       // Stop the thread
+       mlt_properties_set_int( properties, "running", 0 );
+
+       // Wait for termination
+       pthread_join( *thread, NULL );
+
+       // Close the parent
+       mlt_consumer_close( this );
+
+       // Free the memory
+       free( this );
+}
+
diff --git a/mlt/src/modules/dv/consumer_libdv.h b/mlt/src/modules/dv/consumer_libdv.h
new file mode 100644 (file)
index 0000000..de7311e
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * producer_libdv.h -- a DV encoder based on libdv
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CONSUMER_LIBDV_H_
+#define _CONSUMER_LIBDV_H_
+
+#include <framework/mlt_consumer.h>
+
+extern mlt_consumer consumer_libdv_init( char *filename );
+
+#endif
index e27510a2e87f6c1973ab294cf7f6f386c0fc1f40..8d25f70e101ffb96550bf721e86be94aa52915ba 100644 (file)
@@ -21,6 +21,7 @@
 #include <string.h>
 
 #include "producer_libdv.h"
+#include "consumer_libdv.h"
 
 void *mlt_create_producer( char *id, void *arg )
 {
@@ -41,6 +42,8 @@ void *mlt_create_transition( char *id, void *arg )
 
 void *mlt_create_consumer( char *id, void *arg )
 {
+       if ( !strcmp( id, "libdv" ) )
+               return consumer_libdv_init( arg );
        return NULL;
 }
 
index 8c139df6c663884cac83b3e9eda9d7b5e91e4e12..b82a0e66ef2f90e8382f6869b8eec4db5d6355a4 100644 (file)
@@ -130,11 +130,10 @@ static int producer_collect_info( producer_libdv this )
 
                        // Calculate default in/out points
                        double fps = this->is_pal ? 25 : 30000.0 / 1001.0;
-                       mlt_timecode length = ( mlt_timecode )( this->frames_in_file ) / fps;
                        mlt_properties_set_double( properties, "fps", fps );
-                       mlt_properties_set_timecode( properties, "length", length );
-                       mlt_properties_set_timecode( properties, "in", 0.0 );
-                       mlt_properties_set_timecode( properties, "out", ( mlt_timecode )( this->frames_in_file - 1 ) / fps );
+                       mlt_properties_set_position( properties, "length", this->frames_in_file );
+                       mlt_properties_set_position( properties, "in", 0 );
+                       mlt_properties_set_position( properties, "out", this->frames_in_file - 1 );
 
                        // Parse the header for meta info
                        dv_parse_header( this->dv_decoder, dv_data );
@@ -307,7 +306,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        }
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
        // Calculate the next timecode
        mlt_producer_prepare_next( producer );
index 652354bb47a6a7d48b4c7d42884d21202591c959..0d678af208ea9720e96eca0499af70f085002eb5 100644 (file)
@@ -47,7 +47,7 @@ static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format
        if ( !mlt_properties_get_int( producer_properties, "end_of_clip" ) )
        {
                // Get the position
-               double position = mlt_properties_get_double( producer_properties, "dub_position" );
+               mlt_position position = mlt_properties_get_position( producer_properties, "dub_position" );
 
                // We need a frame from the producer
                mlt_frame producer_frame;
@@ -56,7 +56,7 @@ static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format
                mlt_properties_set_double( producer_properties, "fps", mlt_properties_get_double( frame_properties, "fps" ) );
 
                // Seek to the position
-               mlt_producer_seek_frame( producer, ( int64_t )position );
+               mlt_producer_seek( producer, position );
 
                // Get the next frame
                producer->get_frame( producer, &producer_frame, 0 );
@@ -70,7 +70,7 @@ static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format
                        mlt_properties_set_data( frame_properties, "ffmpeg_dub_frame", producer_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
 
                        // Incrment the position
-                       mlt_properties_set_double( producer_properties, "dub_position", position + 1 );
+                       mlt_properties_set_position( producer_properties, "dub_position", position + 1 );
                }
        }
 
@@ -135,7 +135,7 @@ mlt_filter filter_ffmpeg_dub_init( char *file )
        mlt_properties_set_data( properties, "producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL );
 
        // Initialise the audio frame position
-       mlt_properties_set_double( properties, "dub_position", 0 );
+       mlt_properties_set_position( properties, "dub_position", 0 );
 
        return this;
 }
index 9233bb3441879642c86967f178bfc5b69baf733b..f383aff1bc203f04be74dc9fa1121d56337328b3 100644 (file)
@@ -240,7 +240,7 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma
        return 0;
 }
 
-FILE *producer_ffmpeg_run_video( producer_ffmpeg this, mlt_timecode position )
+FILE *producer_ffmpeg_run_video( producer_ffmpeg this, mlt_position position )
 {
        if ( this->video == NULL )
        {
@@ -277,7 +277,7 @@ FILE *producer_ffmpeg_run_video( producer_ffmpeg this, mlt_timecode position )
        return this->video;
 }
 
-FILE *producer_ffmpeg_run_audio( producer_ffmpeg this, mlt_timecode position )
+FILE *producer_ffmpeg_run_audio( producer_ffmpeg this, mlt_position position )
 {
        // Get the producer
        mlt_producer producer = &this->parent;
@@ -530,12 +530,12 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        if ( this->end_of_video && this->end_of_audio )
        {
                mlt_properties_set_int( properties, "end_of_clip", 1 );
-               mlt_properties_set_timecode( producer_properties, "length", mlt_producer_position( &this->parent ) );
+               mlt_properties_set_position( producer_properties, "length", mlt_producer_position( &this->parent ) );
                mlt_producer_set_in_and_out( &this->parent, mlt_producer_get_in( &this->parent ), mlt_producer_position( &this->parent ) );
        }
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
        // Calculate the next timecode
        mlt_producer_prepare_next( producer );
index 752ed4a1241fe84b456c6d4cb20c578650188a0b..2a8d99f45c05b8adf44e628c690ba96963fc5962 100644 (file)
@@ -340,7 +340,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        }
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
        // Calculate the next timecode
        mlt_producer_prepare_next( producer );
index 84ed6e64b09b0a2f0f5c05f98c89aa1f8af98408..04a9e64a66e768b3b4440b3612c9963c5de530af 100644 (file)
@@ -90,7 +90,7 @@ mlt_producer producer_pixbuf_init( char *filename )
                                        gap ++;
                                }
                        } 
-                       mlt_properties_set_timecode( properties, "out", this->count );
+                       mlt_properties_set_position( properties, "out", this->count * 25 );
                }
                else if ( strstr( filename, "/.all." ) != NULL )
                {
@@ -117,7 +117,7 @@ mlt_producer producer_pixbuf_init( char *filename )
                                free( de[ i ] );
                        }
 
-                       mlt_properties_set_timecode( properties, "out", this->count );
+                       mlt_properties_set_position( properties, "out", this->count * 25 );
                        free( de );
                        free( dir_name );
                }
@@ -125,7 +125,7 @@ mlt_producer producer_pixbuf_init( char *filename )
                {
                        this->filenames = realloc( this->filenames, sizeof( char * ) * ( this->count + 1 ) );
                        this->filenames[ this->count ++ ] = strdup( filename );
-                       mlt_properties_set_timecode( properties, "out", 1 );
+                       mlt_properties_set_position( properties, "out", 25 );
                }
 
                // Initialise gobject types
@@ -207,7 +207,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        int image_idx = ( int )floor( mlt_producer_position( producer ) / ttl ) % this->count;
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
     // optimization for subsequent iterations on single picture
        if ( this->image != NULL && image_idx == this->image_idx )
index 581db3dfa5170661dd37c656e84c7a4d90aa6153..62e02b26dd05aeb3f192c655b4510bd8aded516d 100644 (file)
@@ -241,10 +241,15 @@ mlt_producer producer_inigo_init( char **argv )
                mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist ), track );
        }
 
-       mlt_properties props = mlt_multitrack_properties( multitrack );
+       mlt_tractor tractor = mlt_field_tractor( field );
+       mlt_producer prod = mlt_tractor_producer( tractor );
+       mlt_properties props = mlt_tractor_properties( tractor );
+       mlt_properties_set_data( props, "multitrack", multitrack, 0, NULL, NULL );
        mlt_properties_set_data( props, "field", field, 0, NULL, NULL );
        mlt_properties_set_data( props, "group", group, 0, NULL, NULL );
+       mlt_producer_set_in_and_out( prod, 0, mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) );
+       mlt_properties_set_double( props, "fps", mlt_producer_get_fps( mlt_multitrack_producer( multitrack ) ) );
 
-       return mlt_multitrack_producer( multitrack );
+       return mlt_tractor_producer( tractor );
 }
 
index 803e96ee6acd449f0e013b8fdadbf4376fff856f..e56d56c71294fa63bbf87041e2c64a9989f37094 100644 (file)
@@ -529,8 +529,7 @@ static void consumer_close( mlt_consumer parent )
        pthread_mutex_destroy( &this->audio_mutex );
        pthread_cond_destroy( &this->audio_cond );
                
-       // Now clean up the rest (the close = NULL is a bit nasty but needed for now)
-       parent->close = NULL;
+       // Now clean up the rest
        mlt_consumer_close( parent );
 
        // Finally clean up this
index f263a205c8afaa85eaa840e2cb026c1c0e5a725a..5ff7f5f73f39f4cfb28cdd28bec1351b9840b658 100644 (file)
@@ -63,8 +63,15 @@ int mlt_consumer_connect( mlt_consumer this, mlt_service producer )
 
 void mlt_consumer_close( mlt_consumer this )
 {
-       if ( this->close != NULL )
-               this->close( this );
+       // Get the childs close function
+       void ( *consumer_close )( ) = this->close;
+
+       // Make sure it only gets called once
+       this->close = NULL;
+
+       // Call the childs close if available
+       if ( consumer_close != NULL )
+               consumer_close( this );
        else
                mlt_service_close( &this->parent );
 }
index 9795770ba430f94ac293b4e3b6689bf37087d687..9223178994163a2542f7d7395862c80fdfd77b55 100644 (file)
@@ -19,9 +19,8 @@
  */
 
 #include "config.h"
-#include "mlt_factory.h"
+#include "mlt.h"
 #include "mlt_repository.h"
-#include "mlt_properties.h"
 
 #include <stdlib.h>
 #include <string.h>
@@ -41,22 +40,26 @@ static mlt_repository consumers = NULL;
 
 int mlt_factory_init( char *prefix )
 {
-       // If no directory is specified, default to install directory
-       if ( prefix == NULL )
-               prefix = PREFIX_DATA;
-
-       // Store the prefix for later retrieval
-       mlt_prefix = strdup( prefix );
-
-       // Create the object list.
-       object_list = calloc( sizeof( struct mlt_properties_s ), 1 );
-       mlt_properties_init( object_list, NULL );
-
-       // Create a repository for each service type
-       producers = mlt_repository_init( object_list, prefix, "producers.dat", "mlt_create_producer" );
-       filters = mlt_repository_init( object_list, prefix, "filters.dat", "mlt_create_filter" );
-       transitions = mlt_repository_init( object_list, prefix, "transitions.dat", "mlt_create_transition" );
-       consumers = mlt_repository_init( object_list, prefix, "consumers.dat", "mlt_create_consumer" );
+       // Only initialise once
+       if ( mlt_prefix == NULL )
+       {
+               // If no directory is specified, default to install directory
+               if ( prefix == NULL )
+                       prefix = PREFIX_DATA;
+
+               // Store the prefix for later retrieval
+               mlt_prefix = strdup( prefix );
+
+               // Create the object list.
+               object_list = calloc( sizeof( struct mlt_properties_s ), 1 );
+               mlt_properties_init( object_list, NULL );
+
+               // Create a repository for each service type
+               producers = mlt_repository_init( object_list, prefix, "producers.dat", "mlt_create_producer" );
+               filters = mlt_repository_init( object_list, prefix, "filters.dat", "mlt_create_filter" );
+               transitions = mlt_repository_init( object_list, prefix, "transitions.dat", "mlt_create_transition" );
+               consumers = mlt_repository_init( object_list, prefix, "consumers.dat", "mlt_create_consumer" );
+       }
 
        return 0;
 }
@@ -74,7 +77,14 @@ const char *mlt_factory_prefix( )
 
 mlt_producer mlt_factory_producer( char *service, void *input )
 {
-       return ( mlt_producer )mlt_repository_fetch( producers, service, input );
+       mlt_producer obj = mlt_repository_fetch( producers, service, input );
+       if ( obj != NULL )
+       {
+               mlt_properties properties = mlt_producer_properties( obj );
+               mlt_properties_set( properties, "mlt_type", "producer" );
+               mlt_properties_set( properties, "mlt_service", service );
+       }
+       return obj;
 }
 
 /** Fetch a filter from the repository.
@@ -82,7 +92,14 @@ mlt_producer mlt_factory_producer( char *service, void *input )
 
 mlt_filter mlt_factory_filter( char *service, void *input )
 {
-       return ( mlt_filter )mlt_repository_fetch( filters, service, input );
+       mlt_filter obj = mlt_repository_fetch( filters, service, input );
+       if ( obj != NULL )
+       {
+               mlt_properties properties = mlt_filter_properties( obj );
+               mlt_properties_set( properties, "mlt_type", "filter" );
+               mlt_properties_set( properties, "mlt_service", service );
+       }
+       return obj;
 }
 
 /** Fetch a transition from the repository.
@@ -90,7 +107,14 @@ mlt_filter mlt_factory_filter( char *service, void *input )
 
 mlt_transition mlt_factory_transition( char *service, void *input )
 {
-       return ( mlt_transition )mlt_repository_fetch( transitions, service, input );
+       mlt_transition obj = mlt_repository_fetch( transitions, service, input );
+       if ( obj != NULL )
+       {
+               mlt_properties properties = mlt_transition_properties( obj );
+               mlt_properties_set( properties, "mlt_type", "transition" );
+               mlt_properties_set( properties, "mlt_service", service );
+       }
+       return obj;
 }
 
 /** Fetch a consumer from the repository
@@ -98,7 +122,14 @@ mlt_transition mlt_factory_transition( char *service, void *input )
 
 mlt_consumer mlt_factory_consumer( char *service, void *input )
 {
-       return ( mlt_consumer )mlt_repository_fetch( consumers, service, input );
+       mlt_consumer obj = mlt_repository_fetch( consumers, service, input );
+       if ( obj != NULL )
+       {
+               mlt_properties properties = mlt_consumer_properties( obj );
+               mlt_properties_set( properties, "mlt_type", "consumer" );
+               mlt_properties_set( properties, "mlt_service", service );
+       }
+       return obj;
 }
 
 /** Close the factory.
@@ -106,12 +137,16 @@ mlt_consumer mlt_factory_consumer( char *service, void *input )
 
 void mlt_factory_close( )
 {
-       mlt_repository_close( producers );
-       mlt_repository_close( filters );
-       mlt_repository_close( transitions );
-       mlt_repository_close( consumers );
-       mlt_properties_close( object_list );
-       free( mlt_prefix );
-       free( object_list );
+       if ( mlt_prefix != NULL )
+       {
+               mlt_repository_close( producers );
+               mlt_repository_close( filters );
+               mlt_repository_close( transitions );
+               mlt_repository_close( consumers );
+               mlt_properties_close( object_list );
+               free( mlt_prefix );
+               free( object_list );
+               mlt_prefix = NULL;
+       }
 }
 
index a54d97e19e1cf4672672efc3702461d0b36d3833..8a7f51f47f2595e1c75c5fce47d63858dc6734bc 100644 (file)
@@ -89,6 +89,14 @@ mlt_multitrack mlt_field_multitrack( mlt_field this )
        return this->multitrack;
 }
 
+/** Get the tractor.
+*/
+
+mlt_tractor mlt_field_tractor( mlt_field this )
+{
+       return this->tractor;
+}
+
 /** Get the properties associated to this field.
 */
 
index 6fef29606890b9174f36f2f669aeddc4f33f3c77..d84d0cc09a5b0882d3f89b2ea98e32519d01f13d 100644 (file)
@@ -25,6 +25,7 @@
 
 extern mlt_field mlt_field_init( );
 extern mlt_service mlt_field_service( mlt_field this );
+extern mlt_tractor mlt_field_tractor( mlt_field this );
 extern mlt_multitrack mlt_field_multitrack( mlt_field this );
 extern mlt_properties mlt_field_properties( mlt_field this );
 extern int mlt_field_plant_filter( mlt_field this, mlt_filter that, int track );
index 9c0a295234443da8b29cf4105fe6313eb04f6e8c..6e39e7971a04185e5e4b5abfe4d52b30d8b7117b 100644 (file)
@@ -45,8 +45,8 @@ int mlt_filter_init( mlt_filter this, void *child )
                service->get_frame = filter_get_frame;
 
                // Default in, out, track properties
-               mlt_properties_set_timecode( properties, "in", 0 );
-               mlt_properties_set_timecode( properties, "out", 0 );
+               mlt_properties_set_position( properties, "in", 0 );
+               mlt_properties_set_position( properties, "out", 0 );
                mlt_properties_set_int( properties, "track", 0 );
 
                return 0;
@@ -80,8 +80,8 @@ int mlt_filter_connect( mlt_filter this, mlt_service producer, int index )
        {
                mlt_properties properties = mlt_service_properties( &this->parent );
                this->producer = producer;
-               mlt_properties_set_timecode( properties, "in", 0 );
-               mlt_properties_set_timecode( properties, "out", 0 );
+               mlt_properties_set_position( properties, "in", 0 );
+               mlt_properties_set_position( properties, "out", 0 );
                mlt_properties_set_int( properties, "track", index );
        }
        
@@ -91,11 +91,11 @@ int mlt_filter_connect( mlt_filter this, mlt_service producer, int index )
 /** Tune the in/out points.
 */
 
-void mlt_filter_set_in_and_out( mlt_filter this, mlt_timecode in, mlt_timecode out )
+void mlt_filter_set_in_and_out( mlt_filter this, mlt_position in, mlt_position out )
 {
        mlt_properties properties = mlt_service_properties( &this->parent );
-       mlt_properties_set_timecode( properties, "in", in );
-       mlt_properties_set_timecode( properties, "out", out );
+       mlt_properties_set_position( properties, "in", in );
+       mlt_properties_set_position( properties, "out", out );
 }
 
 /** Return the track that this filter is operating on.
@@ -110,19 +110,19 @@ int mlt_filter_get_track( mlt_filter this )
 /** Get the in point.
 */
 
-mlt_timecode mlt_filter_get_in( mlt_filter this )
+mlt_position mlt_filter_get_in( mlt_filter this )
 {
        mlt_properties properties = mlt_service_properties( &this->parent );
-       return mlt_properties_get_timecode( properties, "in" );
+       return mlt_properties_get_position( properties, "in" );
 }
 
 /** Get the out point.
 */
 
-mlt_timecode mlt_filter_get_out( mlt_filter this )
+mlt_position mlt_filter_get_out( mlt_filter this )
 {
        mlt_properties properties = mlt_service_properties( &this->parent );
-       return mlt_properties_get_timecode( properties, "out" );
+       return mlt_properties_get_position( properties, "out" );
 }
 
 /** Process the frame.
@@ -156,8 +156,8 @@ static int filter_get_frame( mlt_service service, mlt_frame_ptr frame, int index
                {
                        if ( !mlt_frame_is_test_card( *frame ) )
                        {
-                               mlt_timecode timecode = mlt_frame_get_timecode( *frame );
-                               if ( timecode >= in && ( out == 0 || timecode < out ) )
+                               mlt_position position = mlt_frame_get_position( *frame );
+                               if ( position >= in && ( out == 0 || position < out ) )
                                        *frame = filter_process( this, *frame );
                        }
                        return 0;
index e3f0f74dccdb4586dacb0b0a1a2e97627a325644..edaf6f626b30d2d160d2211bb7a5f6f2be3536a1 100644 (file)
@@ -51,10 +51,10 @@ extern int mlt_filter_init( mlt_filter this, void *child );
 extern mlt_service mlt_filter_service( mlt_filter this );
 extern mlt_properties mlt_filter_properties( mlt_filter this );
 extern int mlt_filter_connect( mlt_filter this, mlt_service producer, int index );
-extern void mlt_filter_set_in_and_out( mlt_filter this, mlt_timecode in, mlt_timecode out );
+extern void mlt_filter_set_in_and_out( mlt_filter this, mlt_position in, mlt_position out );
 extern int mlt_filter_get_track( mlt_filter this );
-extern mlt_timecode mlt_filter_get_in( mlt_filter this );
-extern mlt_timecode mlt_filter_get_out( mlt_filter this );
+extern mlt_position mlt_filter_get_in( mlt_filter this );
+extern mlt_position mlt_filter_get_out( mlt_filter this );
 extern void mlt_filter_close( mlt_filter );
 
 #endif
index a51fb7e68896e60e903843c81c73a7e674db5f8e..cb26ee944abf93738b744768b1f7464e8afe467b 100644 (file)
@@ -53,7 +53,7 @@ mlt_frame mlt_frame_init( )
                mlt_properties_init( properties, this );
 
                // Set default properties on the frame
-               mlt_properties_set_timecode( properties, "timecode", 0.0 );
+               mlt_properties_set_position( properties, "position", 0.0 );
                mlt_properties_set_data( properties, "image", NULL, 0, NULL, NULL );
                mlt_properties_set_int( properties, "width", 720 );
                mlt_properties_set_int( properties, "height", 576 );
@@ -98,22 +98,22 @@ int mlt_frame_set_aspect_ratio( mlt_frame this, double value )
        return mlt_properties_set_double( properties, "aspect_ratio", value );
 }
 
-/** Get the timecode of this frame.
+/** Get the position of this frame.
 */
 
-mlt_timecode mlt_frame_get_timecode( mlt_frame this )
+mlt_position mlt_frame_get_position( mlt_frame this )
 {
        mlt_properties properties = mlt_frame_properties( this );
-       return mlt_properties_get_timecode( properties, "timecode" );
+       return mlt_properties_get_position( properties, "position" );
 }
 
-/** Set the timecode of this frame.
+/** Set the position of this frame.
 */
 
-int mlt_frame_set_timecode( mlt_frame this, mlt_timecode value )
+int mlt_frame_set_position( mlt_frame this, mlt_position value )
 {
        mlt_properties properties = mlt_frame_properties( this );
-       return mlt_properties_set_timecode( properties, "timecode", value );
+       return mlt_properties_set_position( properties, "position", value );
 }
 
 /** Stack a get_image callback.
@@ -709,7 +709,7 @@ int mlt_frame_mix_audio( mlt_frame this, mlt_frame that, float weight, int16_t *
        int i, j;
 
        mlt_frame_get_audio( this, &p_dest, format, &frequency_dest, &channels_dest, &samples_dest );
-       //fprintf( stderr, "frame dest samples %d channels %d timecode %f\n", samples_dest, channels_dest, mlt_properties_get_timecode( mlt_frame_properties( this ), "timecode" ) );
+       //fprintf( stderr, "frame dest samples %d channels %d position %f\n", samples_dest, channels_dest, mlt_properties_get_position( mlt_frame_properties( this ), "position" ) );
        mlt_frame_get_audio( that, &p_src, format, &frequency_src, &channels_src, &samples_src );
        //fprintf( stderr, "frame src  samples %d channels %d\n", samples_src, channels_src );
        if ( channels_src > 6 )
index 175df0acf5c8a6b53cf4a29fea03132260b73319..58476d546d1816c621a7152a44575b567ca582d2 100644 (file)
@@ -70,8 +70,8 @@ extern mlt_properties mlt_frame_properties( mlt_frame this );
 extern int mlt_frame_is_test_card( mlt_frame this );
 extern double mlt_frame_get_aspect_ratio( mlt_frame this );
 extern int mlt_frame_set_aspect_ratio( mlt_frame this, double value );
-extern mlt_timecode mlt_frame_get_timecode( mlt_frame this );
-extern int mlt_frame_set_timecode( mlt_frame this, mlt_timecode value );
+extern mlt_position mlt_frame_get_position( mlt_frame this );
+extern int mlt_frame_set_position( mlt_frame this, mlt_position value );
 
 extern int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable );
 extern uint8_t *mlt_frame_get_alpha_mask( mlt_frame this );
index 893cef5f6b9c457cdb8751172c42253f917e9cbd..47bc271d1e421a4d7ff4ba4b3f46ba2897b0b3ed 100644 (file)
@@ -96,7 +96,7 @@ mlt_properties mlt_multitrack_properties( mlt_multitrack this )
        return mlt_service_properties( mlt_multitrack_service( this ) );
 }
 
-/** Initialise timecode related information.
+/** Initialise position related information.
 */
 
 void mlt_multitrack_refresh( mlt_multitrack this )
@@ -107,7 +107,7 @@ void mlt_multitrack_refresh( mlt_multitrack this )
        mlt_properties properties = mlt_multitrack_properties( this );
 
        // We need to ensure that the multitrack reports the longest track as its length
-       mlt_timecode length = 0;
+       mlt_position length = 0;
 
        // We need to ensure that fps are the same on all services
        double fps = 0;
@@ -146,8 +146,8 @@ void mlt_multitrack_refresh( mlt_multitrack this )
        }
 
        // Update multitrack properties now - we'll not destroy the in point here
-       mlt_properties_set_timecode( properties, "length", length );
-       mlt_properties_set_timecode( properties, "out", length );
+       mlt_properties_set_position( properties, "length", length );
+       mlt_properties_set_position( properties, "out", length );
        mlt_properties_set_double( properties, "fps", fps );
 }
 
@@ -208,10 +208,10 @@ int mlt_multitrack_connect( mlt_multitrack this, mlt_producer producer, int trac
        0.0, 1.0, b0.0, 0.1, b1.1, 1.1, 0.1, 0.2, [out of playlist2], [out of playlist1]
 */
 
-mlt_timecode mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index )
+mlt_position mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index )
 {
        int first = 1;
-       mlt_timecode position = 0;
+       mlt_position position = 0;
        int i = 0;
 
        // Loop through each of the tracks
@@ -232,7 +232,7 @@ mlt_timecode mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int in
                        // We only consider playlists
                        if ( playlist != NULL )
                        {
-                               // Locate the smallest timecode
+                               // Locate the smallest position
                                if ( first )
                                {
                                        // First position found
@@ -244,13 +244,17 @@ mlt_timecode mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int in
                                else
                                {
                                        // Obtain the clip position in this playlist
-                                       mlt_timecode position2 = mlt_playlist_clip( playlist, whence, index );
+                                       //mlt_position position2 = mlt_playlist_clip( playlist, whence, index );
 
                                        // If this position is prior to the first, then use it
-                                       if ( position2 < position )
-                                               position = position2;
+                                       //if ( position2 < position )
+                                               //position = position2;
                                }
                        }
+                       else
+                       {
+                               fprintf( stderr, "track %d isn't a playlist\n", index );
+                       }
                }
        }
 
@@ -293,11 +297,11 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int ind
                // Get the producer for this track
                mlt_producer producer = this->list[ index ];
 
-               // Obtain the current timecode
+               // Obtain the current position
                uint64_t position = mlt_producer_frame( parent );
 
                // Make sure we're at the same point
-               mlt_producer_seek_frame( producer, position );
+               mlt_producer_seek( producer, position );
 
                // Get the frame from the producer
                mlt_service_get_frame( mlt_producer_service( producer ), frame, 0 );
@@ -313,8 +317,8 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int ind
                // Generate a test frame
                *frame = mlt_frame_init( );
 
-               // Update timecode on the frame we're creating
-               mlt_frame_set_timecode( *frame, mlt_producer_position( parent ) );
+               // Update position on the frame we're creating
+               mlt_frame_set_position( *frame, mlt_producer_position( parent ) );
 
                // Move on to the next frame
                if ( index >= this->count )
index 83f34dd71cb8036ee9622a0a22c513f6779c17e9..3f6d8d9ad603285bed2b4f723189bfeaa71f6454 100644 (file)
@@ -31,7 +31,7 @@ extern mlt_producer mlt_multitrack_producer( mlt_multitrack this );
 extern mlt_service mlt_multitrack_service( mlt_multitrack this );
 extern mlt_properties mlt_multitrack_properties( mlt_multitrack this );
 extern int mlt_multitrack_connect( mlt_multitrack this, mlt_producer producer, int track );
-extern mlt_timecode mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index );
+extern mlt_position mlt_multitrack_clip( mlt_multitrack this, mlt_whence whence, int index );
 extern void mlt_multitrack_close( mlt_multitrack this );
 
 #endif
index 519585ce3b8e9664ae046546ffae26dad08967ac..921bbd5e44da3372997d8a286e997fca0b4ade62 100644 (file)
 typedef struct
 {
        mlt_producer producer;
-       int64_t frame_in;
-       int64_t frame_out;
-       int64_t frame_count;
-       mlt_timecode playtime;
+       mlt_position frame_in;
+       mlt_position frame_out;
+       mlt_position frame_count;
 }
 playlist_entry;
 
@@ -111,13 +110,16 @@ mlt_properties mlt_playlist_properties( mlt_playlist this )
        return mlt_producer_properties( &this->parent );
 }
 
+/** Refresh the playlist after a clip has been changed.
+*/
+
 static int mlt_playlist_virtual_refresh( mlt_playlist this )
 {
        int i = 0;
 
        // Get the fps of the first producer
        double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "first_fps" );
-       mlt_timecode playtime = 0;
+       mlt_position frame_count = 0;
 
        for ( i = 0; i < this->count; i ++ )
        {
@@ -139,15 +141,15 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
                        mlt_properties_set_double( mlt_producer_properties( producer ), "fps", fps );
                }
 
-               // Update the playtime for this clip
-               playtime += this->list[ i ]->playtime;
+               // Update the frame_count for this clip
+               frame_count += this->list[ i ]->frame_count;
        }
 
        // Refresh all properties
        mlt_properties_set_double( mlt_playlist_properties( this ), "first_fps", fps );
        mlt_properties_set_double( mlt_playlist_properties( this ), "fps", fps == 0 ? 25 : fps );
-       mlt_properties_set_timecode( mlt_playlist_properties( this ), "length", playtime );
-       mlt_properties_set_timecode( mlt_playlist_properties( this ), "out", playtime );
+       mlt_properties_set_position( mlt_playlist_properties( this ), "length", frame_count );
+       mlt_properties_set_position( mlt_playlist_properties( this ), "out", frame_count );
 
        return 0;
 }
@@ -155,11 +157,8 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
 /** Append to the virtual playlist.
 */
 
-static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, int64_t in, int64_t out )
+static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_position in, mlt_position out )
 {
-       double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "fps" );
-       double playtime = ( double )( out - in + 1 ) / fps;
-
        // Check that we have room
        if ( this->count >= this->size )
        {
@@ -175,7 +174,6 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer
        this->list[ this->count ]->frame_in = in;
        this->list[ this->count ]->frame_out = out;
        this->list[ this->count ]->frame_count = out - in + 1;
-       this->list[ this->count ]->playtime = playtime;
 
        mlt_producer_set_speed( producer, 0 );
 
@@ -193,21 +191,27 @@ static mlt_producer mlt_playlist_virtual_seek( mlt_playlist this )
        mlt_producer producer = NULL;
 
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode pos = mlt_producer_position( &this->parent );
-       int64_t position = mlt_producer_frame_position( &this->parent, pos );
+       mlt_position position = mlt_producer_frame( &this->parent );
+
+       // Total number of frames
        int64_t total = 0;
 
+       // Get the properties
        mlt_properties properties = mlt_playlist_properties( this );
+
+       // Get the eof handling
        char *eof = mlt_properties_get( properties, "eof" );
 
-       // Loop through the virtual playlist
+       // Index for the main loop
        int i = 0;
 
+       // Loop for each producer until found
        for ( i = 0; i < this->count; i ++ )
        {
                // Increment the total
                total += this->list[ i ]->frame_count;
 
+               // Check if the position indicates that we have found the clip
                if ( position < this->list[ i ]->frame_count )
                {
                        // Found it, now break
@@ -225,47 +229,43 @@ static mlt_producer mlt_playlist_virtual_seek( mlt_playlist this )
        if ( producer != NULL )
        {
                position += this->list[ i ]->frame_in;
-               position += mlt_producer_frame_position( producer, mlt_producer_get_in( producer ) );
-               mlt_producer_seek_frame( producer, position );
+               mlt_producer_seek( producer, position );
        }
        else if ( !strcmp( eof, "pause" ) && total > 0 )
        {
                playlist_entry *entry = this->list[ this->count - 1 ];
                mlt_producer this_producer = mlt_playlist_producer( this );
-               mlt_producer_seek_frame( this_producer, total - 1 );
+               mlt_producer_seek( this_producer, total - 1 - mlt_producer_get_in( this_producer ) );
                producer = entry->producer;
-               position = mlt_producer_frame_position( producer, mlt_producer_get_in( producer ) );
-               mlt_producer_seek_frame( producer, position + entry->frame_out );
+               mlt_producer_seek( producer, entry->frame_out );
                mlt_producer_set_speed( this_producer, 0 );
-               mlt_producer_set_speed( producer, 0 );
        }
        else if ( !strcmp( eof, "loop" ) && total > 0 )
        {
                playlist_entry *entry = this->list[ 0 ];
                mlt_producer this_producer = mlt_playlist_producer( this );
-               mlt_producer_seek_frame( this_producer, 0 );
+               mlt_producer_seek( this_producer, 0 );
                producer = entry->producer;
-               position = entry->frame_in;
-               position += mlt_producer_frame_position( producer, mlt_producer_get_in( producer ) );
-               mlt_producer_seek_frame( producer, position );
+               mlt_producer_seek( producer, entry->frame_in );
        }
        else
        {
-               mlt_producer_seek( mlt_playlist_producer( this ), 0 );
                producer = &this->blank;
        }
 
        return producer;
 }
 
+/** Invoked when a producer indicates that it has prematurely reached its end.
+*/
+
 static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
 {
        // Default producer to blank
        mlt_producer producer = &this->blank;
 
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode pos = mlt_producer_position( &this->parent );
-       int64_t position = mlt_producer_frame_position( &this->parent, pos );
+       mlt_position position = mlt_producer_frame( &this->parent );
 
        // Loop through the virtual playlist
        int i = 0;
@@ -288,9 +288,9 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
        // Seek in real producer to relative position
        if ( i < this->count )
        {
-               // Update the playtime for the changed clip (hmmm)
-               this->list[ i ]->frame_count = position + 1;
-               this->list[ i ]->frame_out = position - this->list[ i ]->frame_in;
+               // Update the frame_count for the changed clip (hmmm)
+               this->list[ i ]->frame_out = position;
+               this->list[ i ]->frame_count = this->list[ i ]->frame_out - this->list[ i ]->frame_in + 1;
 
                // Refresh the playlist
                mlt_playlist_virtual_refresh( this );
@@ -299,11 +299,13 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
        return producer;
 }
 
+/** Obtain the current clips index.
+*/
+
 int mlt_playlist_current_clip( mlt_playlist this )
 {
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode pos = mlt_producer_position( &this->parent );
-       int64_t position = mlt_producer_frame_position( &this->parent, pos );
+       mlt_position position = mlt_producer_frame( &this->parent );
 
        // Loop through the virtual playlist
        int i = 0;
@@ -325,6 +327,9 @@ int mlt_playlist_current_clip( mlt_playlist this )
        return i;
 }
 
+/** Obtain the current clips producer.
+*/
+
 mlt_producer mlt_playlist_current( mlt_playlist this )
 {
        int i = mlt_playlist_current_clip( this );
@@ -334,10 +339,10 @@ mlt_producer mlt_playlist_current( mlt_playlist this )
                return &this->blank;
 }
 
-/** Get the timecode which corresponds to the start of the next clip.
+/** Get the position which corresponds to the start of the next clip.
 */
 
-mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index )
+mlt_position mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index )
 {
        int64_t position = 0;
        int absolute_clip = index;
@@ -365,11 +370,11 @@ mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index
        else if ( absolute_clip > this->count )
                absolute_clip = this->count;
 
-       // Now determine the timecode
+       // Now determine the position
        for ( i = 0; i < absolute_clip; i ++ )
                position += this->list[ i ]->frame_count;
 
-       return mlt_producer_time( &this->parent, position );
+       return position;
 }
 
 int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index )
@@ -384,10 +389,8 @@ int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info,
                info->start = mlt_playlist_clip( this, mlt_whence_relative_start, index );
                info->resource = mlt_properties_get( properties, "resource" );
                info->frame_in = this->list[ index ]->frame_in;
-               info->in = mlt_producer_time( producer, info->frame_in );
                info->frame_out = this->list[ index ]->frame_out;
-               info->out = mlt_producer_time( producer, info->frame_out );
-               info->playtime = this->list[ index ]->playtime;
+               info->frame_count = this->list[ index ]->frame_count;
                info->length = mlt_producer_get_length( producer );
                info->fps = mlt_producer_get_fps( producer );
        }
@@ -418,43 +421,34 @@ int mlt_playlist_clear( mlt_playlist this )
 int mlt_playlist_append( mlt_playlist this, mlt_producer producer )
 {
        // Append to virtual list
-       int64_t in = mlt_producer_frame_position( producer, mlt_producer_get_in( producer ) );
-       int64_t out = mlt_producer_frame_position( producer, mlt_producer_get_out( producer ) );
-       return mlt_playlist_virtual_append( this, producer, 0, out - in );
+       return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) - 1 );
 }
 
 /** Append a producer to the playlist with in/out points.
 */
 
-int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in, double out )
+int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, mlt_position in, mlt_position out )
 {
        // Append to virtual list
        if ( in != -1 && out != -1 )
-       {
-               int64_t fin = mlt_producer_frame_position( producer, in );
-               int64_t fout = mlt_producer_frame_position( producer, out );
-               return mlt_playlist_virtual_append( this, producer, fin, fout );
-       }
+               return mlt_playlist_virtual_append( this, producer, in, out );
        else
-       {
                return mlt_playlist_append( this, producer );
-       }
 }
 
 /** Append a blank to the playlist of a given length.
 */
 
-int mlt_playlist_blank( mlt_playlist this, mlt_timecode length )
+int mlt_playlist_blank( mlt_playlist this, mlt_position length )
 {
        // Append to the virtual list
-       int64_t fout = mlt_producer_frame_position( &this->blank, length );
-       return mlt_playlist_virtual_append( this, &this->blank, 0, fout );
+       return mlt_playlist_virtual_append( this, &this->blank, 0, length );
 }
 
 /** Insert a producer into the playlist.
 */
 
-int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_timecode in, mlt_timecode out )
+int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_position in, mlt_position out )
 {
        return 0;
 }
@@ -469,7 +463,10 @@ int mlt_playlist_move( mlt_playlist this, int from, int to )
        return 0;
 }
 
-int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_timecode in, mlt_timecode out )
+/** Resize the current clip.
+*/
+
+int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_position in, mlt_position out )
 {
        int error = clip < 0 || clip >= this->count;
        if ( error == 0 )
@@ -479,23 +476,19 @@ int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_timecode in, mlt_
 
                if ( in <= -1 )
                        in = 0;
-               if ( out <= -1 || out >= mlt_producer_get_out( producer ) )
-                       out = mlt_producer_get_out( producer );
+               if ( out <= -1 || out >= mlt_producer_get_playtime( producer ) )
+                       out = mlt_producer_get_playtime( producer ) - 1;
 
                if ( out < in )
                {
-                       mlt_timecode t = in;
+                       mlt_position t = in;
                        in = out;
                        out = t;
                }
 
-               int64_t fin = mlt_producer_frame_position( producer, in );
-               int64_t fout = mlt_producer_frame_position( producer, out );
-
-               entry->frame_in = fin;
-               entry->frame_out = fout;
-               entry->frame_count = fout - fin + 1;
-               entry->playtime = out - in;
+               entry->frame_in = in;
+               entry->frame_out = out;
+               entry->frame_count = out - in + 1;
                mlt_playlist_virtual_refresh( this );
        }
        return error;
@@ -529,8 +522,8 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                notifier( argument );
        }
 
-       // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       // Update position on the frame we're creating
+       mlt_frame_set_position( *frame, mlt_producer_frame( producer ) );
 
        // Position ourselves on the next frame
        mlt_producer_prepare_next( producer );
index 8cdcccef8b38a3cd9be648340a3a33a626e50243..dd88959309acc80791bf8895f5b8776c80e4b8ac 100644 (file)
 typedef struct
 {
        mlt_producer producer;
-       mlt_timecode start;
+       mlt_position start;
        char *resource;
-       mlt_timecode in;
-       int64_t frame_in;
-       mlt_timecode out;
-       int64_t frame_out;
-       mlt_timecode playtime;
-       mlt_timecode length;
+       mlt_position frame_in;
+       mlt_position frame_out;
+       mlt_position frame_count;
+       mlt_position length;
        float fps;
 }
 mlt_playlist_clip_info;
@@ -51,16 +49,16 @@ extern mlt_properties mlt_playlist_properties( mlt_playlist this );
 extern int mlt_playlist_count( mlt_playlist this );
 extern int mlt_playlist_clear( mlt_playlist this );
 extern int mlt_playlist_append( mlt_playlist this, mlt_producer producer );
-extern int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in, double out );
-extern int mlt_playlist_blank( mlt_playlist this, mlt_timecode length );
-extern mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index );
+extern int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, mlt_position in, mlt_position out );
+extern int mlt_playlist_blank( mlt_playlist this, mlt_position length );
+extern mlt_position mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index );
 extern int mlt_playlist_current_clip( mlt_playlist this );
 extern mlt_producer mlt_playlist_current( mlt_playlist this );
 extern int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index );
-extern int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_timecode in, mlt_timecode out );
+extern int mlt_playlist_insert( mlt_playlist this, mlt_producer producer, int where, mlt_position in, mlt_position out );
 extern int mlt_playlist_remove( mlt_playlist this, int where );
 extern int mlt_playlist_move( mlt_playlist this, int from, int to );
-extern int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_timecode in, mlt_timecode out );
+extern int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_position in, mlt_position out );
 extern void mlt_playlist_close( mlt_playlist this );
 
 #endif
index 278d9026957b9455183024663a65c405bbfc11b3..c874243548cf7a529cdd95d40ae63accdcc521d4 100644 (file)
@@ -53,14 +53,13 @@ int mlt_producer_init( mlt_producer this, void *child )
 
                // Set the default properties
                mlt_properties_set( properties, "mlt_type", "mlt_producer" );
-               mlt_properties_set_timecode( properties, "position", 0.0 );
+               mlt_properties_set_position( properties, "position", 0.0 );
                mlt_properties_set_double( properties, "frame", 0 );
                mlt_properties_set_double( properties, "fps", 25.0 );
                mlt_properties_set_double( properties, "speed", 1.0 );
-               mlt_properties_set_timecode( properties, "in", 0.0 );
-               mlt_properties_set_timecode( properties, "out", 36000.0 );
-               mlt_properties_set_timecode( properties, "length", 36000.0 );
-               mlt_properties_set_int( properties, "known_length", 1 );
+               mlt_properties_set_position( properties, "in", 0.0 );
+               mlt_properties_set_position( properties, "out", 179999 );
+               mlt_properties_set_position( properties, "length", 180000 );
                mlt_properties_set_double( properties, "aspect_ratio", 4.0 / 3.0 );
                mlt_properties_set( properties, "log_id", "multitrack" );
 
@@ -87,92 +86,64 @@ mlt_properties mlt_producer_properties( mlt_producer this )
        return mlt_service_properties( &this->parent );
 }
 
-/** Convert frame position to timecode.
+/** Convert frame position to position.
 */
 
-mlt_timecode mlt_producer_time( mlt_producer this, int64_t frame )
+/*
+mlt_position mlt_producer_time( mlt_producer this, int64_t frame )
 {
        if ( frame < 0 )
                return -1;
        else
-               return ( mlt_timecode )frame / mlt_producer_get_fps( this );
+               return ( mlt_position )frame / mlt_producer_get_fps( this );
 }
+*/
 
-/** Convert timecode to frame position.
+/** Convert position to frame position.
 */
 
-int64_t mlt_producer_frame_position( mlt_producer this, mlt_timecode position )
+/*
+int64_t mlt_producer_frame_position( mlt_producer this, mlt_position position )
 {
        if ( position < 0 )
                return -1;
        else
                return ( int64_t )( floor( position * mlt_producer_get_fps( this ) + 0.5 ) );
 }
+*/
 
-/** Seek to a specified time code.
+/** Seek to a specified position.
 */
 
-int mlt_producer_seek( mlt_producer this, mlt_timecode timecode )
+int mlt_producer_seek( mlt_producer this, mlt_position position )
 {
        // Check bounds
-       if ( timecode < 0 )
-               timecode = 0;
-       if ( timecode > mlt_producer_get_playtime( this ) )
-               timecode = mlt_producer_get_playtime( this );
+       if ( position < 0 )
+               position = 0;
+       else if ( position > mlt_producer_get_playtime( this ) )
+               position = mlt_producer_get_playtime( this ) - 1;
 
        // Set the position
-       mlt_properties_set_timecode( mlt_producer_properties( this ), "position", timecode );
+       mlt_properties_set_position( mlt_producer_properties( this ), "position", position );
 
        // Calculate the absolute frame
-       double frame = ( mlt_producer_get_in( this ) + timecode ) * mlt_producer_get_fps( this );
-       mlt_properties_set_double( mlt_producer_properties( this ), "frame", floor( frame + 0.5 ) );
-
-       return 0;
-}
-
-/** Seek to a specified absolute frame.
-*/
-
-int mlt_producer_seek_frame( mlt_producer this, int64_t frame )
-{
-       // Calculate the time code
-       double timecode = ( frame / mlt_producer_get_fps( this ) ) - mlt_producer_get_in( this );
-
-       // If timecode is invalid, then seek on time
-       if ( frame < 0 || timecode < 0 )
-       {
-               // Seek to the in point
-               mlt_producer_seek( this, 0 );
-       }
-       else if ( timecode > mlt_producer_get_playtime( this ) )
-       {
-               // Seek to the out point
-               mlt_producer_seek( this, mlt_producer_get_playtime( this ) );
-       }
-       else
-       {
-               // Set the position
-               mlt_properties_set_timecode( mlt_producer_properties( this ), "position", timecode );
-
-               // Set the absolute frame
-               mlt_properties_set_double( mlt_producer_properties( this ), "frame", frame );
-       }
+       mlt_properties_set_position( mlt_producer_properties( this ), "frame", mlt_producer_get_in( this ) + position );
 
        return 0;
 }
 
-/** Get the current time code.
+/** Get the current position (relative to in point).
 */
 
-mlt_timecode mlt_producer_position( mlt_producer this )
+mlt_position mlt_producer_position( mlt_producer this )
 {
-       return mlt_properties_get_timecode( mlt_producer_properties( this ), "position" );
+       return mlt_properties_get_position( mlt_producer_properties( this ), "position" );
 }
 
-/** Get the current frame.
+/** Get the current position (relative to start of producer).
 */
 
-uint64_t mlt_producer_frame( mlt_producer this )
+mlt_position mlt_producer_frame( mlt_producer this )
 {
        return mlt_properties_get_double( mlt_producer_properties( this ), "frame" );
 }
@@ -204,32 +175,30 @@ double mlt_producer_get_fps( mlt_producer this )
 /** Set the in and out points.
 */
 
-int mlt_producer_set_in_and_out( mlt_producer this, mlt_timecode in, mlt_timecode out )
+int mlt_producer_set_in_and_out( mlt_producer this, mlt_position in, mlt_position out )
 {
        // Correct ins and outs if necessary
        if ( in < 0 )
                in = 0;
-       if ( in > mlt_producer_get_length( this ) )
+       else if ( in > mlt_producer_get_length( this ) )
                in = mlt_producer_get_length( this );
+
        if ( out < 0 )
                out = 0;
-       if ( out > mlt_producer_get_length( this ) )
+       else if ( out > mlt_producer_get_length( this ) )
                out = mlt_producer_get_length( this );
 
        // Swap ins and outs if wrong
        if ( out < in )
        {
-               mlt_timecode t = in;
+               mlt_position t = in;
                in = out;
                out = t;
        }
 
        // Set the values
-       mlt_properties_set_timecode( mlt_producer_properties( this ), "in", in );
-       mlt_properties_set_timecode( mlt_producer_properties( this ), "out", out );
-
-       // Seek to the in point
-       mlt_producer_seek( this, 0 );
+       mlt_properties_set_position( mlt_producer_properties( this ), "in", in );
+       mlt_properties_set_position( mlt_producer_properties( this ), "out", out );
 
        return 0;
 }
@@ -237,33 +206,33 @@ int mlt_producer_set_in_and_out( mlt_producer this, mlt_timecode in, mlt_timecod
 /** Get the in point.
 */
 
-mlt_timecode mlt_producer_get_in( mlt_producer this )
+mlt_position mlt_producer_get_in( mlt_producer this )
 {
-       return mlt_properties_get_timecode( mlt_producer_properties( this ), "in" );
+       return mlt_properties_get_position( mlt_producer_properties( this ), "in" );
 }
 
 /** Get the out point.
 */
 
-mlt_timecode mlt_producer_get_out( mlt_producer this )
+mlt_position mlt_producer_get_out( mlt_producer this )
 {
-       return mlt_properties_get_timecode( mlt_producer_properties( this ), "out" );
+       return mlt_properties_get_position( mlt_producer_properties( this ), "out" );
 }
 
 /** Get the total play time.
 */
 
-mlt_timecode mlt_producer_get_playtime( mlt_producer this )
+mlt_position mlt_producer_get_playtime( mlt_producer this )
 {
-       return mlt_producer_get_out( this ) - mlt_producer_get_in( this );
+       return mlt_producer_get_out( this ) - mlt_producer_get_in( this ) + 1;
 }
 
 /** Get the total length of the producer.
 */
 
-mlt_timecode mlt_producer_get_length( mlt_producer this )
+mlt_position mlt_producer_get_length( mlt_producer this )
 {
-       return mlt_properties_get_timecode( mlt_producer_properties( this ), "length" );
+       return mlt_properties_get_position( mlt_producer_properties( this ), "length" );
 }
 
 /** Prepare for next frame.
@@ -271,7 +240,7 @@ mlt_timecode mlt_producer_get_length( mlt_producer this )
 
 void mlt_producer_prepare_next( mlt_producer this )
 {
-       mlt_producer_seek_frame( this, mlt_producer_frame( this ) + mlt_producer_get_speed( this ) );
+       mlt_producer_seek( this, mlt_producer_frame( this ) + mlt_producer_get_speed( this ) );
 }
 
 /** Get a frame.
@@ -287,26 +256,24 @@ static int producer_get_frame( mlt_service service, mlt_frame_ptr frame, int ind
        {
                // Get the frame from the implementation
                result = this->get_frame( this, frame, index );
-
-               mlt_properties frame_properties = mlt_frame_properties( *frame );
-               double speed = mlt_producer_get_speed( this );
-               mlt_properties_set_double( frame_properties, "speed", speed );
        }
        else
        {
                // Generate a test frame
                *frame = mlt_frame_init( );
 
-               // Set the timecode
-               result = mlt_frame_set_timecode( *frame, mlt_producer_position( this ) );
+               // Set the position
+               result = mlt_frame_set_position( *frame, mlt_producer_position( this ) );
 
-               // Calculate the next timecode
+               // Calculate the next position
                mlt_producer_prepare_next( this );
        }
 
-       // Copy the fps of the producer onto the frame
+       // Copy the fps and speed of the producer onto the frame
        mlt_properties properties = mlt_frame_properties( *frame );
        mlt_properties_set_double( properties, "fps", mlt_producer_get_fps( this ) );
+       double speed = mlt_producer_get_speed( this );
+       mlt_properties_set_double( properties, "speed", speed );
 
        return 0;
 }
index 52976524f8fb5e5d840f9c6c7d9ac8a027ff8a69..7e748c0f7b69e0b0c8b18ec042fab2c782ebc279 100644 (file)
@@ -43,23 +43,23 @@ struct mlt_producer_s
 /** Public final methods
 */
 
+//extern double mlt_producer_convert_position_to_time( mlt_producer this, int64_t frame );
+//extern mlt_position mlt_producer_convert_time_to_position( mlt_producer this, double time );
+
 extern int mlt_producer_init( mlt_producer this, void *child );
 extern mlt_service mlt_producer_service( mlt_producer this );
 extern mlt_properties mlt_producer_properties( mlt_producer this );
-extern mlt_timecode mlt_producer_time( mlt_producer this, int64_t frame );
-extern int64_t mlt_producer_frame_position( mlt_producer this, mlt_timecode position );
-extern int mlt_producer_seek( mlt_producer this, mlt_timecode timecode );
-extern int mlt_producer_seek_frame( mlt_producer this, int64_t frame );
-extern mlt_timecode mlt_producer_position( mlt_producer this );
-extern uint64_t mlt_producer_frame( mlt_producer this );
+extern int mlt_producer_seek( mlt_producer this, mlt_position position );
+extern mlt_position mlt_producer_position( mlt_producer this );
+extern mlt_position mlt_producer_frame( mlt_producer this );
 extern int mlt_producer_set_speed( mlt_producer this, double speed );
 extern double mlt_producer_get_speed( mlt_producer this );
 extern double mlt_producer_get_fps( mlt_producer this );
-extern int mlt_producer_set_in_and_out( mlt_producer this, mlt_timecode in, mlt_timecode out );
-extern mlt_timecode mlt_producer_get_in( mlt_producer this );
-extern mlt_timecode mlt_producer_get_out( mlt_producer this );
-extern mlt_timecode mlt_producer_get_playtime( mlt_producer this );
-extern mlt_timecode mlt_producer_get_length( mlt_producer this );
+extern int mlt_producer_set_in_and_out( mlt_producer this, mlt_position in, mlt_position out );
+extern mlt_position mlt_producer_get_in( mlt_producer this );
+extern mlt_position mlt_producer_get_out( mlt_producer this );
+extern mlt_position mlt_producer_get_playtime( mlt_producer this );
+extern mlt_position mlt_producer_get_length( mlt_producer this );
 extern void mlt_producer_prepare_next( mlt_producer this );
 extern void mlt_producer_close( mlt_producer this );
 
index 679d97ad06f701ad8471478f01891b9ca581bd9f..d047da0c2ae503d23fd2c32d64695ca5e3e6717b 100644 (file)
@@ -285,16 +285,16 @@ int mlt_properties_set_double( mlt_properties this, char *name, double value )
 /** Get a value associated to the name.
 */
 
-mlt_timecode mlt_properties_get_timecode( mlt_properties this, char *name )
+mlt_position mlt_properties_get_position( mlt_properties this, char *name )
 {
        mlt_property value = mlt_properties_find( this, name );
-       return value == NULL ? 0 : mlt_property_get_timecode( value );
+       return value == NULL ? 0 : mlt_property_get_position( value );
 }
 
 /** Set a value associated to the name.
 */
 
-int mlt_properties_set_timecode( mlt_properties this, char *name, mlt_timecode value )
+int mlt_properties_set_position( mlt_properties this, char *name, mlt_position value )
 {
        int error = 1;
 
@@ -303,7 +303,7 @@ int mlt_properties_set_timecode( mlt_properties this, char *name, mlt_timecode v
 
        // Set it if not NULL
        if ( property != NULL )
-               error = mlt_property_set_timecode( property, value );
+               error = mlt_property_set_position( property, value );
 
        return error;
 }
index 540b7aec540a500486921e1905c18b1926367219..2cacc9f8d5bf07538c5fae040e3a013b9c85e470 100644 (file)
@@ -48,8 +48,8 @@ extern int mlt_properties_get_int( mlt_properties this, char *name );
 extern int mlt_properties_set_int( mlt_properties this, char *name, int value );
 extern double mlt_properties_get_double( mlt_properties this, char *name );
 extern int mlt_properties_set_double( mlt_properties this, char *name, double value );
-extern mlt_timecode mlt_properties_get_timecode( mlt_properties this, char *name );
-extern int mlt_properties_set_timecode( mlt_properties this, char *name, mlt_timecode value );
+extern mlt_position mlt_properties_get_position( mlt_properties this, char *name );
+extern int mlt_properties_set_position( mlt_properties this, char *name, mlt_position value );
 extern int mlt_properties_set_data( mlt_properties this, char *name, void *value, int length, mlt_destructor, mlt_serialiser );
 extern void *mlt_properties_get_data( mlt_properties this, char *name, int *length );
 extern int mlt_properties_count( mlt_properties this );
index f471b180eda698132dbf073300d63ed2597991e9..0a475299d34855770d8a8fdb32eac6fd127a5dba 100644 (file)
@@ -73,14 +73,14 @@ int mlt_property_set_double( mlt_property this, double value )
        return 0;
 }
 
-/** Set a timecode on this property.
+/** Set a position on this property.
 */
 
-int mlt_property_set_timecode( mlt_property this, mlt_timecode value )
+int mlt_property_set_position( mlt_property this, mlt_position value )
 {
        mlt_property_clear( this );
-       this->types = mlt_prop_timecode;
-       this->prop_timecode = value;
+       this->types = mlt_prop_position;
+       this->prop_position = value;
        return 0;
 }
 
@@ -132,8 +132,8 @@ int mlt_property_get_int( mlt_property this )
                return this->prop_int;
        else if ( this->types & mlt_prop_double )
                return ( int )this->prop_double;
-       else if ( this->types & mlt_prop_timecode )
-               return ( int )this->prop_timecode;
+       else if ( this->types & mlt_prop_position )
+               return ( int )this->prop_position;
        else if ( this->types & mlt_prop_int64 )
                return ( int )this->prop_int64;
        else if ( this->types & mlt_prop_string )
@@ -150,8 +150,8 @@ double mlt_property_get_double( mlt_property this )
                return this->prop_double;
        else if ( this->types & mlt_prop_int )
                return ( double )this->prop_int;
-       else if ( this->types & mlt_prop_timecode )
-               return ( double )this->prop_timecode;
+       else if ( this->types & mlt_prop_position )
+               return ( double )this->prop_position;
        else if ( this->types & mlt_prop_int64 )
                return ( double )this->prop_int64;
        else if ( this->types & mlt_prop_string )
@@ -159,21 +159,21 @@ double mlt_property_get_double( mlt_property this )
        return 0;
 }
 
-/** Get a timecode from this property.
+/** Get a position from this property.
 */
 
-mlt_timecode mlt_property_get_timecode( mlt_property this )
+mlt_position mlt_property_get_position( mlt_property this )
 {
-       if ( this->types & mlt_prop_timecode )
-               return this->prop_timecode;
+       if ( this->types & mlt_prop_position )
+               return this->prop_position;
        else if ( this->types & mlt_prop_int )
-               return ( mlt_timecode )this->prop_int;
+               return ( mlt_position )this->prop_int;
        else if ( this->types & mlt_prop_double )
-               return ( mlt_timecode )this->prop_double;
+               return ( mlt_position )this->prop_double;
        else if ( this->types & mlt_prop_int64 )
-               return ( mlt_timecode )this->prop_int64;
+               return ( mlt_position )this->prop_int64;
        else if ( this->types & mlt_prop_string )
-               return ( mlt_timecode )atof( this->prop_string );
+               return ( mlt_position )atol( this->prop_string );
        return 0;
 }
 
@@ -188,10 +188,10 @@ int64_t mlt_property_get_int64( mlt_property this )
                return ( int64_t )this->prop_int;
        else if ( this->types & mlt_prop_double )
                return ( int64_t )this->prop_double;
-       else if ( this->types & mlt_prop_timecode )
-               return ( int64_t )this->prop_timecode;
+       else if ( this->types & mlt_prop_position )
+               return ( int64_t )this->prop_position;
        else if ( this->types & mlt_prop_string )
-               return ( int64_t )atof( this->prop_string );
+               return ( int64_t )atol( this->prop_string );
        return 0;
 }
 
@@ -215,11 +215,11 @@ char *mlt_property_get_string( mlt_property this )
                        this->prop_string = malloc( 32 );
                        sprintf( this->prop_string, "%e", this->prop_double );
                }
-               else if ( this->types & mlt_prop_timecode )
+               else if ( this->types & mlt_prop_position )
                {
                        this->types |= mlt_prop_string;
                        this->prop_string = malloc( 32 );
-                       sprintf( this->prop_string, "%e", this->prop_timecode );
+                       sprintf( this->prop_string, "%lld", this->prop_position );
                }
                else if ( this->types & mlt_prop_int64 )
                {
index 6b0def55d781c7dbf0d50342843a05c1a328aa3c..3f59ad27e630c68b032e73bfd226545f79c9100e 100644 (file)
@@ -31,7 +31,7 @@ typedef enum
        mlt_prop_none = 0,
        mlt_prop_int = 1,
        mlt_prop_string = 2,
-       mlt_prop_timecode = 4,
+       mlt_prop_position = 4,
        mlt_prop_double = 8,
        mlt_prop_data = 16,
        mlt_prop_int64 = 32
@@ -48,7 +48,7 @@ typedef struct mlt_property_s
 
        // Atomic type handling
        int prop_int;
-       mlt_timecode prop_timecode;
+       mlt_position prop_position;
        double prop_double;
        int64_t prop_int64;
 
@@ -70,13 +70,13 @@ extern mlt_property mlt_property_init( );
 extern void mlt_property_clear( mlt_property this );
 extern int mlt_property_set_int( mlt_property this, int value );
 extern int mlt_property_set_double( mlt_property this, double value );
-extern int mlt_property_set_timecode( mlt_property this, mlt_timecode value );
+extern int mlt_property_set_position( mlt_property this, mlt_position value );
 extern int mlt_property_set_uint64( mlt_property this, uint64_t value );
 extern int mlt_property_set_string( mlt_property this, char *value );
 extern int mlt_property_set_data( mlt_property this, void *value, int length, mlt_destructor destructor, mlt_serialiser serialiser );
 extern int mlt_property_get_int( mlt_property this );
 extern double mlt_property_get_double( mlt_property this );
-extern mlt_timecode mlt_property_get_timecode( mlt_property this );
+extern mlt_position mlt_property_get_position( mlt_property this );
 extern int64_t mlt_property_get_int64( mlt_property this );
 extern char *mlt_property_get_string( mlt_property this );
 extern void *mlt_property_get_data( mlt_property this, int *length );
index f4b77c460c98a4e85c88859b896fe992478a9e47..6c02230f2548e5a9d4cf79ae141f3086ba0b112e 100644 (file)
@@ -22,6 +22,7 @@
 
 #include "mlt_tractor.h"
 #include "mlt_frame.h"
+#include "mlt_multitrack.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 
 struct mlt_tractor_s
 {
-       struct mlt_service_s parent;
+       struct mlt_producer_s parent;
        mlt_service producer;
 };
 
 /** Forward references to static methods.
 */
 
-static int service_get_frame( mlt_service this, mlt_frame_ptr frame, int track );
+static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int track );
 
 /** Constructor for the tractor.
 
@@ -50,10 +51,10 @@ mlt_tractor mlt_tractor_init( )
        mlt_tractor this = calloc( sizeof( struct mlt_tractor_s ), 1 );
        if ( this != NULL )
        {
-               mlt_service service = &this->parent;
-               if ( mlt_service_init( service, this ) == 0 )
+               mlt_producer producer = &this->parent;
+               if ( mlt_producer_init( producer, this ) == 0 )
                {
-                       service->get_frame = service_get_frame;
+                       producer->get_frame = producer_get_frame;
                }
                else
                {
@@ -68,22 +69,36 @@ mlt_tractor mlt_tractor_init( )
 */
 
 mlt_service mlt_tractor_service( mlt_tractor this )
+{
+       return mlt_producer_service( &this->parent );
+}
+
+/** Get the producer object associated to the tractor.
+*/
+
+mlt_producer mlt_tractor_producer( mlt_tractor this )
 {
        return &this->parent;
 }
 
+/** Get the properties object associated to the tractor.
+*/
+
+mlt_properties mlt_tractor_properties( mlt_tractor this )
+{
+       return mlt_producer_properties( &this->parent );
+}
+
 /** Connect the tractor.
 */
 
 int mlt_tractor_connect( mlt_tractor this, mlt_service producer )
 {
-       int ret = mlt_service_connect_producer( &this->parent, producer, 0 );
+       int ret = mlt_service_connect_producer( mlt_tractor_service( this ), producer, 0 );
 
+       // This is the producer we're going to connect to
        if ( ret == 0 )
-       {
-               // This is the producer we're going to connect to
                this->producer = producer;
-       }
 
        return ret;
 }
@@ -93,7 +108,7 @@ int mlt_tractor_connect( mlt_tractor this, mlt_service producer )
        TODO: This should be reading a pump being populated by the thread...
 */
 
-static int service_get_frame( mlt_service parent, mlt_frame_ptr frame, int track )
+static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int track )
 {
        mlt_tractor this = parent->child;
 
@@ -105,6 +120,25 @@ static int service_get_frame( mlt_service parent, mlt_frame_ptr frame, int track
                int done = 0;
                mlt_frame temp;
 
+               // Get the properties of the parent producer
+               mlt_properties properties = mlt_producer_properties( parent );
+
+               // Try to obtain the multitrack associated to the tractor
+               mlt_multitrack multitrack = mlt_properties_get_data( properties, "multitrack", NULL );
+
+               // If we don't have one, we're in trouble... 
+               if ( multitrack != NULL )
+               {
+                       mlt_producer target = mlt_multitrack_producer( multitrack );
+                       mlt_producer_seek( target, mlt_producer_frame( parent ) );
+                       mlt_producer_set_speed( target, mlt_producer_get_speed( parent ) );
+                       mlt_producer_set_in_and_out( parent, mlt_producer_get_in( target ), mlt_producer_get_out( target ) );
+               }
+               else
+               {
+                       fprintf( stderr, "tractor without a multitrack!!\n" );
+               }
+
                // Loop through each of the tracks we're harvesting
                for ( i = 0; !done; i ++ )
                {
@@ -133,6 +167,9 @@ static int service_get_frame( mlt_service parent, mlt_frame_ptr frame, int track
                        }
                }
 
+               // Prepare the next frame
+               mlt_producer_prepare_next( parent );
+
                // Indicate our found status
                return 0;
        }
@@ -149,7 +186,7 @@ static int service_get_frame( mlt_service parent, mlt_frame_ptr frame, int track
 
 void mlt_tractor_close( mlt_tractor this )
 {
-       mlt_service_close( &this->parent );
+       mlt_producer_close( &this->parent );
        free( this );
 }
 
index 28a6071b786ea9699ead97cfc7c770620d096932..b6576ecc523179cc85b417f0c559f66530518f74 100644 (file)
@@ -25,6 +25,8 @@
 
 extern mlt_tractor mlt_tractor_init( );
 extern mlt_service mlt_tractor_service( mlt_tractor this );
+extern mlt_producer mlt_tractor_producer( mlt_tractor this );
+extern mlt_properties mlt_tractor_properties( mlt_tractor this );
 extern int mlt_tractor_connect( mlt_tractor this, mlt_service service );
 extern void mlt_tractor_close( mlt_tractor this );
 
index de416a8177b9cc67d4aff8bbf521b47da7a69825..50715501dea486ca2cf0072dedcd33d18bf82bfb 100644 (file)
@@ -46,8 +46,8 @@ int mlt_transition_init( mlt_transition this, void *child )
 
                service->get_frame = transition_get_frame;
 
-               mlt_properties_set_timecode( properties, "in", 0 );
-               mlt_properties_set_timecode( properties, "out", 0 );
+               mlt_properties_set_position( properties, "in", 0 );
+               mlt_properties_set_position( properties, "out", 0 );
                mlt_properties_set_int( properties, "a_track", 0 );
                mlt_properties_set_int( properties, "b_track", 1 );
 
@@ -91,11 +91,11 @@ int mlt_transition_connect( mlt_transition this, mlt_service producer, int a_tra
 /** Set the in and out points.
 */
 
-void mlt_transition_set_in_and_out( mlt_transition this, mlt_timecode in, mlt_timecode out )
+void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_position out )
 {
        mlt_properties properties = mlt_transition_properties( this );
-       mlt_properties_set_timecode( properties, "in", in );
-       mlt_properties_set_timecode( properties, "out", out );
+       mlt_properties_set_position( properties, "in", in );
+       mlt_properties_set_position( properties, "out", out );
 }
 
 /** Get the index of the a track.
@@ -119,19 +119,19 @@ int mlt_transition_get_b_track( mlt_transition this )
 /** Get the in point.
 */
 
-mlt_timecode mlt_transition_get_in( mlt_transition this )
+mlt_position mlt_transition_get_in( mlt_transition this )
 {
        mlt_properties properties = mlt_transition_properties( this );
-       return mlt_properties_get_timecode( properties, "in" );
+       return mlt_properties_get_position( properties, "in" );
 }
 
 /** Get the out point.
 */
 
-mlt_timecode mlt_transition_get_out( mlt_transition this )
+mlt_position mlt_transition_get_out( mlt_transition this )
 {
        mlt_properties properties = mlt_transition_properties( this );
-       return mlt_properties_get_timecode( properties, "out" );
+       return mlt_properties_get_position( properties, "out" );
 }
 
 /** Process the frame.
@@ -183,8 +183,8 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i
 
        int a_track = mlt_properties_get_int( properties, "a_track" );
        int b_track = mlt_properties_get_int( properties, "b_track" );
-       mlt_timecode in = mlt_properties_get_timecode( properties, "in" );
-       mlt_timecode out = mlt_properties_get_timecode( properties, "out" );
+       mlt_position in = mlt_properties_get_position( properties, "in" );
+       mlt_position out = mlt_properties_get_position( properties, "out" );
 
        // Fetch a and b frames together...
        if ( ( index == a_track || index == b_track ) &&
@@ -198,8 +198,8 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i
        if ( index == a_track )
        {
                // Determine if we're in the right time zone
-               mlt_timecode timecode = mlt_frame_get_timecode( this->a_frame );
-               if ( timecode >= in && timecode < out )
+               mlt_position position = mlt_frame_get_position( this->a_frame );
+               if ( position >= in && position < out )
                {
                        // Process the transition
                        *frame = transition_process( this, this->a_frame, this->b_frame );
@@ -225,8 +225,8 @@ static int transition_get_frame( mlt_service service, mlt_frame_ptr frame, int i
                }
                else
                {
-                       mlt_timecode timecode = mlt_frame_get_timecode( this->b_frame );
-                       if ( timecode >= in && timecode < out )
+                       mlt_position position = mlt_frame_get_position( this->b_frame );
+                       if ( position >= in && position < out )
                        {
                                // We're in the zone, but the 'a frame' has not been requested yet
                                *frame = mlt_frame_init( );
index 7ac765c33a721580f000e615a1c4d8e4e04f3205..c297bdbcdbbd1ab7888bda34cdcad860a4030e79 100644 (file)
@@ -55,11 +55,11 @@ extern int mlt_transition_init( mlt_transition this, void *child );
 extern mlt_service mlt_transition_service( mlt_transition this );
 extern mlt_properties mlt_transition_properties( mlt_transition this );
 extern int mlt_transition_connect( mlt_transition this, mlt_service producer, int a_track, int b_track );
-extern void mlt_transition_set_in_and_out( mlt_transition this, mlt_timecode in, mlt_timecode out );
+extern void mlt_transition_set_in_and_out( mlt_transition this, mlt_position in, mlt_position out );
 extern int mlt_transition_get_a_track( mlt_transition this );
 extern int mlt_transition_get_b_track( mlt_transition this );
-extern mlt_timecode mlt_transition_get_in( mlt_transition this );
-extern mlt_timecode mlt_transition_get_out( mlt_transition this );
+extern mlt_position mlt_transition_get_in( mlt_transition this );
+extern mlt_position mlt_transition_get_out( mlt_transition this );
 extern void mlt_transition_close( mlt_transition this );
 
 #endif
index b100f18f40fd289cee13d533a055eb35c229fc06..162602f6f1f8ebb8ed68f352deee2435bb2d7161 100644 (file)
@@ -31,7 +31,7 @@ typedef enum
 }
 mlt_whence;
 
-typedef double mlt_timecode;
+typedef int64_t mlt_position;
 typedef struct mlt_frame_s *mlt_frame, **mlt_frame_ptr;
 typedef struct mlt_properties_s *mlt_properties;
 typedef struct mlt_service_s *mlt_service;
index 2dbda0e64850ac2f9021ea2a5ac49d4232d41cc1..fa76e647b44998af6a68177e105c41aa836d7485 100644 (file)
@@ -50,43 +50,57 @@ static void transport_action( mlt_producer producer, char *value )
                        case '9':
                                mlt_producer_set_speed( producer, 10 );
                                break;
+                       case 'd':
+                               if ( multitrack != NULL )
+                               {
+                                       int i = 0;
+                                       mlt_position last = -1;
+                                       for ( i = 0; 1; i ++ )
+                                       {
+                                               mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_start, i );
+                                               if ( time == last )
+                                                       break;
+                                               last = time;
+                                               fprintf( stderr, "%d: %lld\n", i, time );
+                                       }
+                               }
+                               break;
+
                        case 'g':
                                if ( multitrack != NULL )
                                {
-                                       mlt_timecode time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 0 );
+                                       mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 0 );
                                        mlt_producer_seek( producer, time );
                                }
                                break;
                        case 'h':
                                if ( multitrack != NULL )
                                {
-                                       mlt_producer producer = mlt_multitrack_producer( multitrack );
-                                       int64_t position = mlt_producer_frame_position( producer, mlt_producer_position( producer ) );
+                                       mlt_position position = mlt_producer_position( producer );
                                        mlt_producer_set_speed( producer, 0 );
-                                       mlt_producer_seek_frame( producer, position - 1 >= 0 ? position - 1 : 0 );
+                                       mlt_producer_seek( producer, position - 1 >= 0 ? position - 1 : 0 );
                                }
                                break;
                        case 'j':
                                if ( multitrack != NULL )
                                {
-                                       mlt_timecode time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 1 );
+                                       mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 1 );
                                        mlt_producer_seek( producer, time );
                                }
                                break;
                        case 'k':
                                if ( multitrack != NULL )
                                {
-                                       mlt_timecode time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, -1 );
+                                       mlt_position time = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, -1 );
                                        mlt_producer_seek( producer, time );
                                }
                                break;
                        case 'l':
                                if ( multitrack != NULL )
                                {
-                                       mlt_producer producer = mlt_multitrack_producer( multitrack );
-                                       int64_t position = mlt_producer_frame_position( producer, mlt_producer_position( producer ) );
+                                       mlt_position position = mlt_producer_position( producer );
                                        mlt_producer_set_speed( producer, 0 );
-                                       mlt_producer_seek_frame( producer, position + 1 );
+                                       mlt_producer_seek( producer, position + 1 );
                                }
                                break;
                }
index 479ed71355c077ba7c46569683fa1ccc9745c7cd..a1043df4ee1f20888eb0461e94d71a03139cdcc6 100644 (file)
@@ -218,7 +218,6 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response )
        mlt_properties properties = unit->properties;
        int generation = mlt_properties_get_int( properties, "generation" );
        mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
-       mlt_producer producer = mlt_playlist_producer( playlist );
 
        valerie_response_printf( response, 1024, "%d\n", generation );
                
@@ -230,8 +229,8 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response )
                                                                 i, info.resource, 
                                                                 info.frame_in, 
                                                                 info.frame_out,
-                                                                mlt_producer_frame_position( producer, info.playtime )
-                                                                mlt_producer_frame_position( producer, info.length )
+                                                                info.frame_count
+                                                                info.length
                                                                 info.fps );
        }
 }
@@ -257,7 +256,7 @@ valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, int64_t in,
        {
                mlt_properties properties = unit->properties;
                mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
-               mlt_playlist_append_io( playlist, instance, mlt_producer_time( instance, in ), mlt_producer_time( instance, out ) );
+               mlt_playlist_append_io( playlist, instance, in, out );
                miracle_log( LOG_DEBUG, "loaded clip %s", clip );
                miracle_unit_status_communicate( unit );
                return valerie_ok;
@@ -274,7 +273,7 @@ valerie_error_code miracle_unit_insert( miracle_unit unit, char *clip, int index
        {
                mlt_properties properties = unit->properties;
                mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
-               mlt_playlist_insert( playlist, instance, index, mlt_producer_time( instance, in ), mlt_producer_time( instance, out ) );
+               mlt_playlist_insert( playlist, instance, index, in, out );
                miracle_log( LOG_DEBUG, "inserted clip %s at %d", clip, index );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
@@ -330,7 +329,7 @@ valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, int64_t i
        {
                mlt_properties properties = unit->properties;
                mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
-               mlt_playlist_append_io( playlist, instance, mlt_producer_time( instance, in ), mlt_producer_time( instance, out ) );
+               mlt_playlist_append_io( playlist, instance, in, out );
                miracle_log( LOG_DEBUG, "appended clip %s", clip );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
@@ -424,13 +423,13 @@ int miracle_unit_get_status( miracle_unit unit, valerie_status status )
                        status->fps = mlt_producer_get_fps( producer );
                        status->in = info.frame_in;
                        status->out = info.frame_out;
-                       status->position = mlt_producer_frame_position( producer, mlt_producer_position( clip ) );
-                       status->length = mlt_producer_frame_position( producer, mlt_producer_get_length( clip ) );
+                       status->position = mlt_producer_position( clip );
+                       status->length = mlt_producer_get_length( clip );
                        strncpy( status->tail_clip, info.resource, sizeof( status->tail_clip ) );
                        status->tail_in = info.frame_in;
                        status->tail_out = info.frame_out;
-                       status->tail_position = mlt_producer_frame_position( producer, mlt_producer_position( clip ) );
-                       status->tail_length = mlt_producer_frame_position( producer, mlt_producer_get_length( clip ) );
+                       status->tail_position = mlt_producer_position( clip );
+                       status->tail_length = mlt_producer_get_length( clip );
                        status->clip_index = mlt_playlist_current_clip( playlist );
                        status->seek_flag = 1;
                }
@@ -477,7 +476,7 @@ void miracle_unit_change_position( miracle_unit unit, int clip, int64_t position
 
        if ( mlt_playlist_get_clip_info( playlist, &info, clip ) == 0 )
        {
-               int64_t frame_start = mlt_producer_frame_position( info.producer, info.start );
+               int64_t frame_start = info.start;
                int64_t frame_offset = position;
 
                if ( frame_offset < 0 )
@@ -487,7 +486,7 @@ void miracle_unit_change_position( miracle_unit unit, int clip, int64_t position
                if ( frame_offset >= info.frame_out )
                        frame_offset = info.frame_out;
                
-               mlt_producer_seek_frame( producer, frame_start + frame_offset - info.frame_in );
+               mlt_producer_seek( producer, frame_start + frame_offset - info.frame_in );
        }
 
        miracle_unit_status_communicate( unit );
@@ -516,8 +515,8 @@ int miracle_unit_set_clip_in( miracle_unit unit, int index, int64_t position )
 
        if ( error == 0 )
        {
-               mlt_timecode in = mlt_producer_time( info.producer, position );
-               error = mlt_playlist_resize_clip( playlist, index, in, info.out );
+               miracle_unit_play( unit, 0 );
+               error = mlt_playlist_resize_clip( playlist, index, position, info.frame_out );
                update_generation( unit );
                miracle_unit_change_position( unit, index, 0 );
        }
@@ -537,8 +536,8 @@ int miracle_unit_set_clip_out( miracle_unit unit, int index, int64_t position )
 
        if ( error == 0 )
        {
-               mlt_timecode out = mlt_producer_time( info.producer, position );
-               error = mlt_playlist_resize_clip( playlist, index, info.in, out );
+               miracle_unit_play( unit, 0 );
+               error = mlt_playlist_resize_clip( playlist, index, info.frame_in, position );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
                miracle_unit_change_position( unit, index, -1 );
@@ -555,8 +554,8 @@ void miracle_unit_step( miracle_unit unit, int64_t offset )
        mlt_properties properties = unit->properties;
        mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL );
        mlt_producer producer = mlt_playlist_producer( playlist );
-       mlt_timecode position = mlt_producer_position( producer );
-       mlt_producer_seek_frame( producer, mlt_producer_frame_position( producer, position ) + offset );
+       mlt_position position = mlt_producer_frame( producer );
+       mlt_producer_seek( producer, position + offset );
 }
 
 /** Set the unit's clip mode regarding in and out points.
index b508654bc09af3b29979562020bf87b51704c684..c929d2572e7dc7de4dcb512297bfcb712755a68a 100644 (file)
@@ -249,7 +249,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        ( *frame )->get_audio = producer_get_audio;
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
        // Calculate the next timecode
        mlt_producer_prepare_next( producer );
index 7bcdfa9fbcdd80a3126c63d72ec58a5393bb28b5..c2ba62dd862a08e761f2c8dca7b00622eb219066 100644 (file)
@@ -44,32 +44,42 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form
        // Get the b frame from the stack
        mlt_frame b_frame = mlt_frame_pop_frame( this );
 
-       // Get the properties of the b frame
-       mlt_properties b_props = mlt_frame_properties( b_frame );
-
-       // Arbitrary composite defaults
-       int x = 0;
-       int y = 0;
-       double mix = 1.0;
-
-       // Override from b frame properties if provided
-       if ( mlt_properties_get( b_props, "x" ) != NULL )
-               x = mlt_properties_get_int( b_props, "x" );
-       if ( mlt_properties_get( b_props, "y" ) != NULL )
-               y = mlt_properties_get_int( b_props, "y" );
-       if ( mlt_properties_get( b_props, "mix" ) != NULL )
-               mix = mlt_properties_get_double( b_props, "mix" );
-
-       // Composite the b_frame on the a_frame
-       mlt_frame_composite_yuv( this, b_frame, x, y, mix );
-
-       // Extract the a_frame image info
-       *width = mlt_properties_get_int( a_props, "width" );
-       *height = mlt_properties_get_int( a_props, "height" );
-       *image = mlt_properties_get_data( a_props, "image", NULL );
-
-       // Close the b_frame
-       mlt_frame_close( b_frame );
+       if ( b_frame != NULL )
+       {
+               // Get the properties of the b frame
+               mlt_properties b_props = mlt_frame_properties( b_frame );
+
+               // Arbitrary composite defaults
+               int x = 0;
+               int y = 0;
+               double mix = 1.0;
+
+               // Override from b frame properties if provided
+               if ( mlt_properties_get( b_props, "x" ) != NULL )
+                       x = mlt_properties_get_int( b_props, "x" );
+               if ( mlt_properties_get( b_props, "y" ) != NULL )
+                       y = mlt_properties_get_int( b_props, "y" );
+               if ( mlt_properties_get( b_props, "mix" ) != NULL )
+                       mix = mlt_properties_get_double( b_props, "mix" );
+
+               // Composite the b_frame on the a_frame
+               mlt_frame_composite_yuv( this, b_frame, x, y, mix );
+
+               // Extract the a_frame image info
+               *width = mlt_properties_get_int( a_props, "width" );
+               *height = mlt_properties_get_int( a_props, "height" );
+               *image = mlt_properties_get_data( a_props, "image", NULL );
+
+               // Close the b_frame
+               mlt_frame_close( b_frame );
+       }
+       else if ( a_props != NULL )
+       {
+               // Extract the a_frame image info
+               *width = mlt_properties_get_int( a_props, "width" );
+               *height = mlt_properties_get_int( a_props, "height" );
+               *image = mlt_properties_get_data( a_props, "image", NULL );
+       }
 
        return 0;
 }
index a3ae3dc7796090a8a392a16966a139da226125f1..71c823805092b1b6d77fb49c951bf1ee2e80eeff 100644 (file)
@@ -339,9 +339,9 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram
        }
 
        // Determine the time position of this frame in the transition duration
-       mlt_timecode in = mlt_transition_get_in( transition );
-       mlt_timecode out = mlt_transition_get_out( transition );
-       mlt_timecode time = mlt_frame_get_timecode( b_frame );
+       mlt_position in = mlt_transition_get_in( transition );
+       mlt_position out = mlt_transition_get_out( transition );
+       mlt_position time = mlt_frame_get_position( b_frame );
        double pos = ( time - in ) / ( out - in );
        
        // Set the b frame properties
index 218f85bcea272672aa19d9ec0854cc8f4a3a89f1..f3aac3ce4402d5c296cfbebb0709204a2fe884e6 100644 (file)
@@ -2,7 +2,8 @@
 TARGET = ../libmltdv.so
 
 OBJS = factory.o \
-          producer_libdv.o 
+          producer_libdv.o \
+          consumer_libdv.o
 
 CFLAGS = -I../../ -Wall -g -D_FILE_OFFSET_BITS=64 -pthread
 
index 876897c2b907fe6d733b92a7b459897020fda75b..94532672a283d7b6d9265ad60964c2ef78bbf3b7 100755 (executable)
@@ -7,5 +7,9 @@ cat << EOF >> ../producers.dat
 libdv                  libmltdv.so
 EOF
 
+cat << EOF >> ../consumers.dat
+libdv                  libmltdv.so
+EOF
+
 fi
 
diff --git a/src/modules/dv/consumer_libdv.c b/src/modules/dv/consumer_libdv.c
new file mode 100644 (file)
index 0000000..07bd6e6
--- /dev/null
@@ -0,0 +1,329 @@
+/*
+ * producer_libdv.c -- a DV encoder based on libdv
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+// Local header files
+#include "consumer_libdv.h"
+
+// mlt Header files
+#include <framework/mlt_frame.h>
+
+// System header files
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+// libdv header files
+#include <libdv/dv.h>
+
+// Forward references.
+static int consumer_encode_video( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame );
+static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame );
+static void consumer_output( mlt_consumer this, uint8_t *dv_frame, int size, mlt_frame frame );
+static void *consumer_thread( void *arg );
+static void consumer_close( mlt_consumer this );
+
+/** Initialise the dv consumer.
+*/
+
+mlt_consumer consumer_libdv_init( char *arg )
+{
+       // Allocate the consumer
+       mlt_consumer this = calloc( 1, sizeof( struct mlt_consumer_s ) );
+
+       // If memory allocated and initialises without error
+       if ( this != NULL && mlt_consumer_init( this, NULL ) == 0 )
+       {
+               // Get properties from the consumer
+               mlt_properties properties = mlt_consumer_properties( this );
+
+               // Allocate a thread
+               pthread_t *thread = calloc( 1, sizeof( pthread_t ) );
+
+               // Assign close callback
+               this->close = consumer_close;
+
+               // Assign all properties
+               if ( arg == NULL || !strcmp( arg, "PAL" ) )
+                       mlt_properties_set_double( properties, "fps", 25 );
+               else
+                       mlt_properties_set_double( properties, "fps", 29.97 );
+
+               mlt_properties_set_data( properties, "thread", thread, sizeof( pthread_t ), free, NULL );
+               mlt_properties_set_data( properties, "video", consumer_encode_video, 0, NULL, NULL );
+               mlt_properties_set_data( properties, "audio", consumer_encode_audio, 0, NULL, NULL );
+               mlt_properties_set_data( properties, "output", consumer_output, 0, NULL, NULL );
+
+               // Create the thread (this should not happen immediately)
+               mlt_properties_set_int( properties, "running", 1 );
+               pthread_create( thread, NULL, consumer_thread, this );
+       }
+       else
+       {
+               // Clean up in case of init failure
+               free( this );
+               this = NULL;
+       }
+
+       // Return this
+       return this;
+}
+
+/** Get or create a new libdv encoder.
+*/
+
+static dv_encoder_t *libdv_get_encoder( mlt_consumer this, mlt_frame frame )
+{
+       // Get the properties of the consumer
+       mlt_properties this_properties = mlt_consumer_properties( this );
+
+       // Obtain the dv_encoder
+       dv_encoder_t *encoder = mlt_properties_get_data( this_properties, "dv_encoder", NULL );
+
+       // Construct one if we don't have one
+       if ( encoder == NULL )
+       {
+               // Get the fps of the consumer (for now - should be from frame)
+               double fps = mlt_properties_get_double( this_properties, "fps" );
+
+               // Create the encoder
+               encoder = dv_encoder_new( fps != 25, 0, 0 );
+
+               // Encoder settings
+               encoder->isPAL = fps = 25;
+               encoder->is16x9 = 0;
+               encoder->vlc_encode_passes = 1;
+               encoder->static_qno = 0;
+               encoder->force_dct = DV_DCT_AUTO;
+
+               // Store the encoder on the properties
+               mlt_properties_set_data( this_properties, "dv_encoder", encoder, 0, ( mlt_destructor )dv_encoder_free, NULL );
+
+               // Convenience for image dimensions
+               mlt_properties_set_int( this_properties, "width", 720 );
+               mlt_properties_set_int( this_properties, "height", fps == 25 ? 576 : 480 );
+       }
+
+       // Return the encoder
+       return encoder;
+}
+
+
+/** The libdv encode video method.
+*/
+
+static int consumer_encode_video( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame )
+{
+       // Obtain the dv_encoder
+       dv_encoder_t *encoder = libdv_get_encoder( this, frame );
+
+       // Get the properties of the consumer
+       mlt_properties this_properties = mlt_consumer_properties( this );
+
+       // This will hold the size of the dv frame
+       int size = 0;
+
+       // If we get an encoder, then encode the image
+       if ( encoder != NULL )
+       {
+               // Specify desired image properties
+               mlt_image_format fmt = mlt_image_yuv422;
+               int width = mlt_properties_get_int( this_properties, "width" );
+               int height = mlt_properties_get_int( this_properties, "height" );
+               uint8_t *image = NULL;
+
+               // Get the image
+               mlt_frame_get_image( frame, &image, &fmt, &width, &height, 0 );
+
+               // Check that we get what we expected
+               if ( fmt != mlt_image_yuv422 || 
+                        width != mlt_properties_get_int( this_properties, "width" ) ||
+                        height != mlt_properties_get_int( this_properties, "height" ) ||
+                        image == NULL )
+               {
+                       // We should try to recover here
+                       fprintf( stderr, "We have a problem houston...\n" );
+               }
+               else
+               {
+                       // Calculate the size of the dv frame
+                       size = height == 576 ? frame_size_625_50 : frame_size_525_60;
+               }
+
+               // Process the frame
+               if ( size != 0 )
+               {
+                       // Encode the image
+                       dv_encode_full_frame( encoder, &image, e_dv_color_yuv, dv_frame );
+               }
+       }
+       
+       return size;
+}
+
+/** The libdv encode audio method.
+*/
+
+static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame )
+{
+       // Get the properties of the consumer
+       mlt_properties this_properties = mlt_consumer_properties( this );
+
+       // Obtain the dv_encoder
+       dv_encoder_t *encoder = libdv_get_encoder( this, frame );
+
+       // Only continue if we have an encoder
+       if ( encoder != NULL )
+       {
+               // Get the frame count
+               int count = mlt_properties_get_int( this_properties, "count" );
+
+               // Default audio args
+               mlt_audio_format fmt = mlt_audio_pcm;
+               int channels = 2;
+               int frequency = 48000;
+               int samples = mlt_sample_calculator( mlt_properties_get_double( this_properties, "fps" ), frequency, count );
+               int16_t *pcm = NULL;
+
+               // Get the frame number
+               time_t start = time( NULL );
+               int height = mlt_properties_get_int( this_properties, "height" );
+               int is_pal = height == 576;
+               int is_wide = 0;
+
+               // Temporary - audio buffer allocation
+               int16_t *audio_buffers[ 4 ];
+               int i = 0;
+               int j = 0;
+               for ( i = 0 ; i < 4; i ++ )
+                       audio_buffers[ i ] = malloc( 2 * DV_AUDIO_MAX_SAMPLES );
+
+               // Get the audio
+               mlt_frame_get_audio( frame, &pcm, &fmt, &frequency, &channels, &samples );
+
+               // Inform the encoder of the number of audio samples
+               encoder->samples_this_frame = samples;
+
+               // Fill the audio buffers correctly
+               for ( i = 0; i < samples; i ++ )
+                       for ( j = 0; j < channels; j++ )
+                               audio_buffers[ j ][ i ] = *pcm ++;
+
+               // Encode audio on frame
+               dv_encode_full_audio( encoder, audio_buffers, channels, frequency, dv_frame );
+
+               // Specify meta data on the frame
+               dv_encode_metadata( dv_frame, is_pal, is_wide, &start, count );
+               dv_encode_timecode( dv_frame, is_pal, count );
+
+               // Update properties
+               mlt_properties_set_int( this_properties, "count", ++ count );
+
+               // Temporary - free audio buffers
+               for ( i = 0 ; i < 4; i ++ )
+                       free( audio_buffers[ i ] );
+       }
+}
+
+/** The libdv output method.
+*/
+
+static void consumer_output( mlt_consumer this, uint8_t *dv_frame, int size, mlt_frame frame )
+{
+       fwrite( dv_frame, size, 1, stdout );
+       fflush( stdout );
+}
+
+/** The main thread - the argument is simply the consumer.
+*/
+
+static void *consumer_thread( void *arg )
+{
+       // Map the argument to the object
+       mlt_consumer this = arg;
+
+       // Get the properties
+       mlt_properties properties = mlt_consumer_properties( this );
+
+       // Get the handling methods
+       int ( *video )( mlt_consumer, uint8_t *, mlt_frame ) = mlt_properties_get_data( properties, "video", NULL );
+       int ( *audio )( mlt_consumer, uint8_t *, mlt_frame ) = mlt_properties_get_data( properties, "audio", NULL );
+       int ( *output )( mlt_consumer, uint8_t *, int, mlt_frame ) = mlt_properties_get_data( properties, "output", NULL );
+
+       // Allocate a single PAL frame for encoding
+       uint8_t *dv_frame = malloc( frame_size_625_50 );
+
+       // Get the service associated to the consumer
+       mlt_service service = mlt_consumer_service( this );
+
+       // Define a frame pointer
+       mlt_frame frame;
+
+       // Loop while running
+       while( mlt_properties_get_int( properties, "running" ) )
+       {
+               // Get the frame
+               if ( mlt_service_get_frame( service, &frame, 0 ) == 0 )
+               {
+                       // Encode the image
+                       int size = video( this, dv_frame, frame );
+
+                       // Encode the audio
+                       if ( size > 0 )
+                               audio( this, dv_frame, frame );
+
+                       // Output the frame
+                       output( this, dv_frame, size, frame );
+
+                       // Close the frame
+                       mlt_frame_close( frame );
+               }
+       }
+
+       // Tidy up
+       free( dv_frame );
+
+       return NULL;
+}
+
+/** Close the consumer.
+*/
+
+static void consumer_close( mlt_consumer this )
+{
+       // Get the properties
+       mlt_properties properties = mlt_consumer_properties( this );
+
+       // Get the thread
+       pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL );
+
+       // Stop the thread
+       mlt_properties_set_int( properties, "running", 0 );
+
+       // Wait for termination
+       pthread_join( *thread, NULL );
+
+       // Close the parent
+       mlt_consumer_close( this );
+
+       // Free the memory
+       free( this );
+}
+
diff --git a/src/modules/dv/consumer_libdv.h b/src/modules/dv/consumer_libdv.h
new file mode 100644 (file)
index 0000000..de7311e
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * producer_libdv.h -- a DV encoder based on libdv
+ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited
+ * Author: Charles Yates <charles.yates@pandora.be>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _CONSUMER_LIBDV_H_
+#define _CONSUMER_LIBDV_H_
+
+#include <framework/mlt_consumer.h>
+
+extern mlt_consumer consumer_libdv_init( char *filename );
+
+#endif
index e27510a2e87f6c1973ab294cf7f6f386c0fc1f40..8d25f70e101ffb96550bf721e86be94aa52915ba 100644 (file)
@@ -21,6 +21,7 @@
 #include <string.h>
 
 #include "producer_libdv.h"
+#include "consumer_libdv.h"
 
 void *mlt_create_producer( char *id, void *arg )
 {
@@ -41,6 +42,8 @@ void *mlt_create_transition( char *id, void *arg )
 
 void *mlt_create_consumer( char *id, void *arg )
 {
+       if ( !strcmp( id, "libdv" ) )
+               return consumer_libdv_init( arg );
        return NULL;
 }
 
index 8c139df6c663884cac83b3e9eda9d7b5e91e4e12..b82a0e66ef2f90e8382f6869b8eec4db5d6355a4 100644 (file)
@@ -130,11 +130,10 @@ static int producer_collect_info( producer_libdv this )
 
                        // Calculate default in/out points
                        double fps = this->is_pal ? 25 : 30000.0 / 1001.0;
-                       mlt_timecode length = ( mlt_timecode )( this->frames_in_file ) / fps;
                        mlt_properties_set_double( properties, "fps", fps );
-                       mlt_properties_set_timecode( properties, "length", length );
-                       mlt_properties_set_timecode( properties, "in", 0.0 );
-                       mlt_properties_set_timecode( properties, "out", ( mlt_timecode )( this->frames_in_file - 1 ) / fps );
+                       mlt_properties_set_position( properties, "length", this->frames_in_file );
+                       mlt_properties_set_position( properties, "in", 0 );
+                       mlt_properties_set_position( properties, "out", this->frames_in_file - 1 );
 
                        // Parse the header for meta info
                        dv_parse_header( this->dv_decoder, dv_data );
@@ -307,7 +306,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        }
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
        // Calculate the next timecode
        mlt_producer_prepare_next( producer );
index 652354bb47a6a7d48b4c7d42884d21202591c959..0d678af208ea9720e96eca0499af70f085002eb5 100644 (file)
@@ -47,7 +47,7 @@ static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format
        if ( !mlt_properties_get_int( producer_properties, "end_of_clip" ) )
        {
                // Get the position
-               double position = mlt_properties_get_double( producer_properties, "dub_position" );
+               mlt_position position = mlt_properties_get_position( producer_properties, "dub_position" );
 
                // We need a frame from the producer
                mlt_frame producer_frame;
@@ -56,7 +56,7 @@ static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format
                mlt_properties_set_double( producer_properties, "fps", mlt_properties_get_double( frame_properties, "fps" ) );
 
                // Seek to the position
-               mlt_producer_seek_frame( producer, ( int64_t )position );
+               mlt_producer_seek( producer, position );
 
                // Get the next frame
                producer->get_frame( producer, &producer_frame, 0 );
@@ -70,7 +70,7 @@ static int filter_get_audio( mlt_frame frame, int16_t **buffer, mlt_audio_format
                        mlt_properties_set_data( frame_properties, "ffmpeg_dub_frame", producer_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
 
                        // Incrment the position
-                       mlt_properties_set_double( producer_properties, "dub_position", position + 1 );
+                       mlt_properties_set_position( producer_properties, "dub_position", position + 1 );
                }
        }
 
@@ -135,7 +135,7 @@ mlt_filter filter_ffmpeg_dub_init( char *file )
        mlt_properties_set_data( properties, "producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL );
 
        // Initialise the audio frame position
-       mlt_properties_set_double( properties, "dub_position", 0 );
+       mlt_properties_set_position( properties, "dub_position", 0 );
 
        return this;
 }
index 9233bb3441879642c86967f178bfc5b69baf733b..f383aff1bc203f04be74dc9fa1121d56337328b3 100644 (file)
@@ -240,7 +240,7 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma
        return 0;
 }
 
-FILE *producer_ffmpeg_run_video( producer_ffmpeg this, mlt_timecode position )
+FILE *producer_ffmpeg_run_video( producer_ffmpeg this, mlt_position position )
 {
        if ( this->video == NULL )
        {
@@ -277,7 +277,7 @@ FILE *producer_ffmpeg_run_video( producer_ffmpeg this, mlt_timecode position )
        return this->video;
 }
 
-FILE *producer_ffmpeg_run_audio( producer_ffmpeg this, mlt_timecode position )
+FILE *producer_ffmpeg_run_audio( producer_ffmpeg this, mlt_position position )
 {
        // Get the producer
        mlt_producer producer = &this->parent;
@@ -530,12 +530,12 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        if ( this->end_of_video && this->end_of_audio )
        {
                mlt_properties_set_int( properties, "end_of_clip", 1 );
-               mlt_properties_set_timecode( producer_properties, "length", mlt_producer_position( &this->parent ) );
+               mlt_properties_set_position( producer_properties, "length", mlt_producer_position( &this->parent ) );
                mlt_producer_set_in_and_out( &this->parent, mlt_producer_get_in( &this->parent ), mlt_producer_position( &this->parent ) );
        }
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
        // Calculate the next timecode
        mlt_producer_prepare_next( producer );
index 752ed4a1241fe84b456c6d4cb20c578650188a0b..2a8d99f45c05b8adf44e628c690ba96963fc5962 100644 (file)
@@ -340,7 +340,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        }
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
        // Calculate the next timecode
        mlt_producer_prepare_next( producer );
index 84ed6e64b09b0a2f0f5c05f98c89aa1f8af98408..04a9e64a66e768b3b4440b3612c9963c5de530af 100644 (file)
@@ -90,7 +90,7 @@ mlt_producer producer_pixbuf_init( char *filename )
                                        gap ++;
                                }
                        } 
-                       mlt_properties_set_timecode( properties, "out", this->count );
+                       mlt_properties_set_position( properties, "out", this->count * 25 );
                }
                else if ( strstr( filename, "/.all." ) != NULL )
                {
@@ -117,7 +117,7 @@ mlt_producer producer_pixbuf_init( char *filename )
                                free( de[ i ] );
                        }
 
-                       mlt_properties_set_timecode( properties, "out", this->count );
+                       mlt_properties_set_position( properties, "out", this->count * 25 );
                        free( de );
                        free( dir_name );
                }
@@ -125,7 +125,7 @@ mlt_producer producer_pixbuf_init( char *filename )
                {
                        this->filenames = realloc( this->filenames, sizeof( char * ) * ( this->count + 1 ) );
                        this->filenames[ this->count ++ ] = strdup( filename );
-                       mlt_properties_set_timecode( properties, "out", 1 );
+                       mlt_properties_set_position( properties, "out", 25 );
                }
 
                // Initialise gobject types
@@ -207,7 +207,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
        int image_idx = ( int )floor( mlt_producer_position( producer ) / ttl ) % this->count;
 
        // Update timecode on the frame we're creating
-       mlt_frame_set_timecode( *frame, mlt_producer_position( producer ) );
+       mlt_frame_set_position( *frame, mlt_producer_position( producer ) );
 
     // optimization for subsequent iterations on single picture
        if ( this->image != NULL && image_idx == this->image_idx )
index 581db3dfa5170661dd37c656e84c7a4d90aa6153..62e02b26dd05aeb3f192c655b4510bd8aded516d 100644 (file)
@@ -241,10 +241,15 @@ mlt_producer producer_inigo_init( char **argv )
                mlt_multitrack_connect( multitrack, mlt_playlist_producer( playlist ), track );
        }
 
-       mlt_properties props = mlt_multitrack_properties( multitrack );
+       mlt_tractor tractor = mlt_field_tractor( field );
+       mlt_producer prod = mlt_tractor_producer( tractor );
+       mlt_properties props = mlt_tractor_properties( tractor );
+       mlt_properties_set_data( props, "multitrack", multitrack, 0, NULL, NULL );
        mlt_properties_set_data( props, "field", field, 0, NULL, NULL );
        mlt_properties_set_data( props, "group", group, 0, NULL, NULL );
+       mlt_producer_set_in_and_out( prod, 0, mlt_producer_get_out( mlt_multitrack_producer( multitrack ) ) );
+       mlt_properties_set_double( props, "fps", mlt_producer_get_fps( mlt_multitrack_producer( multitrack ) ) );
 
-       return mlt_multitrack_producer( multitrack );
+       return mlt_tractor_producer( tractor );
 }
 
index 803e96ee6acd449f0e013b8fdadbf4376fff856f..e56d56c71294fa63bbf87041e2c64a9989f37094 100644 (file)
@@ -529,8 +529,7 @@ static void consumer_close( mlt_consumer parent )
        pthread_mutex_destroy( &this->audio_mutex );
        pthread_cond_destroy( &this->audio_cond );
                
-       // Now clean up the rest (the close = NULL is a bit nasty but needed for now)
-       parent->close = NULL;
+       // Now clean up the rest
        mlt_consumer_close( parent );
 
        // Finally clean up this