]> git.sesse.net Git - mlt/commitdiff
Data feed and show filters
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sat, 2 Oct 2004 10:14:07 +0000 (10:14 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sat, 2 Oct 2004 10:14:07 +0000 (10:14 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@458 d19143bc-622f-0410-bfdd-b5b2a6649095

14 files changed:
src/framework/mlt_factory.c
src/framework/mlt_service.c
src/framework/mlt_tractor.c
src/modules/core/Makefile
src/modules/core/configure
src/modules/core/factory.c
src/modules/core/filter_data.h [new file with mode: 0644]
src/modules/core/filter_data_feed.c [new file with mode: 0644]
src/modules/core/filter_data_show.c [new file with mode: 0644]
src/modules/core/filter_watermark.c
src/modules/core/transition_composite.c
src/modules/data_fx.properties [new file with mode: 0644]
src/modules/dv/producer_libdv.c
src/modules/inigo/producer_inigo.c

index ae0bade1024980e6068e2405ad62f7937f16c254..f183baabf2419ffa36a4244d75c6dfb7382a359a 100644 (file)
@@ -174,6 +174,7 @@ mlt_consumer mlt_factory_consumer( char *service, void *input )
                mlt_properties_set_int( properties, "_unique_id", ++ unique_id );
                mlt_properties_set( properties, "mlt_type", "consumer" );
                mlt_properties_set( properties, "mlt_service", service );
+               mlt_service_attach( mlt_consumer_service( obj ), mlt_factory_filter( "data_show", NULL ) );
        }
        return obj;
 }
index 362f3cc8d927e12f01a808af90d29fec14d3d0d9..06fd7d587bdfbb0bce29977005c759374191bcfa 100644 (file)
@@ -267,31 +267,33 @@ void mlt_service_apply_filters( mlt_service this, mlt_frame frame, int index )
 {
        int i;
        mlt_properties frame_properties = mlt_frame_properties( frame );
-       mlt_properties filter_properties = mlt_service_properties( this );
+       mlt_properties service_properties = mlt_service_properties( this );
        mlt_service_base *base = this->local;
        mlt_position position = mlt_frame_get_position( frame );
-       mlt_position this_in = mlt_properties_get_position( filter_properties, "in" );
+       mlt_position this_in = mlt_properties_get_position( service_properties, "in" );
+       mlt_position this_out = mlt_properties_get_position( service_properties, "out" );
 
        // Hmm - special case for cuts - apply filters from the parent first
-       if ( mlt_properties_get_int( filter_properties, "_cut" ) )
+       if ( mlt_properties_get_int( service_properties, "_cut" ) )
        {
+               mlt_service_apply_filters( ( mlt_service )mlt_properties_get_data( service_properties, "_cut_parent", NULL ), frame, 0 );
                position -= this_in;
                mlt_frame_set_position( frame, position );
-               mlt_service_apply_filters( ( mlt_service )mlt_properties_get_data( filter_properties, "_cut_parent", NULL ), frame, 0 );
        }
 
-       if ( index == 0 || mlt_properties_get_int( filter_properties, "_filter_private" ) == 0 )
+       if ( index == 0 || mlt_properties_get_int( service_properties, "_filter_private" ) == 0 )
        {
                // Process the frame with the attached filters
                for ( i = 0; i < base->filter_count; i ++ )
                {
                        if ( base->filters[ i ] != NULL )
                        {
-                               mlt_properties properties = mlt_filter_properties( base->filters[ i ] );
                                mlt_position in = mlt_filter_get_in( base->filters[ i ] );
                                mlt_position out = mlt_filter_get_out( base->filters[ i ] );
                                if ( ( in == 0 && out == 0 ) || ( position >= in && ( position <= out || out == 0 ) ) )
                                {
+                                       mlt_properties_set_position( frame_properties, "in", 0 );
+                                       mlt_properties_set_position( frame_properties, "out", out == 0 ? this_out - this_in : out - in );
                                        mlt_frame_set_position( frame, position - in );
                                        mlt_filter_process( base->filters[ i ], frame );
                                        mlt_service_apply_filters( mlt_filter_service( base->filters[ i ] ), frame, index + 1 );
@@ -301,8 +303,12 @@ void mlt_service_apply_filters( mlt_service this, mlt_frame frame, int index )
                }
        }
 
-       if ( mlt_properties_get_int( filter_properties, "_cut" ) )
+       if ( mlt_properties_get_int( service_properties, "_cut" ) )
+       {
+               mlt_properties_set_position( frame_properties, "in", this_in );
+               mlt_properties_set_position( frame_properties, "out", this_out );
                mlt_frame_set_position( frame, position + this_in );
+       }
 }
 
 /** Obtain a frame.
@@ -310,11 +316,23 @@ void mlt_service_apply_filters( mlt_service this, mlt_frame frame, int index )
 
 int mlt_service_get_frame( mlt_service this, mlt_frame_ptr frame, int index )
 {
-       if ( this != NULL )
+       if ( this != NULL && this->get_frame != NULL )
        {
-               int result = this->get_frame( this, frame, index );
+               int result = 0;
+               mlt_properties properties = mlt_service_properties( this );
+               mlt_position in = mlt_properties_get_position( properties, "in" );
+               mlt_position out = mlt_properties_get_position( properties, "out" );
+               result = this->get_frame( this, frame, index );
                if ( result == 0 )
+               {
+                       if ( in >=0 && out > 0 )
+                       {
+                               properties = mlt_frame_properties( *frame );
+                               mlt_properties_set_position( properties, "in", in );
+                               mlt_properties_set_position( properties, "out", out );
+                       }
                        mlt_service_apply_filters( this, *frame, 1 );
+               }
                return result;
        }
        *frame = mlt_frame_init( );
index 45918d50f460096ed1517659f00849488f5f4ac0..83f82f9771507dc6a1a688f9b8f34fbab47315f0 100644 (file)
@@ -275,6 +275,9 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra
                        mlt_frame audio = NULL;
                        mlt_frame video = NULL;
 
+                       // Determine which data_queue to pass on...
+                       void *data_queue = NULL;
+
                        // Get the multitrack's producer
                        mlt_producer target = mlt_multitrack_producer( multitrack );
                        mlt_producer_seek( target, mlt_producer_frame( parent ) );
@@ -299,6 +302,10 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra
                                sprintf( label, "_%s_%d", id, count ++ );
                                mlt_properties_set_data( frame_properties, label, temp, 0, ( mlt_destructor )mlt_frame_close, NULL );
 
+                               // We want the last data_queue 
+                               if ( mlt_properties_get_data( mlt_frame_properties( temp ), "data_queue", NULL ) != NULL )
+                                       data_queue = mlt_properties_get_data( mlt_frame_properties( temp ), "data_queue", NULL );
+
                                // Pick up first video and audio frames
                                if ( !done && !mlt_frame_is_test_audio( temp ) && !( mlt_properties_get_int( mlt_frame_properties( temp ), "hide" ) & 2 ) )
                                        audio = temp;
@@ -316,6 +323,7 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra
 
                        if ( video != NULL )
                        {
+                               mlt_properties_set_data( mlt_frame_properties( *frame ), "data_queue", data_queue, 0, NULL, NULL );
                                mlt_frame_push_service( *frame, video );
                                mlt_frame_push_service( *frame, producer_get_image );
                                mlt_properties_inherit( mlt_frame_properties( *frame ), mlt_frame_properties( video ) );
index 4f688281814dd64652f85193c79279e980a7cd96..e8d129b6531a8ee56e20a134318ea93b59369a8b 100644 (file)
@@ -8,6 +8,8 @@ OBJS = factory.o \
           producer_ppm.o \
           filter_brightness.o \
           filter_channelcopy.o \
+          filter_data_feed.o \
+          filter_data_show.o \
           filter_gamma.o \
           filter_greyscale.o \
           filter_luma.o \
@@ -50,6 +52,7 @@ clean:
 
 install: all
        install -m 755 $(TARGET) "$(prefix)/share/mlt/modules"
+       install -m 644 ../data_fx.properties "$(prefix)/share/mlt/modules"
 
 ifneq ($(wildcard .depend),)
 include .depend
index 818fe2431cb87a3bdc0b7feea1671b0c2e47ea3f..7b2e4fe4528e9be215f72793d0134541dedd7c09 100755 (executable)
@@ -12,6 +12,8 @@ EOF
 cat << EOF >> ../filters.dat
 brightness             libmltcore.so
 channelcopy            libmltcore.so
+data_feed              libmltcore.so
+data_show              libmltcore.so
 gamma                  libmltcore.so
 greyscale              libmltcore.so
 luma                   libmltcore.so
index f8a5fb4d2443513b4a5703df4073dd241f8d5a2b..87b8ee42b91aceee0d85d8bc62cd038656c19123 100644 (file)
@@ -25,6 +25,7 @@
 #include "producer_ppm.h"
 #include "filter_brightness.h"
 #include "filter_channelcopy.h"
+#include "filter_data.h"
 #include "filter_gamma.h"
 #include "filter_greyscale.h"
 #include "filter_luma.h"
@@ -57,6 +58,10 @@ void *mlt_create_filter( char *id, void *arg )
                return filter_brightness_init( arg );
        if ( !strcmp( id, "channelcopy" ) )
                return filter_channelcopy_init( arg );
+       if ( !strcmp( id, "data_feed" ) )
+               return filter_data_feed_init( arg );
+       if ( !strcmp( id, "data_show" ) )
+               return filter_data_show_init( arg );
        if ( !strcmp( id, "gamma" ) )
                return filter_gamma_init( arg );
        if ( !strcmp( id, "greyscale" ) )
diff --git a/src/modules/core/filter_data.h b/src/modules/core/filter_data.h
new file mode 100644 (file)
index 0000000..6413bd6
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * filter_data.h -- data feed and show filters
+ * Copyright (C) 2004-2005 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 _MLT_FILTER_DATA_H_
+#define _MLT_FILTER_DATA_H_
+
+#include <framework/mlt_filter.h>
+
+extern mlt_filter filter_data_feed_init( char * );
+extern mlt_filter filter_data_show_init( char * );
+
+#endif
+
diff --git a/src/modules/core/filter_data_feed.c b/src/modules/core/filter_data_feed.c
new file mode 100644 (file)
index 0000000..a490525
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * filter_data_feed.c -- data feed filter
+ * Copyright (C) 2004-2005 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.
+ */
+
+#include "filter_data.h"
+#include <framework/mlt.h>
+
+/** This filter should be used in conjuction with the data_show filter.
+       The concept of the data_feed is that it can be used to pass titles
+       or images to render on the frame, but doesn't actually do it 
+       itself. data_feed imposes few rules on what's passed on and the 
+       validity is confirmed in data_show before use.
+*/
+
+/** Data queue destructor.
+*/
+
+static void destroy_data_queue( void *arg )
+{
+       if ( arg != NULL )
+       {
+               // Assign the correct type
+               mlt_deque queue = arg;
+
+               // Iterate through each item and destroy them
+               while ( mlt_deque_peek_front( queue ) != NULL )
+                       mlt_properties_close( mlt_deque_pop_back( queue ) );
+
+               // Close the deque
+               mlt_deque_close( queue );
+       }
+}
+
+/** Filter processing.
+*/
+
+static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+{
+       // Get the filter properties
+       mlt_properties filter_properties = mlt_filter_properties( this );
+
+       // Get the frame properties
+       mlt_properties frame_properties = mlt_frame_properties( frame );
+
+       // Get the data queue
+       mlt_deque data_queue = mlt_properties_get_data( frame_properties, "data_queue", NULL );
+
+       // Create the data queue if it doesn't exist
+       if ( data_queue == NULL )
+       {
+               // Create the queue
+               data_queue = mlt_deque_init( );
+
+               // Assign it to the frame with the destructor
+               mlt_properties_set_data( frame_properties, "data_queue", data_queue, 0, destroy_data_queue, NULL );
+       }
+
+       // Now create the data feed
+       if ( data_queue != NULL )
+       {
+               // Get the in and out points of this filter
+               int in = mlt_filter_get_in( this );
+               int out = mlt_filter_get_out( this );
+
+               // Create a new data feed
+               mlt_properties feed = mlt_properties_new( );
+
+               // Get the type of the data feed
+               char *type = mlt_properties_get( filter_properties, "type" );
+
+               // Assign it the base properties
+               mlt_properties_set( feed, "id", mlt_properties_get( filter_properties, "_unique_id" ) );
+               mlt_properties_set( feed, "type", type );
+               mlt_properties_set_position( feed, "position", mlt_frame_get_position( frame ) );
+
+               // Assign in/out of service we're connected to
+               mlt_properties_set_position( feed, "in", mlt_properties_get_position( frame_properties, "in" ) );
+               mlt_properties_set_position( feed, "out", mlt_properties_get_position( frame_properties, "out" ) );
+
+               // Correct in/out to the filter if specified
+               if ( in != 0 )
+                       mlt_properties_set_position( feed, "in", in );
+               if ( out != 0 )
+                       mlt_properties_set_position( feed, "out", out );
+
+               // Pass the properties which start with a "feed." prefix 
+               // Note that 'feed.text' in the filter properties becomes 'text' on the feed
+               mlt_properties_pass( feed, filter_properties, "feed." );
+
+               // Push it on to the queue
+               mlt_deque_push_back( data_queue, feed );
+       }
+
+       return frame;
+}
+
+/** Constructor for the filter.
+*/
+
+mlt_filter filter_data_feed_init( char *arg )
+{
+       // Create the filter
+       mlt_filter this = mlt_filter_new( );
+
+       // Initialise it
+       if ( this != NULL )
+       {
+               // Get the properties
+               mlt_properties properties = mlt_filter_properties( this );
+
+               // Assign the argument (default to titles)
+               mlt_properties_set( properties, "type", arg == NULL ? "titles" : arg );
+
+               // Specify the processing method
+               this->process = filter_process;
+       }
+
+       return this;
+}
+
diff --git a/src/modules/core/filter_data_show.c b/src/modules/core/filter_data_show.c
new file mode 100644 (file)
index 0000000..2843dde
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * filter_data_show.c -- data feed filter
+ * Copyright (C) 2004-2005 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.
+ */
+
+#include "filter_data.h"
+#include <framework/mlt.h>
+#include <stdlib.h>
+#include <string.h>
+
+/** Handle the profile.
+*/
+
+static mlt_filter obtain_filter( mlt_filter filter, char *type )
+{
+       // Result to return
+       mlt_filter result = NULL;
+
+       // Miscelaneous variable
+       int i = 0;
+       int type_len = strlen( type );
+
+       // Get the properties of the data show filter
+       mlt_properties filter_properties = mlt_filter_properties( filter );
+
+       // Get the profile properties
+       mlt_properties profile_properties = mlt_properties_get_data( filter_properties, "profile_properties", NULL );
+
+       // Obtain the profile_properties if we haven't already
+       if ( profile_properties == NULL )
+       {
+               // Get the profile requested
+               char *profile = mlt_properties_get( filter_properties, "profile" );
+
+               // Load the specified profile or use the default
+               if ( profile != NULL )
+               {
+                       profile_properties = mlt_properties_load( profile );
+               }
+               else
+               {
+                       // Sometimes C can be laborious.. 
+                       static char *default_file = "/data_fx.properties";
+                       char *temp = malloc( strlen( mlt_factory_prefix( ) ) + strlen( default_file ) + 1 );
+                       if ( temp != NULL )
+                       {
+                               strcpy( temp, mlt_factory_prefix( ) );
+                               strcat( temp, default_file );
+                               profile_properties = mlt_properties_load( temp );
+                               free( temp );
+                       }
+               }
+
+               // Store for later retrieval
+               mlt_properties_set_data( filter_properties, "profile_properties", profile_properties, 0, ( mlt_destructor )mlt_properties_close, NULL );
+       }
+
+       if ( profile_properties != NULL )
+       {
+               for ( i = 0; i < mlt_properties_count( profile_properties ); i ++ )
+               {
+                       char *name = mlt_properties_get_name( profile_properties, i );
+                       char *value = mlt_properties_get_value( profile_properties, i );
+       
+                       if ( result == NULL && !strcmp( name, type ) && result == NULL )
+                               result = mlt_factory_filter( value, NULL );
+                       else if ( result != NULL && !strncmp( name, type, type_len ) && name[ type_len ] == '.' )
+                               mlt_properties_set( mlt_filter_properties( result ), name + type_len + 1, value );
+                       else if ( result != NULL )
+                               break;
+               }
+       }
+
+       return result;
+}
+
+/** Process the frame for the requested type
+*/
+
+static int process_feed( mlt_properties feed, mlt_filter filter, mlt_frame frame )
+{
+       // Error return
+       int error = 1;
+
+       // Get the properties of the data show filter
+       mlt_properties filter_properties = mlt_filter_properties( filter );
+
+       // Get the type requested by the feeding filter
+       char *type = mlt_properties_get( feed, "type" );
+
+       // Fetch the filter associated to this type
+       mlt_filter requested = mlt_properties_get_data( filter_properties, type, NULL );
+
+       // Calculate the length of the feed
+       int length = mlt_properties_get_int( feed, "out" ) - mlt_properties_get_int( feed, "in" ) + 1;
+
+       // If it doesn't exist, then create it now
+       if ( requested == NULL )
+       {
+               // Source filter from profile
+               requested = obtain_filter( filter, type );
+
+               // Store it on the properties for subsequent retrieval/destruction
+               mlt_properties_set_data( filter_properties, type, requested, 0, ( mlt_destructor )mlt_filter_close, NULL );
+       }
+
+       // If we have one, then process it now...
+       if ( requested != NULL )
+       {
+               int i = 0;
+               mlt_properties properties = mlt_filter_properties( requested );
+               static char *prefix = "properties.";
+               int len = strlen( prefix );
+
+               // Pass properties from feed into requested
+               for ( i = 0; i < mlt_properties_count( properties ); i ++ )
+               {
+                       char *name = mlt_properties_get_name( properties, i );
+                       char *key = mlt_properties_get_value( properties, i );
+                       if ( !strncmp( name, prefix, len ) )
+                       {
+                               if ( !strncmp( name + len, "length[", 7 ) )
+                               {
+                                       int period = mlt_properties_get_int( properties, "period" );
+                                       period = period == 0 ? 1 : period;
+                                       mlt_properties_set_position( properties, key, length / period );
+                               }
+                               else
+                               {
+                                       char *value = mlt_properties_get( feed, name + len );
+                                       if ( value != NULL )
+                                               mlt_properties_set( properties, key, value );
+                               }
+                       }
+               }
+
+               // Set the original position on the frame
+               mlt_frame_set_position( frame, mlt_properties_get_int( feed, "position" ) );
+
+               // Process the filter
+               mlt_filter_process( requested, frame );
+
+               // Should be ok...
+               error = 0;
+       }
+
+       return error;
+}
+
+/** Get the image.
+*/
+
+static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
+{
+       // Pop the service
+       mlt_filter filter = mlt_frame_pop_service( frame );
+
+       // Get the frame properties
+       mlt_properties frame_properties = mlt_frame_properties( frame );
+
+       // Fetch the data queue
+       mlt_deque data_queue = mlt_properties_get_data( frame_properties, "data_queue", NULL );
+
+       // Iterate through each entry on the queue
+       while ( data_queue != NULL && mlt_deque_peek_front( data_queue ) != NULL )
+       {
+               // Get the data feed
+               mlt_properties feed = mlt_deque_pop_front( data_queue );
+
+               // Process the data feed...
+               process_feed( feed, filter, frame );
+
+               // Close the feed
+               mlt_properties_close( feed );
+       }
+
+       // Need to get the image
+       return mlt_frame_get_image( frame, image, format, width, height, 1 );
+}
+
+
+/** Filter processing.
+*/
+
+static mlt_frame filter_process( mlt_filter this, mlt_frame frame )
+{
+       // Push the filter
+       mlt_frame_push_service( frame, this );
+
+       // Register the get image method
+       mlt_frame_push_get_image( frame, filter_get_image );
+
+       // Return the frame
+       return frame;
+}
+
+/** Constructor for the filter.
+*/
+
+mlt_filter filter_data_show_init( char *arg )
+{
+       // Create the filter
+       mlt_filter this = mlt_filter_new( );
+
+       // Initialise it
+       if ( this != NULL )
+       {
+               // Get the properties
+               mlt_properties properties = mlt_filter_properties( this );
+
+               // Assign the argument (default to titles)
+               mlt_properties_set( properties, "profile", arg == NULL ? NULL : arg );
+
+               // Specify the processing method
+               this->process = filter_process;
+       }
+
+       return this;
+}
+
index bf781dc2480296b66547646a03a9148d64a59010..4908d441073e7eca174d0f8412cd690676326c9a 100644 (file)
@@ -74,6 +74,9 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format
 
                // Pass all the composite. properties on the filter down
                mlt_properties_pass( composite_properties, properties, "composite." );
+
+               // Force a refresh
+               mlt_properties_set_int( composite_properties, "refresh", 1 );
        }
 
        // Create a producer if don't have one
index de2c464dae55c473f861b5e0431b33d4de52ce47..57cf67d01976aabb16fc32c3674816a932e7feb8 100644 (file)
@@ -296,7 +296,7 @@ static int alignment_parse( char* align )
 static void alignment_calculate( struct geometry_s *geometry )
 {
        geometry->x += ( geometry->w - geometry->sw ) * geometry->halign / 2;
-       geometry->y += ( geometry->h - geometry->sh ) * geometry->valign;
+       geometry->y += ( geometry->h - geometry->sh ) * geometry->valign / 2;
 }
 
 /** Calculate the position for this frame.
@@ -1022,20 +1022,45 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f
 
                // Do the calculation
                struct geometry_s *start = composite_calculate( &result, this, a_frame, position );
-               
+
+               // Get the image from the b frame
+               uint8_t *image_b = NULL;
+               int width_b = *width;
+               int height_b = *height;
+       
                // Optimisation - no compositing required
                if ( result.mix == 0 || ( result.w == 0 && result.h == 0 ) )
                        return 0;
 
+               // Need to keep the width/height of the a_frame on the b_frame for titling
+               if ( mlt_properties_get( a_props, "dest_width" ) == NULL )
+               {
+                       mlt_properties_set_int( a_props, "dest_width", *width );
+                       mlt_properties_set_int( a_props, "dest_height", *height );
+                       mlt_properties_set_int( b_props, "dest_width", *width );
+                       mlt_properties_set_int( b_props, "dest_height", *height );
+               }
+               else
+               {
+                       mlt_properties_set_int( b_props, "dest_width", mlt_properties_get_int( a_props, "dest_width" ) );
+                       mlt_properties_set_int( b_props, "dest_height", mlt_properties_get_int( a_props, "dest_height" ) );
+               }
+
                // Since we are the consumer of the b_frame, we must pass along these
                // consumer properties from the a_frame
+               mlt_properties_set_double( b_props, "consumer_progressive", mlt_properties_get_double( a_props, "consumer_progressive" ) );
                mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) );
 
-               // Get the image from the b frame
-               uint8_t *image_b = NULL;
-               int width_b = *width;
-               int height_b = *height;
-               
+               // Special case for titling...
+               if ( mlt_properties_get_int( properties, "titles" ) )
+               {
+                       if ( mlt_properties_get( b_props, "rescale.interp" ) == NULL )
+                               mlt_properties_set( b_props, "rescale.interp", "nearest" );
+                       mlt_properties_set( properties, "fill", NULL );
+                       width_b = mlt_properties_get_int( a_props, "dest_width" );
+                       height_b = mlt_properties_get_int( a_props, "dest_height" );
+               }
+
                if ( get_b_frame_image( this, b_frame, &image_b, &width_b, &height_b, &result ) == 0 )
                {
                        uint8_t *dest = *image;
diff --git a/src/modules/data_fx.properties b/src/modules/data_fx.properties
new file mode 100644 (file)
index 0000000..dd8cbbc
--- /dev/null
@@ -0,0 +1,81 @@
+# This properties file describes the fx available to the data_send and 
+# data_show filters
+#
+# Syntax is as follows:
+#
+#      name=<filter>
+#      name.description=<user defined>
+#      name.properties.<variable>=<full-property>
+#      name.<property>=value
+#      etc
+#
+# Typically, the <filter> is a 'region' and additional filters are 
+# included as properties using the normal region filter syntax.
+#
+
+#
+# The titles filter definition
+#
+
+titles=region
+titles.description=Titles
+titles.properties.markup=filter[1].producer.markup
+titles.type.markup=text
+titles.period=2
+titles.properties.length[0]=filter[0].composite.out
+titles.properties.length[1]=filter[1].composite.out
+titles.composite.start=5%,70%:90%x20%
+titles.filter[0]=watermark
+titles.filter[0].resource=colour:0x000000
+titles.filter[0].composite.start=0%,0%:100%x100%:0
+titles.filter[0].composite.key[5]=0%,0%:100%x100%:40
+titles.filter[1]=watermark
+titles.filter[1].resource=pango:
+titles.filter[1].producer.markup=Shotcut
+titles.filter[1].composite.start=1%,1%:99%x99%:0
+titles.filter[1].composite.key[8]=1%,1%:99%x99%:100
+titles.filter[1].composite.titles=1
+
+#
+# The top titles filter definition
+#
+
+top-titles=region
+top-titles.description=Top Titles
+top-titles.properties.markup=filter[1].producer.markup
+top-titles.type.markup=text
+titles.period=2
+top-titles.properties.length[0]=filter[0].composite.out
+top-titles.properties.length[1]=filter[1].composite.out
+top-titles.composite.start=5%,5%:90%x20%
+top-titles.filter[0]=watermark
+top-titles.filter[0].resource=colour:0x000000
+top-titles.filter[0].composite.start=0%,0%:100%x100%:0
+top-titles.filter[0].composite.key[5]=0%,0%:100%x100%:40
+top-titles.filter[1]=watermark
+top-titles.filter[1].resource=pango:
+top-titles.filter[1].producer.markup=Shotcut
+top-titles.filter[1].composite.start=1%,1%:99%x99%:0
+top-titles.filter[1].composite.key[8]=1%,1%:99%x99%:100
+top-titles.filter[1].composite.halign=centre
+top-titles.filter[1].composite.titles=1
+
+#
+# OK - Silly example...
+#
+
+tickertape=region
+tickertape.description=Tickertape
+tickertape.properties.markup=filter[1].producer.markup
+tickertape.type.markup=text
+tickertape.properties.length[0]=filter[1].composite.out
+tickertape.composite.start=0%,93%:100%x7%
+tickertape.filter[0]=watermark
+tickertape.filter[0].resource=colour:0x000000
+tickertape.filter[0].composite.start=0%,0%:100%x100%:100
+tickertape.filter[1]=watermark
+tickertape.filter[1].resource=pango:
+tickertape.filter[1].producer.markup=Shotcut
+tickertape.filter[1].composite.start=101%,1%:300%x99%:100
+tickertape.filter[1].composite.end=-300%,1%:300%x99%:100
+tickertape.filter[1].composite.titles=1
index 249213d278943e31d30c18e95ee5ff271838d240..6ab349c403924776066bd2a7488b0ebc6236ec24 100644 (file)
@@ -415,7 +415,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i
                // Update other info on the frame
                mlt_properties_set_int( properties, "width", 720 );
                mlt_properties_set_int( properties, "height", this->is_pal ? 576 : 480 );
-               mlt_properties_set_int( properties, "top_field_first", 0 );
+               mlt_properties_set_int( properties, "top_field_first", !this->is_pal ? 0 : ( data[ 5 ] & 0x07 ) == 0 ? 0 : 1 );
 
                // Parse the header for meta info
                dv_parse_header( dv_decoder, data );
index d6fb2838d8da5255c50f91f9948cf9519dff5320..ad811f4cd246f844ec45ee2ff125062326e93a98 100644 (file)
@@ -147,7 +147,7 @@ mlt_producer producer_inigo_init( char **argv )
                        if ( group != NULL )
                                properties = group;
                }
-               else if ( !strcmp( argv[ i ], "-attach" ) || !strcmp( argv[ i ], "-chain" ) )
+               else if ( !strcmp( argv[ i ], "-attach" ) || !strcmp( argv[ i ], "-attach-cut" ) )
                {
                        int type = !strcmp( argv[ i ], "-attach" ) ? 0 : 1;
                        mlt_filter filter = create_attach( field, argv[ ++ i ], track );
@@ -159,6 +159,13 @@ mlt_producer producer_inigo_init( char **argv )
                                producer = info.cut;
                        }
 
+                       if ( type == 1 )
+                       {
+                               mlt_playlist_clip_info info;
+                               mlt_playlist_get_clip_info( playlist, &info, mlt_playlist_count( playlist ) - 1 );
+                               producer = info.cut;
+                       }
+
                        if ( filter != NULL && mlt_playlist_count( playlist ) > 0 )
                        {
                                if ( type == 0 )