]> git.sesse.net Git - mlt/commitdiff
Merge pull request #3 from j-b-m/master
authorDan Dennedy <dan@dennedy.org>
Sun, 24 Jun 2012 16:46:34 +0000 (09:46 -0700)
committerDan Dennedy <dan@dennedy.org>
Sun, 24 Jun 2012 16:46:34 +0000 (09:46 -0700)
QImage module: fix Qt4 detection

16 files changed:
src/framework/mlt_playlist.c
src/framework/mlt_playlist.h
src/mlt++/MltPlaylist.cpp
src/mlt++/MltPlaylist.h
src/modules/avformat/producer_avformat.c
src/modules/core/filter_region.c
src/modules/core/producer_melt.c
src/modules/core/transition_region.c
src/modules/jackrack/consumer_jack.c
src/modules/jackrack/consumer_jack.yml
src/modules/jackrack/filter_jackrack.c
src/modules/rtaudio/consumer_rtaudio.cpp
src/modules/rtaudio/consumer_rtaudio.yml
src/modules/sdl/consumer_sdl_audio.c
src/modules/sdl/consumer_sdl_audio.yml
src/modules/xml/producer_xml.c

index 356b0d79de09543136165e8c1b8adfe05e41980c..324f6aaded096000d7c6db58228bb9f792da3380 100644 (file)
@@ -102,6 +102,23 @@ mlt_playlist mlt_playlist_init( )
        return self;
 }
 
+/** Construct a playlist with a profile.
+ *
+ * Sets the resource property to "<playlist>".
+ * Set the mlt_type to property to "mlt_producer".
+ * \public \memberof mlt_playlist_s
+ * \param profile the profile to use with the profile
+ * \return a new playlist
+ */
+
+mlt_playlist mlt_playlist_new( mlt_profile profile )
+{
+    mlt_playlist self = mlt_playlist_init();
+    if ( self )
+        mlt_properties_set_data( MLT_PLAYLIST_PROPERTIES( self ), "_profile", profile, 0, NULL, NULL );
+    return self;
+}
+
 /** Get the producer associated to this playlist.
  *
  * \public \memberof mlt_playlist_s
@@ -702,15 +719,36 @@ int mlt_playlist_append_io( mlt_playlist self, mlt_producer producer, mlt_positi
  *
  * \public \memberof mlt_playlist_s
  * \param self a playlist
- * \param length the ending time of the blank entry, not its duration
+ * \param out the ending time of the blank entry, not its duration
  * \return true if there was an error
  */
 
-int mlt_playlist_blank( mlt_playlist self, mlt_position length )
+int mlt_playlist_blank( mlt_playlist self, mlt_position out )
 {
        // Append to the virtual list
-       if (length >= 0)
-               return mlt_playlist_virtual_append( self, &self->blank, 0, length );
+       if ( out >= 0 )
+               return mlt_playlist_virtual_append( self, &self->blank, 0, out );
+       else
+               return 1;
+}
+
+/** Append a blank item to the playlist with duration as a time string.
+ *
+ * \public \memberof mlt_playlist_s
+ * \param self a playlist
+ * \param length the duration of the blank entry as a time string
+ * \return true if there was an error
+ */
+
+int mlt_playlist_blank_time( mlt_playlist self, const char* length )
+{
+       if ( self && length )
+       {
+               mlt_properties properties = MLT_PLAYLIST_PROPERTIES( self );
+               mlt_properties_set( properties , "_blank_time", length );
+               mlt_position duration = mlt_properties_get_position( properties, "_blank_time" );
+               return mlt_playlist_blank( self, duration - 1 );
+       }
        else
                return 1;
 }
@@ -1067,7 +1105,7 @@ int mlt_playlist_join( mlt_playlist self, int clip, int count, int merge )
        if ( error == 0 )
        {
                int i = clip;
-               mlt_playlist new_clip = mlt_playlist_init( );
+               mlt_playlist new_clip = mlt_playlist_new( mlt_service_profile( MLT_PLAYLIST_SERVICE(self) ) );
                mlt_events_block( MLT_PLAYLIST_PROPERTIES( self ), self );
                if ( clip + count >= self->count )
                        count = self->count - clip - 1;
index a6364316e943d9e4e4f596a122aadc8455df9495..ee5411b579bace13ad04b941857ce4569f8fbc5f 100644 (file)
@@ -80,6 +80,7 @@ struct mlt_playlist_s
 #define MLT_PLAYLIST_PROPERTIES( playlist )    MLT_SERVICE_PROPERTIES( MLT_PLAYLIST_SERVICE( playlist ) )
 
 extern mlt_playlist mlt_playlist_init( );
+extern mlt_playlist mlt_playlist_new( mlt_profile profile );
 extern mlt_producer mlt_playlist_producer( mlt_playlist self );
 extern mlt_service mlt_playlist_service( mlt_playlist self );
 extern mlt_properties mlt_playlist_properties( mlt_playlist self );
@@ -87,7 +88,8 @@ extern int mlt_playlist_count( mlt_playlist self );
 extern int mlt_playlist_clear( mlt_playlist self );
 extern int mlt_playlist_append( mlt_playlist self, mlt_producer producer );
 extern int mlt_playlist_append_io( mlt_playlist self, mlt_producer producer, mlt_position in, mlt_position out );
-extern int mlt_playlist_blank( mlt_playlist self, mlt_position length );
+extern int mlt_playlist_blank( mlt_playlist self, mlt_position out );
+extern int mlt_playlist_blank_time( mlt_playlist self, const char *length );
 extern mlt_position mlt_playlist_clip( mlt_playlist self, mlt_whence whence, int index );
 extern int mlt_playlist_current_clip( mlt_playlist self );
 extern mlt_producer mlt_playlist_current( mlt_playlist self );
index a13faf35a5e0e1c3b4934139c3818f8767352ef9..557cd7d65d4bef6afe6b35b292e687fe71195f6f 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include "MltPlaylist.h"
 #include "MltTransition.h"
+#include "MltProfile.h"
 using namespace Mlt;
 
 ClipInfo::ClipInfo( ) :
@@ -85,6 +86,12 @@ Playlist::Playlist( ) :
        instance = mlt_playlist_init( );
 }
 
+Playlist::Playlist( Profile& profile ) :
+       instance( NULL )
+{
+       instance = mlt_playlist_new( profile.get_profile() );
+}
+
 Playlist::Playlist( Service &producer ) :
        instance( NULL )
 {
@@ -138,9 +145,14 @@ int Playlist::append( Producer &producer, int in, int out )
        return mlt_playlist_append_io( get_playlist( ), producer.get_producer( ), in, out );
 }
 
-int Playlist::blank( int length )
+int Playlist::blank( int out )
+{
+       return mlt_playlist_blank( get_playlist( ), out );
+}
+
+int Playlist::blank( const char *length )
 {
-       return mlt_playlist_blank( get_playlist( ), length );
+       return mlt_playlist_blank_time( get_playlist( ), length );
 }
 
 int Playlist::clip( mlt_whence whence, int index )
index 1a48503286c0654919a87b4ed0589d7ef0a64fd3..7d0325562e7b48da1957ab4da9a587c13b98528c 100644 (file)
@@ -33,6 +33,7 @@ namespace Mlt
        class Service;
        class Playlist;
        class Transition;
+       class Profile;
 
        class MLTPP_DECLSPEC ClipInfo
        {
@@ -60,6 +61,7 @@ namespace Mlt
                        mlt_playlist instance;
                public:
                        Playlist( );
+                       Playlist( Profile& profile );
                        Playlist( Service &playlist );
                        Playlist( Playlist &playlist );
                        Playlist( mlt_playlist playlist );
@@ -69,7 +71,8 @@ namespace Mlt
                        int count( );
                        int clear( );
                        int append( Producer &producer, int in = -1, int out = -1 );
-                       int blank( int length );
+                       int blank( int out );
+                       int blank( const char *length );
                        int clip( mlt_whence whence, int index );
                        int current_clip( );
                        Producer *current( );
index fc21d02c0b9ec94e96728f0f08d97f9bd59361c7..d3f0884974f41a8be4cd7496a8d736ce44c89d29 100644 (file)
@@ -1548,7 +1548,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form
                        if ( ret >= 0 && pkt.stream_index == self->video_index && pkt.size > 0 )
                        {
                                // Determine time code of the packet
-                               if ( pkt.pts == AV_NOPTS_VALUE )
+                               if ( use_pts && pkt.pts == AV_NOPTS_VALUE )
                                {
                                        self->invalid_pts_counter++;
                                        if ( self->invalid_pts_counter > 20 )
index 8fd8e8d6ab84e78a236e06dd2c58471471c39b04..7ccfe5287681abc2f73f6ce8c8b722df9cc9e12d 100644 (file)
 /** Filter processing.
 */
 
-static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
 {
+       // Get the filter
+       mlt_filter filter = mlt_frame_pop_service( frame );
+
        // Get the properties of the filter
-       mlt_properties properties = MLT_FILTER_PROPERTIES( this );
+       mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
+
+       mlt_service_lock( MLT_FILTER_SERVICE( filter ) );
 
        // Get the region transition
        mlt_transition transition = mlt_properties_get_data( properties, "_transition", NULL );
@@ -42,21 +47,36 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
        if ( transition == NULL )
        {
                // Create the transition
-               mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) );
+               mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) );
                transition = mlt_factory_transition( profile, "region", NULL );
 
                // Register with the filter
                mlt_properties_set_data( properties, "_transition", transition, 0, ( mlt_destructor )mlt_transition_close, NULL );
 
                // Pass a reference to this filter down
-               mlt_properties_set_data( MLT_TRANSITION_PROPERTIES( transition ), "_region_filter", this, 0, NULL, NULL );
+               mlt_properties_set_data( MLT_TRANSITION_PROPERTIES( transition ), "_region_filter", filter, 0, NULL, NULL );
        }
 
+       mlt_service_unlock( MLT_FILTER_SERVICE( filter ) );
+
        // Pass all properties down
-       mlt_properties_pass( MLT_TRANSITION_PROPERTIES( transition ), properties, "" );
+       mlt_properties_inherit( MLT_TRANSITION_PROPERTIES( transition ), properties );
+
+       // Make the frame's position relative to this filter's in point
+       mlt_frame_set_position( frame, mlt_filter_get_position( filter, frame ) );
 
        // Process the frame
-       return mlt_transition_process( transition, frame, NULL );
+       mlt_transition_process( transition, frame, NULL );
+
+       return mlt_frame_get_image( frame, image, format, width, height, writable );
+}
+
+static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+{
+       mlt_frame_push_service( frame, this );
+       mlt_frame_push_get_image( frame, filter_get_image );
+
+       return frame;
 }
 
 /** Constructor for the filter.
@@ -86,4 +106,3 @@ mlt_filter filter_region_init( mlt_profile profile, mlt_service_type type, const
        // Return the filter
        return this;
 }
-
index 3c8368cbd06fb0f9f90dbbc3dd0abb2ab8860dd1..47307f643b2142a847e4f97f0867b84870f5f4fc 100644 (file)
@@ -126,7 +126,7 @@ mlt_producer producer_melt_init( mlt_profile profile, mlt_service_type type, con
        int track = 0;
        mlt_producer producer = NULL;
        mlt_tractor mix = NULL;
-       mlt_playlist playlist = mlt_playlist_init( );
+       mlt_playlist playlist = mlt_playlist_new( profile );
        mlt_properties group = mlt_properties_new( );
        mlt_tractor tractor = mlt_tractor_new( );
        mlt_properties properties = MLT_TRACTOR_PROPERTIES( tractor );
@@ -373,7 +373,11 @@ mlt_producer producer_melt_init( mlt_profile profile, mlt_service_type type, con
                        if ( producer != NULL && !mlt_producer_is_cut( producer ) )
                                mlt_playlist_append( playlist, producer );
                        producer = NULL;
-                       mlt_playlist_blank( playlist, atof( argv[ ++ i ] ) );
+                       if ( strchr( argv[ i + 1 ], ':' ) )
+                               mlt_playlist_blank_time( playlist, argv[ ++ i ] );
+                       else
+                               // support for legacy where plain int is an out point instead of length
+                               mlt_playlist_blank( playlist, atof( argv[ ++ i ] ) );
                }
                else if ( !strcmp( argv[ i ], "-track" ) ||
                                  !strcmp( argv[ i ], "-null-track" ) ||
@@ -391,7 +395,7 @@ mlt_producer producer_melt_init( mlt_profile profile, mlt_service_type type, con
                        {
                                mlt_multitrack_connect( multitrack, MLT_PLAYLIST_PRODUCER( playlist ), track ++ );
                                track_service( field, playlist, ( mlt_destructor )mlt_playlist_close );
-                               playlist = mlt_playlist_init( );
+                               playlist = mlt_playlist_new( profile );
                        }
                        if ( playlist != NULL )
                        {
index 4486d23d0d72eb21fcfbe94bf615a5564a94f92c..6fddfa0c59059e0e5bbd358e9b2f31af6b8990ed 100644 (file)
@@ -27,7 +27,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-static int create_instance( mlt_transition this, char *name, char *value, int count )
+static int create_instance( mlt_transition transition, char *name, char *value, int count )
 {
        // Return from this function
        int error = 0;
@@ -46,14 +46,14 @@ static int create_instance( mlt_transition this, char *name, char *value, int co
                *arg ++ = '\0';
 
        // Create the filter
-       mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) );
+       mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) );
        filter = mlt_factory_filter( profile, type, arg );
 
        // If we have a filter, then initialise and store it
        if ( filter != NULL )
        {
-               // Properties of this
-               mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+               // Properties of transition
+               mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
 
                // String to hold the property name
                char id[ 256 ];
@@ -73,6 +73,7 @@ static int create_instance( mlt_transition this, char *name, char *value, int co
 
                // Pass all the key properties on the filter down
                mlt_properties_pass( MLT_FILTER_PROPERTIES( filter ), properties, key );
+               mlt_properties_pass_list( MLT_FILTER_PROPERTIES( filter ), properties, "in, out, length" );
 
                // Ensure that filter is assigned
                mlt_properties_set_data( properties, id, filter, 0, ( mlt_destructor )mlt_filter_close, NULL );
@@ -90,19 +91,19 @@ static int create_instance( mlt_transition this, char *name, char *value, int co
        return error;
 }
 
-static uint8_t *filter_get_alpha_mask( mlt_frame this )
+static uint8_t *filter_get_alpha_mask( mlt_frame frame )
 {
        uint8_t *alpha = NULL;
 
        // Obtain properties of frame
-       mlt_properties properties = MLT_FRAME_PROPERTIES( this );
+       mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
 
        // Get the shape frame
        mlt_frame shape_frame = mlt_properties_get_data( properties, "shape_frame", NULL );
 
        // Get the width and height of the image
-       int region_width = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "width" );
-       int region_height = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "height" );
+       int region_width = mlt_properties_get_int( properties, "width" );
+       int region_height = mlt_properties_get_int( properties, "height" );
        uint8_t *image = NULL;
        mlt_image_format format = mlt_image_yuv422;
                                        
@@ -112,25 +113,26 @@ static uint8_t *filter_get_alpha_mask( mlt_frame this )
 
        alpha = mlt_frame_get_alpha_mask( shape_frame );
 
+       int size = region_width * region_height;
+       uint8_t *alpha_duplicate = mlt_pool_alloc( size );
+
        // Generate from the Y component of the image if no alpha available
        if ( alpha == NULL )
        {
-               int size = region_width * region_height;
-               uint8_t *p = mlt_pool_alloc( size );
-               alpha = p;
+               alpha = alpha_duplicate;
                while ( size -- )
                {
-                       *p ++ = ( int )( ( ( *image ++ - 16 ) * 299 ) / 255 );
+                       *alpha ++ = ( int )( ( ( *image ++ - 16 ) * 299 ) / 255 );
                        image ++;
                }
-               mlt_frame_set_alpha( this, alpha, region_width * region_height, mlt_pool_release );
        }
        else
        {
-               mlt_frame_set_alpha( this, alpha, region_width * region_height, NULL );
+               memcpy( alpha_duplicate, alpha, size );
        }
+       mlt_frame_set_alpha( frame, alpha_duplicate, region_width * region_height, mlt_pool_release );
 
-       return alpha;
+       return alpha_duplicate;
 }
 
 /** Do it :-).
@@ -145,12 +147,15 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
        mlt_frame b_frame = mlt_frame_pop_frame( frame );
 
        // Get the watermark transition object
-       mlt_transition this = mlt_frame_pop_service( frame );
+       mlt_transition transition = mlt_frame_pop_service( frame );
 
        // Get the properties of the transition
-       mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+       mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
+
+       // Get the properties of the a frame
+       mlt_properties a_props = MLT_FRAME_PROPERTIES( frame );
 
-       mlt_service_lock( MLT_TRANSITION_SERVICE( this ) );
+       mlt_service_lock( MLT_TRANSITION_SERVICE( transition ) );
 
        // Get the composite from the transition
        mlt_transition composite = mlt_properties_get_data( properties, "composite", NULL );
@@ -159,13 +164,13 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
        mlt_filter filter = mlt_properties_get_data( properties, "_filter_0", NULL );
 
        // Get the position
-       mlt_position position = mlt_transition_get_position( this, frame );
+       mlt_position position = mlt_transition_get_position( transition, frame );
 
        // Create a composite if we don't have one
        if ( composite == NULL )
        {
                // Create composite via the factory
-               mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) );
+               mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) );
                composite = mlt_factory_transition( profile, "composite", NULL );
 
                // If we have one
@@ -214,7 +219,7 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                                char *value = mlt_properties_get_value( properties, i );
 
                                // Create an instance
-                               if ( create_instance( this, name, value, count ) == 0 )
+                               if ( create_instance( transition, name, value, count ) == 0 )
                                        count ++;
                        }
                }
@@ -262,8 +267,8 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                }
        }
 
-       mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "width", *width );
-       mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "height", *height );
+       mlt_properties_set_int( a_props, "width", *width );
+       mlt_properties_set_int( a_props, "height", *height );
 
        // Only continue if we have both filter and composite
        if ( composite != NULL )
@@ -288,14 +293,19 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
 
                        // Ensure a destructor
                        char *name = mlt_properties_get( properties, "_unique_id" );
-                       mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), name, b_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
+                       mlt_properties_set_data( a_props, name, b_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
                }
 
+               // Properties of the B frame
+               mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame );
+
                // filter_only prevents copying the alpha channel of the shape to the output frame
                // by compositing filtered frame over itself
                if ( mlt_properties_get_int( properties, "filter_only" ) )
                {
+                       char *name = mlt_properties_get( properties, "_unique_id" );
                        frame = composite_copy_region( composite, b_frame, position );
+                       mlt_properties_set_data( b_props, name, frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
                }
 
                // Make sure the filter is in the correct position
@@ -343,7 +353,7 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                                        resource = "pixbuf:<svg width='100' height='100'><circle cx='50' cy='50' r='50' fill='black'/></svg>";
 
                                // Create the producer
-                               mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( this ) );
+                               mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) );
                                producer = mlt_factory_producer( profile, factory, resource );
 
                                // If we have one
@@ -376,7 +386,7 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                                if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &shape_frame, 0 ) == 0 )
                                {
                                        // Ensure that the shape frame will be closed
-                                       mlt_properties_set_data( MLT_FRAME_PROPERTIES( b_frame ), "shape_frame", shape_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
+                                       mlt_properties_set_data( b_props, "shape_frame", shape_frame, 0, ( mlt_destructor )mlt_frame_close, NULL );
 
                                        // Specify the callback for evaluation
                                        b_frame->get_alpha_mask = filter_get_alpha_mask;
@@ -388,7 +398,7 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
                error = mlt_frame_get_image( frame, image, format, width, height, 0 );
        }
 
-       mlt_service_unlock( MLT_TRANSITION_SERVICE( this ) );
+       mlt_service_unlock( MLT_TRANSITION_SERVICE( transition ) );
 
        return error;
 }
@@ -396,10 +406,10 @@ static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_for
 /** Filter processing.
 */
 
-static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt_frame b_frame )
+static mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame )
 {
        // Push the transition on to the frame
-       mlt_frame_push_service( a_frame, this );
+       mlt_frame_push_service( a_frame, transition );
 
        // Push the b_frame on to the stack
        mlt_frame_push_frame( a_frame, b_frame );
@@ -417,16 +427,16 @@ static mlt_frame transition_process( mlt_transition this, mlt_frame a_frame, mlt
 mlt_transition transition_region_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
 {
        // Create a new transition
-       mlt_transition this = mlt_transition_new( );
+       mlt_transition transition = mlt_transition_new( );
 
        // Further initialisation
-       if ( this != NULL )
+       if ( transition != NULL )
        {
                // Get the properties from the transition
-               mlt_properties properties = MLT_TRANSITION_PROPERTIES( this );
+               mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition );
 
                // Assign the transition process method
-               this->process = transition_process;
+               transition->process = transition_process;
 
                // Default factory
                mlt_properties_set( properties, "factory", mlt_environment( "MLT_PRODUCER" ) );
@@ -439,6 +449,6 @@ mlt_transition transition_region_init( mlt_profile profile, mlt_service_type typ
        }
 
        // Return the transition
-       return this;
+       return transition;
 }
 
index ce18604e88ac703164e9b54e56d12a6cf2e83613..a9e363003561963103c41431a06bf5e0b428ed2d 100644 (file)
@@ -240,6 +240,8 @@ static int jack_process( jack_nframes_t frames, void * data )
                char *dest = jack_port_get_buffer( self->ports[i], frames );
 
                jack_ringbuffer_read( self->ringbuffers[i], dest, ring_size < jack_size ? ring_size : jack_size );
+               if ( ring_size < jack_size )
+                       memset( dest + ring_size, 0, jack_size - ring_size );
        }
 
        return error;
@@ -303,8 +305,10 @@ static int consumer_play_audio( consumer_jack self, mlt_frame frame, int init_au
        mlt_audio_format afmt = mlt_audio_float;
 
        // Set the preferred params of the test card signal
+       double speed = mlt_properties_get_double( MLT_FRAME_PROPERTIES(frame), "_speed" );
        int channels = mlt_properties_get_int( properties, "channels" );
        int frequency = mlt_properties_get_int( properties, "frequency" );
+       int scrub = mlt_properties_get_int( properties, "scrub_audio" );
        int samples = mlt_sample_calculator( mlt_properties_get_double( properties, "fps" ), frequency, self->counter++ );
        float *buffer;
 
@@ -324,12 +328,15 @@ static int consumer_play_audio( consumer_jack self, mlt_frame frame, int init_au
                init_audio = 0;
        }
 
-       if ( init_audio == 0 )
+       if ( init_audio == 0 && ( speed == 1.0 || speed == 0.0 ) )
        {
                int i;
                size_t mlt_size = samples * sizeof(float);
                float volume = mlt_properties_get_double( properties, "volume" );
 
+               if ( !scrub && speed == 0.0 )
+                       volume = 0.0;
+
                if ( volume != 1.0 )
                {
                        float *p = buffer;
index abef3aea569422f2bd757ddc95f6464f20a65650..1d9e48ee91847b8459c7793d69daa0e5657ad4ef 100644 (file)
@@ -15,20 +15,44 @@ parameters:
     type: integer
     minimum: 1
     default: 2
+
   - identifier: out_1
     title: Send L
     type: string
+
   - identifier: out_2
     title: Send R
     type: string
+
   - identifier: volume
     title: Volume
     type: float
     minimum: 0.0
     default: 1.0
+
   - identifier: refresh
     description: >
       Applications should set this to update the video frame when paused.
     type: integer
     minimum: 0
     maximum: 1
+
+  - identifier: audio_off
+    title: Audio off
+    type: integer
+    description: If 1, disable audio output
+    mutable: yes
+    minimum: 0
+    maximum: 1
+    default: 0
+    widget: checkbox
+
+  - identifier: scrub_audio
+    title: Audio scrubbing
+    type: integer
+    description: If enabled, sound is played even when the speed is not normal.
+    mutable: yes
+    minimum: 0
+    maximum: 1
+    default: 0
+    widget: checkbox
index c15d31e82db81f7d892a2a3d98adf0505215a767..08df789e1b34fad4d488634550d2903b63984dd1 100644 (file)
@@ -93,14 +93,14 @@ static int jack_sync( jack_transport_state_t state, jack_position_t *jack_pos, v
 
 static void on_jack_start( mlt_properties owner, mlt_properties properties )
 {
-       fprintf(stderr, "%s\n", __FUNCTION__);
+       mlt_log_verbose( NULL, "%s\n", __FUNCTION__ );
        jack_client_t *jack_client = mlt_properties_get_data( properties, "jack_client", NULL );
        jack_transport_start( jack_client );
 }
 
 static void on_jack_stop( mlt_properties owner, mlt_properties properties )
 {
-       fprintf(stderr, "%s\n", __FUNCTION__);
+       mlt_log_verbose( NULL, "%s\n", __FUNCTION__ );
        jack_client_t *jack_client = mlt_properties_get_data( properties, "jack_client", NULL );
        jack_transport_stop( jack_client );
 }
@@ -108,7 +108,7 @@ static void on_jack_stop( mlt_properties owner, mlt_properties properties )
 static void on_jack_seek( mlt_properties owner, mlt_filter filter, mlt_position *position )
 {
        mlt_properties properties = MLT_FILTER_PROPERTIES( filter );
-
+       mlt_log_verbose( MLT_FILTER_SERVICE(filter), "%s: %d\n", __FUNCTION__, *position );
 
        mlt_properties_set_int( properties, "_sync_guard", 1 );
        mlt_properties_set_position( properties, "_jack_seek", *position );
@@ -120,7 +120,6 @@ static void on_jack_seek( mlt_properties owner, mlt_filter filter, mlt_position
        jack_nframes_t jack_frame = jack_get_sample_rate( jack_client );
        jack_frame *= *position / mlt_profile_fps( profile );
 
-       fprintf(stderr, "%s: %d\n", __FUNCTION__, *position);
        jack_transport_locate( jack_client, jack_frame );
 }
 
@@ -271,6 +270,8 @@ static int jack_process (jack_nframes_t frames, void * data)
                }
                ring_size = jack_ringbuffer_read_space( output_buffers[i] );
                jack_ringbuffer_read( output_buffers[i], ( char * )jack_output_buffers[i], ring_size < jack_size ? ring_size : jack_size );
+               if ( ring_size < jack_size )
+                       memset( &jack_output_buffers[i][ring_size], 0, jack_size - ring_size );
                
                // Return audio through in port
                jack_input_buffers[i] = jack_port_get_buffer( jack_input_ports[i], frames );
index 01f5955407bd4573fabedf26b8d797e1b4e02d1a..8c002125f6a313bcc2e6319e079d7b91417b4b8b 100644 (file)
@@ -389,6 +389,7 @@ public:
                // Set the preferred params of the test card signal
                int channels = mlt_properties_get_int( properties, "channels" );
                int frequency = mlt_properties_get_int( properties, "frequency" );
+               int scrub = mlt_properties_get_int( properties, "scrub_audio" );
                static int counter = 0;
                int samples = mlt_sample_calculator( mlt_properties_get_double( properties, "fps" ), frequency, counter++ );
                int16_t *pcm;
@@ -441,7 +442,7 @@ public:
                                pthread_cond_wait( &audio_cond, &audio_mutex );
                        if ( running )
                        {
-                               if ( mlt_properties_get_double( properties, "_speed" ) == 1 )
+                               if ( scrub || mlt_properties_get_double( properties, "_speed" ) == 1 )
                                        memcpy( &audio_buffer[ audio_avail ], pcm, bytes );
                                else
                                        memset( &audio_buffer[ audio_avail ], 0, bytes );
index 80ded0e1356ce8b5710c6468275c32bf7c71442b..c2b8cb21fcdf542c0c0cb1ad9b80b1feb3a6df4c 100644 (file)
@@ -42,3 +42,13 @@ parameters:
     type: integer
     minimum: 0
     maximum: 1
+
+  - identifier: scrub_audio
+    title: Audio scrubbing
+    type: integer
+    description: If enabled, sound is played even when the speed is not normal.
+    mutable: yes
+    minimum: 0
+    maximum: 1
+    default: 0
+    widget: checkbox
index 59b651bd6338c39d1e46e536ac20e77b15697b5a..266580e3d7ee1f3b493b301f5a6ba6c704b34eb2 100644 (file)
@@ -276,6 +276,7 @@ static int consumer_play_audio( consumer_sdl self, mlt_frame frame, int init_aud
        // Set the preferred params of the test card signal
        int channels = mlt_properties_get_int( properties, "channels" );
        int frequency = mlt_properties_get_int( properties, "frequency" );
+       int scrub = mlt_properties_get_int( properties, "scrub_audio" );
        static int counter = 0;
 
        int samples = mlt_sample_calculator( mlt_properties_get_double( self->properties, "fps" ), frequency, counter++ );
@@ -330,7 +331,7 @@ static int consumer_play_audio( consumer_sdl self, mlt_frame frame, int init_aud
                        pthread_cond_wait( &self->audio_cond, &self->audio_mutex );
                if ( self->running )
                {
-                       if ( mlt_properties_get_double( properties, "_speed" ) == 1 )
+                       if ( scrub || mlt_properties_get_double( properties, "_speed" ) == 1 )
                                memcpy( &self->audio_buffer[ self->audio_avail ], pcm, bytes );
                        else
                                memset( &self->audio_buffer[ self->audio_avail ], 0, bytes );
index 2e1d802c816e967377b153c2e3eae34a84de6041..834261fcaab0b7b0ce9bbdd2b3f86899a0ae61ad 100644 (file)
@@ -9,3 +9,40 @@ license: LGPLv2.1
 language: en
 tags:
   - Audio
+description: >
+  Simple DirectMedia Layer audio only output module.
+
+parameters:
+  - identifier: volume
+    title: Volume
+    type: float
+    description: Audio level factor.
+    mutable: yes
+
+  - identifier: audio_off
+    title: Audio off
+    type: integer
+    description: If 1, disable audio output
+    mutable: yes
+    minimum: 0
+    maximum: 1
+    default: 0
+    widget: checkbox
+
+  - identifier: audio_buffer
+    title: Audio buffer
+    type: integer
+    description: Size of the sdl audio buffer.
+    mutable: yes
+    default: 2048
+    minimum: 128
+
+  - identifier: scrub_audio
+    title: Audio scrubbing
+    type: integer
+    description: If enabled, sound is played even when the speed is not normal.
+    mutable: yes
+    minimum: 0
+    maximum: 1
+    default: 0
+    widget: checkbox
index c41d488a05593534a6a5c72a2f66f9b45c47ac50..88d7eebcda232d0baffd492791f7335478d262f2 100644 (file)
@@ -466,7 +466,7 @@ static void on_end_multitrack( deserialise_context context, const xmlChar *name
 
 static void on_start_playlist( deserialise_context context, const xmlChar *name, const xmlChar **atts)
 {
-       mlt_playlist playlist = mlt_playlist_init( );
+       mlt_playlist playlist = mlt_playlist_new( context->profile );
        mlt_service service = MLT_PLAYLIST_SERVICE( playlist );
        mlt_properties properties = MLT_SERVICE_PROPERTIES( service );
 
@@ -675,7 +675,6 @@ static void on_start_blank( deserialise_context context, const xmlChar *name, co
        // Get the playlist from the stack
        enum service_type type;
        mlt_service service = context_pop_service( context, &type );
-       mlt_position length = 0;
        
        if ( type == mlt_playlist_type && service != NULL )
        {
@@ -684,14 +683,12 @@ static void on_start_blank( deserialise_context context, const xmlChar *name, co
                {
                        if ( xmlStrcmp( atts[0], _x("length") ) == 0 )
                        {
-                               length = atoll( _s(atts[1]) );
+                               // Append a blank to the playlist
+                               mlt_playlist_blank_time( MLT_PLAYLIST( service ), _s(atts[1]) );
                                break;
                        }
                }
 
-               // Append a blank to the playlist
-               mlt_playlist_blank( MLT_PLAYLIST( service ), length - 1 );
-
                // Push the playlist back onto the stack
                context_push_service( context, service, type );
        }
@@ -1492,8 +1489,15 @@ static void parse_url( mlt_properties properties, char *url )
                        
                        case ':':
                        case '=':
-                               url[ i++ ] = '\0';
-                               value = &url[ i ];
+#ifdef WIN32
+                               if ( url[i] == ':' && url[i + 1] != '/' )
+                               {
+#endif
+                                       url[ i++ ] = '\0';
+                                       value = &url[ i ];
+#ifdef WIN32
+                               }
+#endif
                                break;
                        
                        case '&':