From 95f429b56026f5897ebad9060608b6631dcf7515 Mon Sep 17 00:00:00 2001 From: lilo_booter Date: Sat, 2 Oct 2004 10:14:07 +0000 Subject: [PATCH] Data feed and show filters git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@458 d19143bc-622f-0410-bfdd-b5b2a6649095 --- src/framework/mlt_factory.c | 1 + src/framework/mlt_service.c | 36 +++- src/framework/mlt_tractor.c | 8 + src/modules/core/Makefile | 3 + src/modules/core/configure | 2 + src/modules/core/factory.c | 5 + src/modules/core/filter_data.h | 30 +++ src/modules/core/filter_data_feed.c | 136 ++++++++++++++ src/modules/core/filter_data_show.c | 235 ++++++++++++++++++++++++ src/modules/core/filter_watermark.c | 3 + src/modules/core/transition_composite.c | 39 +++- src/modules/data_fx.properties | 81 ++++++++ src/modules/dv/producer_libdv.c | 2 +- src/modules/inigo/producer_inigo.c | 9 +- 14 files changed, 572 insertions(+), 18 deletions(-) create mode 100644 src/modules/core/filter_data.h create mode 100644 src/modules/core/filter_data_feed.c create mode 100644 src/modules/core/filter_data_show.c create mode 100644 src/modules/data_fx.properties diff --git a/src/framework/mlt_factory.c b/src/framework/mlt_factory.c index ae0bade1..f183baab 100644 --- a/src/framework/mlt_factory.c +++ b/src/framework/mlt_factory.c @@ -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; } diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c index 362f3cc8..06fd7d58 100644 --- a/src/framework/mlt_service.c +++ b/src/framework/mlt_service.c @@ -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( ); diff --git a/src/framework/mlt_tractor.c b/src/framework/mlt_tractor.c index 45918d50..83f82f97 100644 --- a/src/framework/mlt_tractor.c +++ b/src/framework/mlt_tractor.c @@ -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 ) ); diff --git a/src/modules/core/Makefile b/src/modules/core/Makefile index 4f688281..e8d129b6 100644 --- a/src/modules/core/Makefile +++ b/src/modules/core/Makefile @@ -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 diff --git a/src/modules/core/configure b/src/modules/core/configure index 818fe243..7b2e4fe4 100755 --- a/src/modules/core/configure +++ b/src/modules/core/configure @@ -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 diff --git a/src/modules/core/factory.c b/src/modules/core/factory.c index f8a5fb4d..87b8ee42 100644 --- a/src/modules/core/factory.c +++ b/src/modules/core/factory.c @@ -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 index 00000000..6413bd6d --- /dev/null +++ b/src/modules/core/filter_data.h @@ -0,0 +1,30 @@ +/* + * filter_data.h -- data feed and show filters + * Copyright (C) 2004-2005 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * 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 + +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 index 00000000..a4905251 --- /dev/null +++ b/src/modules/core/filter_data_feed.c @@ -0,0 +1,136 @@ +/* + * filter_data_feed.c -- data feed filter + * Copyright (C) 2004-2005 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * 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 + +/** 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 index 00000000..2843ddee --- /dev/null +++ b/src/modules/core/filter_data_show.c @@ -0,0 +1,235 @@ +/* + * filter_data_show.c -- data feed filter + * Copyright (C) 2004-2005 Ushodaya Enterprises Limited + * Author: Charles Yates + * + * 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 +#include +#include + +/** 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; +} + diff --git a/src/modules/core/filter_watermark.c b/src/modules/core/filter_watermark.c index bf781dc2..4908d441 100644 --- a/src/modules/core/filter_watermark.c +++ b/src/modules/core/filter_watermark.c @@ -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 diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index de2c464d..57cf67d0 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -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 index 00000000..dd8cbbc8 --- /dev/null +++ b/src/modules/data_fx.properties @@ -0,0 +1,81 @@ +# This properties file describes the fx available to the data_send and +# data_show filters +# +# Syntax is as follows: +# +# name= +# name.description= +# name.properties.= +# name.=value +# etc +# +# Typically, the 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 diff --git a/src/modules/dv/producer_libdv.c b/src/modules/dv/producer_libdv.c index 249213d2..6ab349c4 100644 --- a/src/modules/dv/producer_libdv.c +++ b/src/modules/dv/producer_libdv.c @@ -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 ); diff --git a/src/modules/inigo/producer_inigo.c b/src/modules/inigo/producer_inigo.c index d6fb2838..ad811f4c 100644 --- a/src/modules/inigo/producer_inigo.c +++ b/src/modules/inigo/producer_inigo.c @@ -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 ) -- 2.39.2