From dd4fc496b376a53c7f5599324b5d1962c19ec41d Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 31 Oct 2020 08:24:49 -0500 Subject: [PATCH 001/122] Add MLT chain and link classes Also add the first link module: timeremap --- src/framework/Makefile | 8 +- src/framework/mlt.h | 2 + src/framework/mlt.vers | 18 ++ src/framework/mlt_chain.c | 460 ++++++++++++++++++++++++++++ src/framework/mlt_chain.h | 56 ++++ src/framework/mlt_factory.c | 38 ++- src/framework/mlt_factory.h | 1 + src/framework/mlt_link.c | 130 ++++++++ src/framework/mlt_link.h | 74 +++++ src/framework/mlt_producer.c | 6 +- src/framework/mlt_repository.c | 21 ++ src/framework/mlt_repository.h | 1 + src/framework/mlt_service.c | 4 + src/framework/mlt_types.h | 8 +- src/mlt++/Makefile | 2 + src/mlt++/Mlt.h | 1 + src/mlt++/MltChain.cpp | 123 ++++++++ src/mlt++/MltChain.h | 59 ++++ src/mlt++/MltLink.cpp | 82 +++++ src/mlt++/MltLink.h | 49 +++ src/mlt++/MltProducer.cpp | 3 +- src/mlt++/MltRepository.cpp | 5 + src/mlt++/MltRepository.h | 1 + src/mlt++/mlt++.vers | 31 ++ src/modules/avformat/factory.c | 7 + src/modules/core/Makefile | 1 + src/modules/core/factory.c | 3 + src/modules/core/link_timeremap.c | 421 +++++++++++++++++++++++++ src/modules/core/link_timeremap.yml | 27 ++ src/modules/core/producer_melt.c | 64 +++- src/modules/xml/consumer_xml.c | 97 +++++- src/modules/xml/producer_xml.c | 204 +++++++++++- 32 files changed, 1995 insertions(+), 12 deletions(-) create mode 100644 src/framework/mlt_chain.c create mode 100644 src/framework/mlt_chain.h create mode 100644 src/framework/mlt_link.c create mode 100644 src/framework/mlt_link.h create mode 100644 src/mlt++/MltChain.cpp create mode 100644 src/mlt++/MltChain.h create mode 100644 src/mlt++/MltLink.cpp create mode 100644 src/mlt++/MltLink.h create mode 100644 src/modules/core/link_timeremap.c create mode 100644 src/modules/core/link_timeremap.yml diff --git a/src/framework/Makefile b/src/framework/Makefile index 4040fc458..d083728c1 100644 --- a/src/framework/Makefile +++ b/src/framework/Makefile @@ -51,7 +51,9 @@ OBJS = mlt_audio.o \ mlt_cache.o \ mlt_animation.o \ mlt_slices.o \ - mlt_luma_map.o + mlt_luma_map.o \ + mlt_link.o \ + mlt_chain.o INCS = mlt_audio.h \ mlt_consumer.h \ @@ -82,7 +84,9 @@ INCS = mlt_audio.h \ mlt_cache.h \ mlt_animation.h \ mlt_slices.h \ - mlt_luma_map.h + mlt_luma_map.h \ + mlt_link.h \ + mlt_chain.h SRCS := $(OBJS:.o=.c) diff --git a/src/framework/mlt.h b/src/framework/mlt.h index f4f345ac0..5f18feff7 100644 --- a/src/framework/mlt.h +++ b/src/framework/mlt.h @@ -59,6 +59,8 @@ extern "C" #include "mlt_cache.h" #include "mlt_version.h" #include "mlt_slices.h" +#include "mlt_link.h" +#include "mlt_chain.h" #ifdef __cplusplus } diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index 20b5cb029..da44f6019 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -576,3 +576,21 @@ MLT_6.22.0 { mlt_audio_channel_layout_channels; mlt_audio_channel_layout_default; } MLT_6.20.0; + +MLT_6.24.0 { + global: + mlt_factory_link; + mlt_chain_init; + mlt_chain_set_source; + mlt_chain_get_source; + mlt_chain_attach; + mlt_chain_detach; + mlt_chain_link_count; + mlt_chain_move_link; + mlt_chain_link; + mlt_chain_close; + mlt_link_init; + mlt_link_connect_next; + mlt_link_close; + mlt_repository_links; +} MLT_6.22.0; diff --git a/src/framework/mlt_chain.c b/src/framework/mlt_chain.c new file mode 100644 index 000000000..46e06f219 --- /dev/null +++ b/src/framework/mlt_chain.c @@ -0,0 +1,460 @@ +/** + * \file mlt_chain.c + * \brief link service class + * \see mlt_chain_s + * + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "mlt_chain.h" +#include "mlt_factory.h" +#include "mlt_frame.h" +#include "mlt_log.h" + +#include +#include +#include + +/** \brief private service definition */ + +typedef struct +{ + int link_count; + int link_size; + mlt_link* links; + mlt_producer source; + mlt_profile source_profile; + mlt_properties source_parameters; + mlt_producer begin; +} +mlt_chain_base; + +/* Forward references to static methods. +*/ + +static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); +static void relink_chain( mlt_chain self ); +static void chain_property_changed( mlt_service owner, mlt_chain self, char *name ); +static void source_property_changed( mlt_service owner, mlt_chain self, char *name ); + +/** Construct a chain. + * + * \public \memberof mlt_chain_s + * \return the new chain + */ + +mlt_chain mlt_chain_init( mlt_profile profile ) +{ + mlt_chain self = calloc( 1, sizeof( struct mlt_chain_s ) ); + if ( self != NULL ) + { + mlt_producer producer = &self->parent; + if ( mlt_producer_init( producer, self ) == 0 ) + { + mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); + + mlt_properties_set( properties, "mlt_type", "chain" ); + mlt_properties_clear( properties, "resource"); + mlt_properties_clear( properties, "mlt_service"); + mlt_properties_clear( properties, "in"); + mlt_properties_clear( properties, "out"); + mlt_properties_clear( properties, "length"); + + producer->get_frame = producer_get_frame; + producer->close = ( mlt_destructor )mlt_chain_close; + producer->close_object = self; + + mlt_service_set_profile( MLT_CHAIN_SERVICE( self ), profile ); + + // Generate local space + self->local = calloc( 1, sizeof( mlt_chain_base ) ); + mlt_chain_base* base = self->local; + base->source_profile = mlt_profile_init(NULL); + + // Listen to property changes to pass along to the source + mlt_events_listen( MLT_CHAIN_PROPERTIES(self), self, "property-changed", ( mlt_listener )chain_property_changed ); + } + else + { + free( self ); + self = NULL; + } + } + return self; +} + +/** Set the source producer. + * + * \public \memberof mlt_chain_s + * \param self a chain + * \param source the new source producer + */ + +void mlt_chain_set_source( mlt_chain self, mlt_producer source ) +{ + int error = self == NULL || source == NULL; + if ( error == 0 ) + { + mlt_chain_base* base = self->local; + mlt_properties source_properties = MLT_PRODUCER_PROPERTIES( source ); + int n = 0; + int i = 0; + + // Clean up from previous source + mlt_producer_close( base->source ); + mlt_properties_close( base->source_parameters ); + + // Save the source producer + base->source = source; + mlt_properties_inc_ref( source_properties ); + + // Create a list of all parameters used by the source producer so that + // they can be passed between the source producer and this chain. + base->source_parameters = mlt_properties_new(); + mlt_repository repository = mlt_factory_repository(); + mlt_properties source_metadata = mlt_repository_metadata( repository, producer_type, mlt_properties_get( source_properties, "mlt_service" ) ); + if ( source_metadata ) + { + mlt_properties params = (mlt_properties) mlt_properties_get_data( source_metadata, "parameters", NULL ); + if ( params ) + { + n = mlt_properties_count( params ); + for ( i = 0; i < n; i++ ) + { + mlt_properties param = (mlt_properties) mlt_properties_get_data( params, mlt_properties_get_name( params, i ), NULL ); + char* identifier = mlt_properties_get( param, "identifier" ); + if ( identifier ) + { + // Set the value to 1 to indicate the parameter exists. + mlt_properties_set_int( base->source_parameters, identifier, 1 ); + } + } + } + } + + // Pass parameters and properties from the source producer to this chain. + // Some properties may have been set during source initialization. + n = mlt_properties_count( source_properties ); + mlt_events_block( MLT_CHAIN_PROPERTIES(self), self ); + for ( i = 0; i < n; i++ ) + { + char* name = mlt_properties_get_name( source_properties, i ); + if ( mlt_properties_get_int( base->source_parameters, name ) || + !strcmp( name, "mlt_service" ) || + !strcmp( name, "_mlt_service_hidden" ) || + !strncmp( name, "meta.", 5 ) ) + { + mlt_properties_pass_property( MLT_CHAIN_PROPERTIES(self), source_properties, name ); + } + } + // If a length has not been specified for this chain, copy in/out/length from the source producer + if ( !mlt_producer_get_length( MLT_CHAIN_PRODUCER(self) ) ) { + mlt_properties_set_int( MLT_CHAIN_PROPERTIES(self), "length", mlt_producer_get_length( base->source ) ); + mlt_producer_set_in_and_out( MLT_CHAIN_PRODUCER(self), mlt_producer_get_in( base->source ), mlt_producer_get_out( base->source ) ); + } + mlt_events_unblock( MLT_CHAIN_PROPERTIES(self), self ); + + // Monitor property changes from the source to pass to the chain. + mlt_events_listen( source_properties, self, "property-changed", ( mlt_listener )source_property_changed ); + + // Save the native source producer profile + mlt_profile_from_producer( base->source_profile, base->source ); + + // This chain will control the speed + mlt_producer_set_speed( base->source, 0.0 ); + + // Reconfigure the chain + relink_chain( self ); + mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", NULL ); + } +} + +/** Get the source producer. + * + * \public \memberof mlt_chain_s + * \param self a chain + * \return the source producer + */ + +extern mlt_producer mlt_chain_get_source( mlt_chain self ) +{ + mlt_producer source = NULL; + if ( self && self->local ) + { + mlt_chain_base* base = self->local; + source = base->source; + } + return source; +} + +/** Attach a link. + * + * \public \memberof mlt_chain_s + * \param self a chain + * \param link the link to attach + * \return true if there was an error + */ + +int mlt_chain_attach( mlt_chain self, mlt_link link ) +{ + int error = self == NULL || link == NULL; + if ( error == 0 ) + { + int i = 0; + mlt_chain_base *base = self->local; + + for ( i = 0; error == 0 && i < base->link_count; i ++ ) + if ( base->links[ i ] == link ) + error = 1; + + if ( error == 0 ) + { + if ( base->link_count == base->link_size ) + { + base->link_size += 10; + base->links = realloc( base->links, base->link_size * sizeof( mlt_link ) ); + } + + if ( base->links != NULL ) + { + mlt_properties_inc_ref( MLT_LINK_PROPERTIES( link ) ); + mlt_properties_set_data( MLT_LINK_PROPERTIES( link ), "chain", self, 0, NULL, NULL ); + base->links[ base->link_count ++ ] = link; + relink_chain( self ); + mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", NULL ); + } + else + { + error = 2; + } + } + } + return error; +} + +/** Detach a link. + * + * \public \memberof mlt_chain_s + * \param self a chain + * \param link the link to detach + * \return true if there was an error + */ + +int mlt_chain_detach( mlt_chain self, mlt_link link ) +{ + int error = self == NULL || link == NULL; + if ( error == 0 ) + { + int i = 0; + mlt_chain_base *base = self->local; + + for ( i = 0; i < base->link_count; i ++ ) + if ( base->links[ i ] == link ) + break; + + if ( i < base->link_count ) + { + base->links[ i ] = NULL; + for ( i ++ ; i < base->link_count; i ++ ) + base->links[ i - 1 ] = base->links[ i ]; + base->link_count --; + mlt_link_close( link ); + relink_chain( self ); + mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", NULL ); + } + } + return error; +} + +/** Get the number of links attached. + * + * \public \memberof mlt_chain_s + * \param self a chain + * \return the number of attached links or -1 if there was an error + */ + +int mlt_chain_link_count( mlt_chain self ) +{ + int result = -1; + if ( self ) + { + mlt_chain_base *base = self->local; + result = base->link_count; + } + return result; +} + +/** Reorder the attached links. + * + * \public \memberof mlt_chain_s + * \param self a chain + * \param from the current index value of the link to move + * \param to the new index value for the link specified in \p from + * \return true if there was an error + */ + +int mlt_chain_move_link( mlt_chain self, int from, int to ) +{ + int error = -1; + if ( self ) + { + mlt_chain_base *base = self->local; + if ( from < 0 ) from = 0; + if ( from >= base->link_count ) from = base->link_count - 1; + if ( to < 0 ) to = 0; + if ( to >= base->link_count ) to = base->link_count - 1; + if ( from != to && base->link_count > 1 ) + { + mlt_link link = base->links[from]; + int i; + if ( from > to ) + { + for ( i = from; i > to; i-- ) + base->links[i] = base->links[i - 1]; + } + else + { + for ( i = from; i < to; i++ ) + base->links[i] = base->links[i + 1]; + } + base->links[to] = link; + relink_chain( self ); + mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", NULL ); + error = 0; + } + } + return error; +} + +/** Retrieve an attached link. + * + * \public \memberof mlt_chain_s + * \param self a chain + * \param index which one of potentially multiple links + * \return the link or null if there was an error + */ + +mlt_link mlt_chain_link( mlt_chain self, int index ) +{ + mlt_link link = NULL; + if ( self != NULL ) + { + mlt_chain_base *base = self->local; + if ( index >= 0 && index < base->link_count ) + link = base->links[ index ]; + } + return link; +} + +/** Close the chain and free its resources. + * + * \public \memberof mlt_chain_s + * \param self a chain + */ + +void mlt_chain_close( mlt_chain self ) +{ + if ( self != NULL && mlt_properties_dec_ref( MLT_CHAIN_PROPERTIES( self ) ) <= 0 ) + { + int i = 0; + mlt_chain_base *base = self->local; + mlt_events_block( MLT_CHAIN_PROPERTIES( self ), self ); + for ( i = 0; i < base->link_count; i ++ ) + mlt_link_close( base->links[ i ] ); + free( base->links ); + mlt_profile_close( base->source_profile ); + free( base ); + self->parent.close = NULL; + mlt_producer_close( &self->parent ); + free( self ); + } +} + +static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ) +{ + int result = 1; + if ( parent && parent->child ) + { + mlt_chain self = parent->child; + if( self ) + { + mlt_chain_base *base = self->local; + mlt_producer_seek( base->begin, mlt_producer_frame( parent ) ); + result = mlt_service_get_frame( MLT_PRODUCER_SERVICE( base->begin ), frame, index ); + mlt_producer_prepare_next( parent ); + } + } + return result; +} + +static void relink_chain( mlt_chain self ) +{ + mlt_chain_base *base = self->local; + mlt_profile profile = mlt_service_profile( MLT_CHAIN_SERVICE(self) ); + + if ( base->link_count == 0 ) + { + base->begin = base->source; + // If there are no links, the producer can operate in the final frame rate + mlt_service_set_profile( MLT_PRODUCER_SERVICE(base->source), profile ); + } + else + { + // Set the producer to be in native frame rate + mlt_service_set_profile( MLT_PRODUCER_SERVICE(base->source), base->source_profile ); + + int i = 0; + base->begin = MLT_LINK_PRODUCER( base->links[0] ); + for ( i = 0; i < base->link_count - 1; i++ ) + { + mlt_link_connect_next( base->links[i], MLT_LINK_PRODUCER( base->links[i+1] ), profile ); + } + mlt_link_connect_next( base->links[base->link_count -1], base->source, profile ); + } +} + +static void chain_property_changed( mlt_service owner, mlt_chain self, char *name ) +{ + mlt_chain_base *base = self->local; + if ( !base->source ) return; + if ( mlt_properties_get_int( base->source_parameters, name ) || + !strncmp( name, "meta.", 5 ) ) + { + // Pass parameter changes from this chain to the encapsulated source producer. + mlt_properties chain_properties = MLT_CHAIN_PROPERTIES( self ); + mlt_properties source_properties = MLT_PRODUCER_PROPERTIES( base->source ); + mlt_events_block( source_properties, self ); + mlt_properties_pass_property( source_properties, chain_properties, name ); + mlt_events_unblock( source_properties, self ); + } +} + +static void source_property_changed( mlt_service owner, mlt_chain self, char *name ) +{ + mlt_chain_base *base = self->local; + if ( mlt_properties_get_int( base->source_parameters, name ) || + !strncmp( name, "meta.", 5 ) ) + { + // The source producer might change its own parameters. + // Pass those changes to this producer. + mlt_properties chain_properties = MLT_CHAIN_PROPERTIES( self ); + mlt_properties source_properties = MLT_PRODUCER_PROPERTIES( base->source ); + mlt_events_block( chain_properties, self ); + mlt_properties_pass_property( chain_properties, source_properties, name ); + mlt_events_unblock( chain_properties, self ); + } +} diff --git a/src/framework/mlt_chain.h b/src/framework/mlt_chain.h new file mode 100644 index 000000000..778b1a8c5 --- /dev/null +++ b/src/framework/mlt_chain.h @@ -0,0 +1,56 @@ +/** + * \file mlt_chain.h + * \brief chain service class + * \see mlt_chain_s + * + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MLT_CHAIN_H +#define MLT_CHAIN_H + +#include "mlt_link.h" +#include "mlt_producer.h" + +/** \brief Chain class + * + * The chain is a producer class that that can connect multiple link producers in a sequence. + * + * \extends mlt_producer_s + */ + +struct mlt_chain_s +{ + struct mlt_producer_s parent; + void* local; /**< \private instance object */ +}; + +#define MLT_CHAIN_PRODUCER( chain ) ( &( chain )->parent ) +#define MLT_CHAIN_SERVICE( chain ) MLT_PRODUCER_SERVICE( MLT_CHAIN_PRODUCER( chain ) ) +#define MLT_CHAIN_PROPERTIES( chain ) MLT_SERVICE_PROPERTIES( MLT_CHAIN_SERVICE( chain ) ) + +extern mlt_chain mlt_chain_init( mlt_profile ); +extern void mlt_chain_set_source( mlt_chain self, mlt_producer source ); +extern mlt_producer mlt_chain_get_source( mlt_chain self ); +extern int mlt_chain_attach( mlt_chain self, mlt_link link ); +extern int mlt_chain_detach( mlt_chain self, mlt_link link ); +extern int mlt_chain_link_count( mlt_chain self ); +extern int mlt_chain_move_link( mlt_chain self, int from, int to ); +extern mlt_link mlt_chain_link( mlt_chain self, int index ); +extern void mlt_chain_close( mlt_chain self ); + +#endif diff --git a/src/framework/mlt_factory.c b/src/framework/mlt_factory.c index 775aaf733..818d211f6 100644 --- a/src/framework/mlt_factory.c +++ b/src/framework/mlt_factory.c @@ -364,7 +364,15 @@ mlt_producer mlt_factory_producer( mlt_profile profile, const char *service, con if ( obj != NULL ) { mlt_properties properties = MLT_PRODUCER_PROPERTIES( obj ); - set_common_properties( properties, profile, "producer", service ); + if ( mlt_service_identify( MLT_PRODUCER_SERVICE( obj ) ) == chain_type ) + { + // XML producer may return a chain + set_common_properties( properties, profile, "chain", service ); + } + else + { + set_common_properties( properties, profile, "producer", service ); + } } } return obj; @@ -399,6 +407,34 @@ mlt_filter mlt_factory_filter( mlt_profile profile, const char *service, const v return obj; } +/** Fetch a link from the repository. + * + * \param service the name of the link + * \param input an optional argument to the link constructor, typically a string + * \return a new link + */ + +mlt_link mlt_factory_link( const char *service, const void *input ) +{ + mlt_link obj = NULL; + + // Offer the application the chance to 'create' + mlt_events_fire( event_object, "link-create-request", service, input, &obj, NULL ); + + if ( obj == NULL ) + { + obj = mlt_repository_create( repository, NULL, link_type, service, input ); + mlt_events_fire( event_object, "link-create-done", service, input, obj, NULL ); + } + + if ( obj != NULL ) + { + mlt_properties properties = MLT_LINK_PROPERTIES( obj ); + set_common_properties( properties, NULL, "link", service ); + } + return obj; +} + /** Fetch a transition from the repository. * * \param profile the \p mlt_profile to use diff --git a/src/framework/mlt_factory.h b/src/framework/mlt_factory.h index 57660ab45..0861411a4 100644 --- a/src/framework/mlt_factory.h +++ b/src/framework/mlt_factory.h @@ -53,6 +53,7 @@ extern int mlt_environment_set( const char *name, const char *value ); extern mlt_properties mlt_factory_event_object( ); extern mlt_producer mlt_factory_producer( mlt_profile profile, const char *service, const void *resource ); extern mlt_filter mlt_factory_filter( mlt_profile profile, const char *name, const void *input ); +extern mlt_link mlt_factory_link( const char *name, const void *input ); extern mlt_transition mlt_factory_transition( mlt_profile profile, const char *name, const void *input ); extern mlt_consumer mlt_factory_consumer( mlt_profile profile, const char *name, const void *input ); extern void mlt_factory_register_for_clean_up( void *ptr, mlt_destructor destructor ); diff --git a/src/framework/mlt_link.c b/src/framework/mlt_link.c new file mode 100644 index 000000000..f10872cb5 --- /dev/null +++ b/src/framework/mlt_link.c @@ -0,0 +1,130 @@ +/** + * \file mlt_link.c + * \brief link service class + * \see mlt_link_s + * + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "mlt_link.h" +#include "mlt_frame.h" +#include "mlt_log.h" + +#include +#include + +/* Forward references to static methods. +*/ + +static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int track ); + +/** Construct a link. + * + * Sets the mlt_type to "link" + * + * \public \memberof mlt_link_s + * \return the new link + */ + +mlt_link mlt_link_init( ) +{ + mlt_link self = calloc( 1, sizeof( struct mlt_link_s ) ); + if ( self != NULL ) + { + mlt_producer producer = &self->parent; + if ( mlt_producer_init( producer, self ) == 0 ) + { + mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); + + mlt_properties_set( properties, "mlt_type", "link" ); + mlt_properties_clear( properties, "mlt_service"); + mlt_properties_clear( properties, "resource"); + mlt_properties_clear( properties, "in"); + mlt_properties_clear( properties, "out"); + mlt_properties_clear( properties, "length"); + mlt_properties_clear( properties, "eof"); + producer->get_frame = producer_get_frame; + producer->close = ( mlt_destructor )mlt_link_close; + producer->close_object = self; + } + else + { + free( self ); + self = NULL; + } + } + return self; +} + +/** Connect this link to the next producer. + * + * \public \memberof mlt_link_s + * \param self a link + * \param next the producer to get frames from + * \param default_profile a profile to use if needed (some links derive their frame rate from the next producer) + * \return true on error + */ + +int mlt_link_connect_next( mlt_link self, mlt_producer next, mlt_profile default_profile ) +{ + self->next = next; + if ( self->configure ) + { + self->configure( self, default_profile ); + } + return 0; +} + +/** Close the link and free its resources. + * + * \public \memberof mlt_link_s + * \param self a link + */ + +void mlt_link_close( mlt_link self ) +{ + if ( self != NULL && mlt_properties_dec_ref( MLT_LINK_PROPERTIES( self ) ) <= 0 ) + { + if( self->close ) + { + self->close( self ); + } + else + { + self->parent.close = NULL; + mlt_producer_close( &self->parent ); + } + } +} + +static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ) +{ + if ( parent && parent->child ) + { + mlt_link self = parent->child; + if ( self->get_frame != NULL ) + { + return self->get_frame( self, frame, index ); + } + else + { + /* Default implementation: get a frame from the next producer */ + return mlt_service_get_frame( MLT_PRODUCER_SERVICE( self->next ), frame, index ); + } + } + return 1; +} diff --git a/src/framework/mlt_link.h b/src/framework/mlt_link.h new file mode 100644 index 000000000..bd8c61d81 --- /dev/null +++ b/src/framework/mlt_link.h @@ -0,0 +1,74 @@ +/** + * \file mlt_link.h + * \brief link service class + * \see mlt_link_s + * + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MLT_LINK_H +#define MLT_LINK_H + +#include "mlt_producer.h" + +/** \brief Link class + * + * The link is a producer class that that can be connected to other link producers in a Chain. + * + * \extends mlt_producer_s + * \properties \em next holds a reference to the next producer in the chain + */ + +struct mlt_link_s +{ + /** \publicsection */ + struct mlt_producer_s parent; + + /** \protectedsection */ + + /** Get a frame of data (virtual function). + * + * \param mlt_link a link + * \param mlt_frame_ptr a frame pointer by reference + * \param int an index + * \return true if there was an error + */ + int ( *get_frame )( mlt_link, mlt_frame_ptr, int ); + + /** Configure the link (virtual function). + * + * \param mlt_link a link + * \param mlt_profile a default profile to use + */ + void ( *configure )( mlt_link, mlt_profile ); + + /** Virtual close function */ + void ( *close )( mlt_link ); + + /** \privatesection */ + mlt_producer next; +}; + +#define MLT_LINK_PRODUCER( link ) ( &( link )->parent ) +#define MLT_LINK_SERVICE( link ) MLT_PRODUCER_SERVICE( MLT_LINK_PRODUCER( link ) ) +#define MLT_LINK_PROPERTIES( link ) MLT_SERVICE_PROPERTIES( MLT_LINK_SERVICE( link ) ) + +extern mlt_link mlt_link_init( ); +extern int mlt_link_connect_next( mlt_link self, mlt_producer next, mlt_profile default_profile ); +extern void mlt_link_close( mlt_link self ); + +#endif diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index 8cff00664..30d288503 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -321,7 +321,11 @@ int mlt_producer_seek( mlt_producer self, mlt_position position ) mlt_producer_seek( mlt_producer_cut_parent( self ), position + mlt_producer_get_in( self ) ); // Check bounds - if ( position < 0 || mlt_producer_get_playtime( self ) == 0 ) + if( mlt_service_identify( MLT_PRODUCER_SERVICE(self) ) == link_type ) + { + // Do not bounds check a link. + } + else if ( position < 0 || mlt_producer_get_playtime( self ) == 0 ) { position = 0; } diff --git a/src/framework/mlt_repository.c b/src/framework/mlt_repository.c index 814207393..d5638280a 100644 --- a/src/framework/mlt_repository.c +++ b/src/framework/mlt_repository.c @@ -47,6 +47,7 @@ struct mlt_repository_s struct mlt_properties_s parent; /// a list of object files mlt_properties consumers; /// a list of entry points for consumers mlt_properties filters; /// a list of entry points for filters + mlt_properties links; /// a list of entry points for links mlt_properties producers; /// a list of entry points for producers mlt_properties transitions; /// a list of entry points for transitions }; @@ -69,6 +70,7 @@ mlt_repository mlt_repository_init( const char *directory ) mlt_properties_init( &self->parent, self ); self->consumers = mlt_properties_new(); self->filters = mlt_properties_new(); + self->links = mlt_properties_new(); self->producers = mlt_properties_new(); self->transitions = mlt_properties_new(); @@ -178,6 +180,9 @@ void mlt_repository_register( mlt_repository self, mlt_service_type service_type case filter_type: mlt_properties_set_data( self->filters, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); break; + case link_type: + mlt_properties_set_data( self->links, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); + break; case producer_type: mlt_properties_set_data( self->producers, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); break; @@ -185,6 +190,7 @@ void mlt_repository_register( mlt_repository self, mlt_service_type service_type mlt_properties_set_data( self->transitions, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); break; default: + mlt_log_error( NULL, "%s: Unable to register \"%s\"\n", __FUNCTION__, service ); break; } } @@ -211,6 +217,9 @@ static mlt_properties get_service_properties( mlt_repository self, mlt_service_t case filter_type: service_properties = mlt_properties_get_data( self->filters, service, NULL ); break; + case link_type: + service_properties = mlt_properties_get_data( self->links, service, NULL ); + break; case producer_type: service_properties = mlt_properties_get_data( self->producers, service, NULL ); break; @@ -286,6 +295,18 @@ mlt_properties mlt_repository_filters( mlt_repository self ) return self->filters; } +/** Get the list of registered links. + * + * \public \memberof mlt_repository_s + * \param self a repository + * \return a properties list of all of the links + */ + +mlt_properties mlt_repository_links( mlt_repository self ) +{ + return self->links; +} + /** Get the list of registered producers. * * \public \memberof mlt_repository_s diff --git a/src/framework/mlt_repository.h b/src/framework/mlt_repository.h index f004b6d0e..c17cf9610 100644 --- a/src/framework/mlt_repository.h +++ b/src/framework/mlt_repository.h @@ -59,6 +59,7 @@ extern void *mlt_repository_create( mlt_repository self, mlt_profile profile, ml extern void mlt_repository_close( mlt_repository self ); extern mlt_properties mlt_repository_consumers( mlt_repository self ); extern mlt_properties mlt_repository_filters( mlt_repository self ); +extern mlt_properties mlt_repository_links( mlt_repository self ); extern mlt_properties mlt_repository_producers( mlt_repository self ); extern mlt_properties mlt_repository_transitions( mlt_repository self ); extern void mlt_repository_register_metadata( mlt_repository self, mlt_service_type type, const char *service, mlt_metadata_callback, void *callback_data ); diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c index 91919d5f9..05f8a7079 100644 --- a/src/framework/mlt_service.c +++ b/src/framework/mlt_service.c @@ -179,8 +179,12 @@ mlt_service_type mlt_service_identify( mlt_service self ) type = filter_type; else if ( !strcmp( mlt_type, "transition" ) ) type = transition_type; + else if ( !strcmp( mlt_type, "chain" ) ) + type = chain_type; else if ( !strcmp( mlt_type, "consumer" ) ) type = consumer_type; + else if ( !strcmp( mlt_type, "link" ) ) + type = link_type; else type = unknown_type; } diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index 6e10df973..583c0c733 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -148,7 +148,9 @@ typedef enum filter_type, /**< Filter class */ transition_type, /**< Transition class */ consumer_type, /**< Consumer class */ - field_type /**< Field class */ + field_type, /**< Field class */ + link_type, /**< Link class */ + chain_type /**< Chain class */ } mlt_service_type; @@ -208,6 +210,8 @@ typedef struct mlt_cache_s *mlt_cache; /**< pointer to Cache ob typedef struct mlt_cache_item_s *mlt_cache_item; /**< pointer to CacheItem object */ typedef struct mlt_animation_s *mlt_animation; /**< pointer to Property Animation object */ typedef struct mlt_slices_s *mlt_slices; /**< pointer to Sliced processing context object */ +typedef struct mlt_link_s *mlt_link; /**< pointer to Link object */ +typedef struct mlt_chain_s *mlt_chain; /**< pointer to Chain object */ typedef void ( *mlt_destructor )( void * ); /**< pointer to destructor function */ typedef char *( *mlt_serialiser )( void *, int length );/**< pointer to serialization function */ @@ -221,6 +225,8 @@ typedef char *( *mlt_serialiser )( void *, int length );/**< pointer to serializ #define MLT_TRANSITION(x) ( ( mlt_transition )( x ) ) /**< Cast to a Transition pointer */ #define MLT_CONSUMER(x) ( ( mlt_consumer )( x ) ) /**< Cast to a Consumer pointer */ #define MLT_FRAME(x) ( ( mlt_frame )( x ) ) /**< Cast to a Frame pointer */ +#define MLT_LINK(x) ( ( mlt_link )( x ) ) /**< Cast to a Link pointer */ +#define MLT_CHAIN(x) ( ( mlt_chain )( x ) ) /**< Cast to a Chain pointer */ #ifndef MIN #define MIN(x, y) ((x) < (y) ? (x) : (y)) diff --git a/src/mlt++/Makefile b/src/mlt++/Makefile index f1acead1e..f3839d2ee 100644 --- a/src/mlt++/Makefile +++ b/src/mlt++/Makefile @@ -28,6 +28,7 @@ endif OBJS = MltAudio.o \ MltAnimation.o \ + MltChain.o \ MltConsumer.o \ MltDeque.o \ MltEvent.o \ @@ -38,6 +39,7 @@ OBJS = MltAudio.o \ MltFilteredProducer.o \ MltFrame.o \ MltGeometry.o \ + MltLink.o \ MltMultitrack.o \ MltParser.o \ MltPlaylist.o \ diff --git a/src/mlt++/Mlt.h b/src/mlt++/Mlt.h index 89ed7fe6e..93d7f8377 100644 --- a/src/mlt++/Mlt.h +++ b/src/mlt++/Mlt.h @@ -23,6 +23,7 @@ #include "MltAudio.h" #include "MltAnimation.h" +#include "MltChain.h" #include "MltConsumer.h" #include "MltDeque.h" #include "MltEvent.h" diff --git a/src/mlt++/MltChain.cpp b/src/mlt++/MltChain.cpp new file mode 100644 index 000000000..94aee894d --- /dev/null +++ b/src/mlt++/MltChain.cpp @@ -0,0 +1,123 @@ +/** + * MltChain.cpp - Chain wrapper + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "MltChain.h" + +using namespace Mlt; + +Chain::Chain( ) : + instance( nullptr ) +{ +} + +Chain::Chain( Profile& profile, const char *id, const char *service ) : + instance( mlt_chain_init( profile.get_profile() ) ) +{ + Mlt::Producer source( profile, id, service ); + mlt_chain_set_source( instance, source.get_producer() ); +} + +Chain::Chain( Profile& profile ) : + instance( mlt_chain_init( profile.get_profile() ) ) +{ +} + +Chain::Chain( mlt_chain chain ) : + instance( chain ) +{ + inc_ref( ); +} + +Chain::Chain( Chain& chain ) : + Mlt::Producer( chain ), + instance( chain.get_chain( ) ) +{ + inc_ref( ); +} + +Chain::Chain( Chain* chain ) : + Mlt::Producer( chain ), + instance( chain != NULL ? chain->get_chain( ) : NULL ) +{ + if ( is_valid( ) ) + inc_ref( ); +} + +Chain::Chain( Service& chain ) : + instance( NULL ) +{ + if ( chain.type( ) == chain_type ) + { + instance = ( mlt_chain )chain.get_service( ); + inc_ref( ); + } +} + +Chain::~Chain( ) +{ + mlt_chain_close( instance ); + instance = nullptr; +} + +mlt_chain Chain::get_chain( ) +{ + return instance; +} + +mlt_producer Chain::get_producer( ) +{ + return MLT_CHAIN_PRODUCER( instance ); +} + +void Chain::set_source( Mlt::Producer& source ) +{ + mlt_chain_set_source( instance, source.get_producer() ); +} + +Mlt::Producer Chain::get_source( ) +{ + return Mlt::Producer( mlt_chain_get_source(instance) ); +} + +int Chain::attach( Mlt::Link& link ) +{ + return mlt_chain_attach( instance, link.get_link() ); +} + +int Chain::detach( Mlt::Link& link ) +{ + return mlt_chain_detach( instance, link.get_link() ); +} + +int Chain::link_count() const +{ + return mlt_chain_link_count( instance ); +} + +bool Chain::move_link( int from, int to ) +{ + return (bool)mlt_chain_move_link( instance, from, to ); +} + +Mlt::Link* Chain::link( int index ) +{ + mlt_link result = mlt_chain_link( instance, index ); + return result == NULL ? NULL : new Link( result ); + +} diff --git a/src/mlt++/MltChain.h b/src/mlt++/MltChain.h new file mode 100644 index 000000000..acd756824 --- /dev/null +++ b/src/mlt++/MltChain.h @@ -0,0 +1,59 @@ +/** + * MltChain.h - Chain wrapper + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MLTPP_CHAIN_H +#define MLTPP_CHAIN_H + +#include "MltConfig.h" + +#include + +#include "MltLink.h" +#include "MltProducer.h" +#include "MltProfile.h" + +namespace Mlt +{ + class MLTPP_DECLSPEC Chain : public Producer + { + private: + mlt_chain instance; + public: + Chain( ); + Chain( Profile& profile, const char *id, const char *service = NULL ); + Chain( Mlt::Profile& profile ); + Chain( mlt_chain chain ); + Chain( Chain& chain ); + Chain( Chain* chain ); + Chain( Service& chain ); + virtual ~Chain( ); + virtual mlt_chain get_chain( ); + mlt_producer get_producer( ); + void set_source( Mlt::Producer& source ); + Mlt::Producer get_source( ); + int attach( Mlt::Link& link ); + int detach( Mlt::Link& link ); + int link_count() const; + bool move_link( int from, int to ); + Mlt::Link* link( int index ); + }; +} + +#endif + diff --git a/src/mlt++/MltLink.cpp b/src/mlt++/MltLink.cpp new file mode 100644 index 000000000..08b204f77 --- /dev/null +++ b/src/mlt++/MltLink.cpp @@ -0,0 +1,82 @@ +/** + * MltLink.cpp - MLT Wrapper + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "MltLink.h" +#include "MltProfile.h" + +#include +#include + +using namespace Mlt; + +Link::Link( ) : + instance( nullptr ) +{ +} + +Link::Link( mlt_link link ) + : instance( link ) +{ + inc_ref( ); +} + +Link::Link( const char *id, const char *arg ) : + instance( NULL ) +{ + if ( arg != NULL ) + { + instance = mlt_factory_link( id, arg ); + } + else + { + if ( strchr( id, ':' ) ) + { + char *temp = strdup( id ); + char *arg = strchr( temp, ':' ) + 1; + *( arg - 1 ) = '\0'; + instance = mlt_factory_link( temp, arg ); + free( temp ); + } + else + { + instance = mlt_factory_link( id, NULL ); + } + } +} + +Link::~Link( ) +{ + mlt_link_close( instance ); +} + +mlt_link Link::get_link( ) +{ + return instance; +} + +mlt_producer Link::get_producer( ) +{ + return MLT_LINK_PRODUCER( instance ); +} + +int Link::connect_next( Mlt::Producer& next, Mlt::Profile& default_profile ) +{ + return mlt_link_connect_next( instance, next.get_producer(), default_profile.get_profile() ); +} + diff --git a/src/mlt++/MltLink.h b/src/mlt++/MltLink.h new file mode 100644 index 000000000..a9825a3cd --- /dev/null +++ b/src/mlt++/MltLink.h @@ -0,0 +1,49 @@ +/** + * MltLink.h - MLT Wrapper + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MLTPP_LINK_H +#define MLTPP_LINK_H + +#include "MltConfig.h" +#include "MltProducer.h" +#include "MltProducer.h" + +#include + +namespace Mlt +{ + class Producer; + class Profile; + + class MLTPP_DECLSPEC Link : public Producer + { + private: + mlt_link instance; + public: + Link( ); + Link( mlt_link link ); + Link( const char* id, const char* service = NULL ); + virtual ~Link( ); + virtual mlt_link get_link( ); + mlt_producer get_producer( ); + int connect_next( Mlt::Producer& next, Mlt::Profile& default_profile ); + }; +} + +#endif diff --git a/src/mlt++/MltProducer.cpp b/src/mlt++/MltProducer.cpp index b196f6dc6..4a061695f 100644 --- a/src/mlt++/MltProducer.cpp +++ b/src/mlt++/MltProducer.cpp @@ -51,7 +51,8 @@ Producer::Producer( Service &producer ) : { mlt_service_type type = producer.type( ); if ( type == producer_type || type == playlist_type || - type == tractor_type || type == multitrack_type ) + type == tractor_type || type == multitrack_type || + type == chain_type || type == link_type ) { instance = ( mlt_producer )producer.get_service( ); inc_ref( ); diff --git a/src/mlt++/MltRepository.cpp b/src/mlt++/MltRepository.cpp index 264f9453b..ecfe931ef 100644 --- a/src/mlt++/MltRepository.cpp +++ b/src/mlt++/MltRepository.cpp @@ -58,6 +58,11 @@ Properties *Repository::filters( ) const return new Properties( mlt_repository_filters( instance ) ); } +Properties *Repository::links( ) const +{ + return new Properties( mlt_repository_links( instance ) ); +} + Properties *Repository::producers( ) const { return new Properties( mlt_repository_producers( instance ) ); diff --git a/src/mlt++/MltRepository.h b/src/mlt++/MltRepository.h index 52a0ab76f..f2a9ffb80 100644 --- a/src/mlt++/MltRepository.h +++ b/src/mlt++/MltRepository.h @@ -47,6 +47,7 @@ namespace Mlt void *create( Profile& profile, mlt_service_type type, const char *service, void *arg ); Properties *consumers( ) const; Properties *filters( ) const; + Properties *links( ) const; Properties *producers( ) const; Properties *transitions( ) const; void register_metadata( mlt_service_type type, const char *service, mlt_metadata_callback, void *callback_data ); diff --git a/src/mlt++/mlt++.vers b/src/mlt++/mlt++.vers index f9997ee37..87f4d4475 100644 --- a/src/mlt++/mlt++.vers +++ b/src/mlt++/mlt++.vers @@ -612,3 +612,34 @@ MLTPP_6.22.0 { "Mlt::Audio::set_layout(mlt_channel_layout)"; }; } MLTPP_6.20.0; + +MLTPP_6.24.0 { + global: + extern "C++" { + "Mlt::Link::Link()"; + "Mlt::Link::Link(mlt_link)"; + "Mlt::Link::Link(char const*, char const*)"; + "Mlt::Link::~Link()"; + "Mlt::Link::mlt_link get_link()"; + "Mlt::Link::mlt_producer get_producer()"; + "Mlt::Link::connect_next(Mlt::Producer&, Mlt::Profile&)"; + "Mlt::Chain::Chain()"; + "Mlt::Chain::Chain(Mlt::Profile&, char const*, char const*)"; + "Mlt::Chain::Chain(Mlt::Profile&)"; + "Mlt::Chain::Chain(mlt_chain)"; + "Mlt::Chain::Chain(Mlt::Chain&)"; + "Mlt::Chain::Chain(Mlt::Chain*)"; + "Mlt::Chain::Chain(Mlt::Service&)"; + "Mlt::Chain::~Chain()"; + "Mlt::Chain::get_chain()"; + "Mlt::Chain::get_producer()"; + "Mlt::Chain::set_source(Mlt::Producer&)"; + "Mlt::Chain::get_source()"; + "Mlt::Chain::attach(Mlt::Link&)"; + "Mlt::Chain::detach(Mlt::Link&)"; + "Mlt::Chain::link_count() const"; + "Mlt::Chain::move_link(int, int)"; + "Mlt::Chain::link(int)"; + "Mlt::Repository::links() const"; + }; +} MLTPP_6.22.0; diff --git a/src/modules/avformat/factory.c b/src/modules/avformat/factory.c index e342ff700..c05dcbc97 100644 --- a/src/modules/avformat/factory.c +++ b/src/modules/avformat/factory.c @@ -309,6 +309,12 @@ static mlt_properties avformat_metadata( mlt_service_type type, const char *id, default: return NULL; } + + if ( type == producer_type && !strcmp( id, "avformat-novalidate" ) ) + { + id = "avformat"; + } + // Load the yaml file snprintf( file, PATH_MAX, "%s/avformat/%s_%s.yml", mlt_environment( "MLT_DATA" ), service_type, id ); result = mlt_properties_parse_yaml( file ); @@ -425,6 +431,7 @@ MLT_REPOSITORY MLT_REGISTER( producer_type, "avformat-novalidate", create_service ); MLT_REGISTER_METADATA( consumer_type, "avformat", avformat_metadata, NULL ); MLT_REGISTER_METADATA( producer_type, "avformat", avformat_metadata, NULL ); + MLT_REGISTER_METADATA( producer_type, "avformat-novalidate", avformat_metadata, NULL ); #endif #ifdef FILTERS MLT_REGISTER( filter_type, "avcolour_space", create_service ); diff --git a/src/modules/core/Makefile b/src/modules/core/Makefile index e524f990c..390b66bdc 100644 --- a/src/modules/core/Makefile +++ b/src/modules/core/Makefile @@ -41,6 +41,7 @@ OBJS = factory.o \ filter_resize.o \ filter_transition.o \ filter_watermark.o \ + link_timeremap.o \ transition_composite.o \ transition_luma.o \ transition_mix.o \ diff --git a/src/modules/core/factory.c b/src/modules/core/factory.c index c959f424d..9828c8198 100644 --- a/src/modules/core/factory.c +++ b/src/modules/core/factory.c @@ -49,6 +49,7 @@ extern mlt_filter filter_rescale_init( mlt_profile profile, mlt_service_type typ extern mlt_filter filter_resize_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_transition_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_watermark_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); +extern mlt_link link_timeremap_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_producer producer_colour_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_producer producer_consumer_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_producer producer_hold_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); @@ -103,6 +104,7 @@ MLT_REPOSITORY MLT_REGISTER( filter_type, "resize", filter_resize_init ); MLT_REGISTER( filter_type, "transition", filter_transition_init ); MLT_REGISTER( filter_type, "watermark", filter_watermark_init ); + MLT_REGISTER( link_type, "timeremap", link_timeremap_init ); MLT_REGISTER( producer_type, "abnormal", producer_loader_init ); MLT_REGISTER( producer_type, "color", producer_colour_init ); MLT_REGISTER( producer_type, "colour", producer_colour_init ); @@ -145,6 +147,7 @@ MLT_REPOSITORY MLT_REGISTER_METADATA( filter_type, "resize", metadata, "filter_resize.yml" ); MLT_REGISTER_METADATA( filter_type, "transition", metadata, "filter_transition.yml" ); MLT_REGISTER_METADATA( filter_type, "watermark", metadata, "filter_watermark.yml" ); + MLT_REGISTER_METADATA( link_type, "timeremap", metadata, "link_timeremap.yml" ); MLT_REGISTER_METADATA( producer_type, "colour", metadata, "producer_colour.yml" ); MLT_REGISTER_METADATA( producer_type, "color", metadata, "producer_colour.yml" ); MLT_REGISTER_METADATA( producer_type, "consumer", metadata, "producer_consumer.yml" ); diff --git a/src/modules/core/link_timeremap.c b/src/modules/core/link_timeremap.c new file mode 100644 index 000000000..536a9a2e5 --- /dev/null +++ b/src/modules/core/link_timeremap.c @@ -0,0 +1,421 @@ +/* + * link_timeremap.c + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +static void link_configure( mlt_link self, mlt_profile default_profile ) +{ + mlt_service_set_profile( MLT_LINK_SERVICE( self ), default_profile ); +} + +static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* format, int* frequency, int* channels, int* samples ) +{ + mlt_link self = (mlt_link)mlt_frame_pop_audio( frame ); + mlt_properties unique_properties = mlt_frame_get_unique_properties( frame, MLT_LINK_SERVICE(self) ); + if ( !unique_properties ) + { + return 1; + } + double source_time = mlt_properties_get_double( unique_properties, "source_time" ); + double source_duration = mlt_properties_get_double( unique_properties, "source_duration" ); + double source_fps = mlt_properties_get_double( unique_properties, "source_fps" ); + double link_fps = mlt_producer_get_fps( MLT_LINK_PRODUCER( self ) ); + double frame_duration = 1.0 / link_fps; + double speed = 0.0; + if ( source_duration != 0.0 ) + { + speed = fabs(source_duration) / frame_duration; + } + + // Validate the request + *channels = *channels <= 0 ? 2 : *channels; + int src_frequency = mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "audio_frequency" ); + if ( src_frequency > 0 ) + { + *frequency = src_frequency; + } + else if ( *frequency <= 0 ) + { + *frequency = 48000; + } + + if ( speed < 0.1 || speed > 10 ) + { + // Return silent samples for speeds less than 0.1 or > 10 + mlt_position position = mlt_frame_original_position( frame ); + *samples = mlt_sample_calculator( link_fps, *frequency, position ); + int size = mlt_audio_format_size( *format, *samples, *channels ); + *audio = mlt_pool_alloc( size ); + memset( *audio, 0, size ); + mlt_frame_set_audio( frame, *audio, *format, size, mlt_pool_release ); + return 0; + } + else + { + int sample_count = mlt_sample_calculator( link_fps, *frequency, mlt_frame_get_position( frame ) ); + sample_count = lrint( (double)sample_count * speed ); + mlt_position in_frame_pos = floor( source_time * source_fps ); + + // Calculate the samples to get from the input frames + int64_t first_out_sample = source_time * (double)*frequency; + int64_t first_in_sample = mlt_sample_calculator_to_now( source_fps, *frequency, in_frame_pos ); + int samples_to_skip = first_out_sample - first_in_sample; + if ( samples_to_skip < 0 ) + { + mlt_log_error( MLT_LINK_SERVICE(self), "Audio too late: %d\t%d\n", (int)first_out_sample, (int)first_in_sample ); + samples_to_skip = 0; + } + + // Allocate the out buffer + struct mlt_audio_s out; + mlt_audio_set_values( &out, NULL, *frequency, *format, sample_count, *channels ); + mlt_audio_alloc_data( &out ); + + // Copy audio from the input frames to the output buffer + int samples_copied = 0; + int samples_needed = sample_count; + + while ( samples_needed > 0 ) + { + char key[19]; + sprintf( key, "%d", in_frame_pos ); + mlt_frame src_frame = (mlt_frame)mlt_properties_get_data( unique_properties, key, NULL ); + if ( !src_frame ) + { + mlt_log_error( MLT_LINK_SERVICE(self), "Frame not found: %d\n", in_frame_pos ); + break; + } + + int in_samples = mlt_sample_calculator( source_fps, *frequency, in_frame_pos ); + struct mlt_audio_s in; + mlt_audio_set_values( &in, NULL, *frequency, *format, in_samples, *channels ); + + int error = mlt_frame_get_audio( src_frame, &in.data, &in.format, &in.frequency, &in.channels, &in.samples ); + if ( error ) + { + mlt_log_error( MLT_LINK_SERVICE(self), "No audio: %d\n", in_frame_pos ); + break; + } + + int samples_to_copy = in.samples - samples_to_skip; + if ( samples_to_copy > samples_needed ) + { + samples_to_copy = samples_needed; + } + mlt_log_debug( MLT_LINK_SERVICE(self), "Copy: %d\t%d\t%d\t%d\n", samples_to_skip, samples_to_skip + samples_to_copy -1, samples_to_copy, in.samples ); + + if ( samples_to_copy > 0 ) + { + mlt_audio_copy( &out, &in, samples_to_copy, samples_to_skip, samples_copied ); + samples_copied += samples_to_copy; + samples_needed -= samples_to_copy; + } + + samples_to_skip = 0; + in_frame_pos++; + } + + if ( samples_copied != sample_count ) + { + mlt_log_error( MLT_LINK_SERVICE(self), "Sample under run: %d\t%d\n", samples_copied, sample_count ); + mlt_audio_shrink( &out , samples_copied ); + } + + if ( source_duration < 0.0 ) + { + // Going backwards + mlt_audio_reverse( &out ); + } + + out.frequency = lrint( (double)out.frequency * speed ); + mlt_frame_set_audio( frame, out.data, out.format, 0, out.release_data ); + mlt_audio_get_values( &out, audio, frequency, format, samples, channels ); + return 0; + } + + return 1; +} + +static int link_get_image_blend( mlt_frame frame, uint8_t** image, mlt_image_format* format, int* width, int* height, int writable ) +{ + static const int MAX_BLEND_IMAGES = 10; + mlt_link self = (mlt_link)mlt_frame_pop_get_image( frame ); + mlt_properties unique_properties = mlt_frame_get_unique_properties( frame, MLT_LINK_SERVICE(self) ); + if ( !unique_properties ) + { + return 1; + } + double source_time = mlt_properties_get_double( unique_properties, "source_time"); + double source_fps = mlt_properties_get_double( unique_properties, "source_fps"); + + // Get pointers to all the images for this frame + uint8_t* images[MAX_BLEND_IMAGES]; + int image_count = 0; + mlt_position in_frame_pos = floor( source_time * source_fps ); + while ( image_count < MAX_BLEND_IMAGES ) + { + char key[19]; + sprintf( key, "%d", in_frame_pos ); + mlt_frame src_frame = (mlt_frame)mlt_properties_get_data( unique_properties, key, NULL ); + if ( src_frame && !mlt_frame_get_image( src_frame, &images[image_count], format, width, height, 0 ) ) + { + in_frame_pos++; + image_count++; + } + else + { + break; + } + } + + if ( image_count <= 0 ) + { + return 1; + } + + // Sum all the images into one image with 16 bit components + int size = mlt_image_format_size( *format, *width, *height, NULL ); + *image = mlt_pool_alloc( size ); + int s = 0; + uint8_t* p = *image; + for( s = 0; s < size; s++ ) + { + int16_t sum = 0; + int i = 0; + for( i = 0; i < image_count; i++ ) + { + sum += *(images[i]); + images[i]++; + } + *p = sum / image_count; + p++; + } + mlt_frame_set_image( frame, *image, size, mlt_pool_release ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "format", *format ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "width", *width ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "height", *height ); + + return 0; +} + +static int link_get_image_nearest( mlt_frame frame, uint8_t** image, mlt_image_format* format, int* width, int* height, int writable ) +{ + mlt_link self = (mlt_link)mlt_frame_pop_get_image( frame ); + mlt_properties unique_properties = mlt_frame_get_unique_properties( frame, MLT_LINK_SERVICE(self) ); + if ( !unique_properties ) + { + return 1; + } + double source_time = mlt_properties_get_double( unique_properties, "source_time"); + double source_fps = mlt_properties_get_double( unique_properties, "source_fps"); + mlt_position in_frame_pos = floor( source_time * source_fps ); + char key[19]; + sprintf( key, "%d", in_frame_pos ); + + mlt_frame src_frame = (mlt_frame)mlt_properties_get_data( unique_properties, key, NULL ); + if ( src_frame ) + { + uint8_t* in_image; + if ( !mlt_frame_get_image( src_frame, &in_image, format, width, height, 0 ) ) + { + int size = mlt_image_format_size( *format, *width, *height, NULL ); + *image = mlt_pool_alloc( size ); + memcpy( *image, in_image, size ); + mlt_frame_set_image( frame, *image, size, mlt_pool_release ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "format", *format ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "width", *width ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "height", *height ); + + uint8_t* in_alpha = mlt_frame_get_alpha( src_frame ); + if ( in_alpha ) + { + size = *width * *height; + uint8_t* out_alpha = mlt_pool_alloc( size ); + memcpy( out_alpha, in_alpha, size ); + mlt_frame_set_alpha( frame, out_alpha, size, mlt_pool_release ); + }; + return 0; + } + } + + return 1; +} + +static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) +{ + mlt_properties properties = MLT_LINK_PROPERTIES( self ); + mlt_position position = mlt_producer_position( MLT_LINK_PRODUCER( self ) ); + mlt_position length = mlt_producer_get_length( MLT_LINK_PRODUCER( self ) ); + double source_time = 0.0; + double source_duration = 0.0; + double source_fps = mlt_producer_get_fps( self->next ); + + int result = 0; + + // Create a frame + *frame = mlt_frame_init( MLT_LINK_SERVICE(self) ); + mlt_frame_set_position( *frame, mlt_producer_position( MLT_LINK_PRODUCER(self) ) ); + mlt_properties unique_properties = mlt_frame_unique_properties( *frame, MLT_LINK_SERVICE(self) ); + + // Calculate the frames from the next link to be used + if ( !mlt_properties_exists( properties, "map" ) ) + { + double link_fps = mlt_producer_get_fps( MLT_LINK_PRODUCER( self ) ); + source_time = (double)position / link_fps; + source_duration = 1.0 / link_fps; + } + else + { + source_time = mlt_properties_anim_get_double( properties, "map", position, length ); + double next_source_time = mlt_properties_anim_get_double( properties, "map", position + 1, length ); + source_duration = next_source_time - source_time; + } + + mlt_properties_set_double( unique_properties, "source_fps", source_fps ); + mlt_properties_set_double( unique_properties, "source_time", source_time ); + mlt_properties_set_double( unique_properties, "source_duration", source_duration ); + + mlt_log_debug( MLT_LINK_SERVICE(self), "Get Frame: %f -> %f\t%d\n", source_fps, mlt_producer_get_fps( MLT_LINK_PRODUCER(self) ), position ); + + // Get frames from the next link and pass them along with the new frame + int in_frame_count = 0; + mlt_frame src_frame = NULL; + mlt_frame prev_frame = mlt_properties_get_data( properties, "_prev_frame", NULL ); + mlt_position prev_frame_position = prev_frame ? mlt_frame_get_position( prev_frame ) : -1; + mlt_position in_frame_pos = floor( source_time * source_fps ); + double frame_time = (double)in_frame_pos / source_fps; + double source_end_time = source_time + fabs(source_duration); + if ( frame_time == source_end_time ) + { + // Force one frame to be sent. + source_end_time += 0.0000000001; + } + while ( frame_time < source_end_time ) + { + if( in_frame_pos == prev_frame_position ) + { + // Reuse the previous frame to avoid seeking. + src_frame = prev_frame; + mlt_properties_inc_ref( MLT_FRAME_PROPERTIES(src_frame) ); + } + else + { + mlt_producer_seek( self->next, in_frame_pos ); + result = mlt_service_get_frame( MLT_PRODUCER_SERVICE( self->next ), &src_frame, index ); + if ( result ) + { + break; + } + } + // Save the source frame on the output frame + char key[19]; + sprintf( key, "%d", in_frame_pos ); + mlt_properties_set_data( unique_properties, key, src_frame, 0, (mlt_destructor)mlt_frame_close, NULL ); + + // Calculate the next frame + in_frame_pos++; + frame_time = (double)in_frame_pos / source_fps; + in_frame_count++; + } + + if ( !src_frame ) + { + mlt_frame_close( *frame ); + *frame = NULL; + return 1; + } + + // Copy some useful properties from one of the source frames. + (*frame)->convert_image = src_frame->convert_image; + (*frame)->convert_audio = src_frame->convert_audio; + mlt_properties_pass_list( MLT_FRAME_PROPERTIES(*frame), MLT_FRAME_PROPERTIES(src_frame), "audio_frequency" ); + + if ( src_frame != prev_frame ) + { + // Save the last source frame because it might be requested for the next frame. + mlt_properties_inc_ref( MLT_FRAME_PROPERTIES(src_frame) ); + mlt_properties_set_data( properties, "_prev_frame", src_frame, 0, (mlt_destructor)mlt_frame_close, NULL ); + } + + // Setup callbacks + char* mode = mlt_properties_get( properties, "image_mode" ); + mlt_frame_push_get_image( *frame, (void*)self ); + if ( in_frame_count == 1 || !mode || !strcmp( mode, "nearest" ) ) + { + mlt_frame_push_get_image( *frame, link_get_image_nearest ); + } + else + { + mlt_frame_push_get_image( *frame, link_get_image_blend ); + } + + mlt_frame_push_audio( *frame, (void*)self ); + mlt_frame_push_audio( *frame, link_get_audio ); + + // Apply a resampler + mlt_filter resampler = (mlt_filter)mlt_properties_get_data( properties, "_resampler", NULL ); + if ( !resampler ) + { + resampler = mlt_factory_filter( mlt_service_profile( MLT_LINK_SERVICE(self) ), "resample", NULL ); + if ( !resampler ) + { + resampler = mlt_factory_filter( mlt_service_profile( MLT_LINK_SERVICE(self) ), "swresample", NULL ); + } + if( resampler ) + { + mlt_properties_set_data( properties, "_resampler", resampler, 0, (mlt_destructor)mlt_filter_close, NULL ); + } + } + if ( resampler ) + { + mlt_filter_process( resampler, *frame ); + } + + mlt_producer_prepare_next( MLT_LINK_PRODUCER( self ) ); + + return result; +} + +static void link_close( mlt_link self ) +{ + self->close = NULL; + mlt_link_close( self ); + free( self ); +} + +mlt_link link_timeremap_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) +{ + mlt_link self = mlt_link_init(); + if ( self != NULL ) + { + // Callback registration + self->configure = link_configure; + self->get_frame = link_get_frame; + self->close = link_close; + } + return self; +} diff --git a/src/modules/core/link_timeremap.yml b/src/modules/core/link_timeremap.yml new file mode 100644 index 000000000..e2ddc2e29 --- /dev/null +++ b/src/modules/core/link_timeremap.yml @@ -0,0 +1,27 @@ +schema_version: 0.3 +type: link +identifier: timeremap +title: Time Remap +version: 1 +copyright: Meltytech, LLC +license: LGPLv2.1 +language: en +tags: + - Audio + - Video +description: Remap frames in time. +parameters: + - identifier: map + title: Map + type: float + description: > + A map of input frame times to output frame times. + mutable: yes + - identifier: image_mode + title: Image Mode + type: string + description: The image mode to use. + values: + - nearest # Output the nearest frame + - blend # Blend the frames that make up the output + mutable: yes diff --git a/src/modules/core/producer_melt.c b/src/modules/core/producer_melt.c index 9d9cc8a67..f704831fc 100644 --- a/src/modules/core/producer_melt.c +++ b/src/modules/core/producer_melt.c @@ -130,6 +130,19 @@ static mlt_transition create_transition( mlt_profile profile, mlt_field field, c return transition; } +static mlt_link create_link( mlt_field field, char *id ) +{ + char *temp = strdup( id ); + char *arg = strchr( temp, ':' ); + if ( arg != NULL ) + *arg ++ = '\0'; + mlt_link link = mlt_factory_link( temp, arg ); + if ( link != NULL ) + track_service( field, link, ( mlt_destructor )mlt_link_close ); + free( temp ); + return link; +} + mlt_producer producer_melt_init( mlt_profile profile, mlt_service_type type, const char *id, char **argv ) { int i; @@ -143,6 +156,7 @@ mlt_producer producer_melt_init( mlt_profile profile, mlt_service_type type, con mlt_field field = mlt_tractor_field( tractor ); mlt_properties field_properties = mlt_field_properties( field ); mlt_multitrack multitrack = mlt_tractor_multitrack( tractor ); + mlt_chain chain = NULL; char *title = NULL; // Assistance for template construction (allows -track usage to specify the first track) @@ -418,6 +432,41 @@ mlt_producer producer_melt_init( mlt_profile profile, mlt_service_type type, con mlt_properties_set_int( properties, "hide", 2 ); } } + else if ( !strcmp( argv[ i ], "-chain" ) ) + { + if ( chain == NULL && producer != NULL && !mlt_producer_is_cut( producer ) ) + mlt_playlist_append( playlist, producer ); + else if ( chain != NULL && mlt_chain_get_source( chain ) != NULL ) + { + mlt_playlist_append( playlist, producer ); + } + + chain = mlt_chain_init( profile ); + if ( chain != NULL ) + { + producer = MLT_CHAIN_PRODUCER( chain ); + properties = MLT_PRODUCER_PROPERTIES( producer ); + mlt_properties_inherit( properties, group ); + track_service( field, chain, ( mlt_destructor )mlt_chain_close ); + } + } + else if ( !strcmp( argv[ i ], "-link" ) ) + { + if ( chain == NULL || mlt_chain_get_source( chain ) == NULL ) + { + fprintf( stderr, "A link can only be added to a chain with a producer.\n" ); + } + else + { + mlt_link link = create_link( field, argv[ ++ i ] ); + if ( link != NULL ) + { + mlt_chain_attach( chain, link ); + properties = MLT_LINK_PROPERTIES( link ); + mlt_properties_inherit( properties, group ); + } + } + } else if ( strchr( argv[ i ], '=' ) && strstr( argv[ i ], "transition_count ++ ); break; + case xml_chain: + sprintf( temp, "chain%d", context->chain_count ++ ); + break; + case xml_link: + sprintf( temp, "link%d", context->link_count ++ ); + break; case xml_existing: // Never gets here break; @@ -606,6 +616,74 @@ static void serialise_transition( serialise_context context, mlt_service service } } +static void serialise_link( serialise_context context, mlt_service service, xmlNode *node ) +{ + xmlNode *child = node; + mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); + + if ( context->pass == 0 ) + { + // Get a new id - if already allocated, do nothing + char *id = xml_get_id( context, service, xml_link ); + if ( id == NULL ) + return; + + child = xmlNewChild( node, NULL, _x("link"), NULL ); + + // Set the id + xmlNewProp( child, _x("id"), _x(id) ); + if ( mlt_properties_get( properties, "title" ) ) + xmlNewProp( child, _x("title"), _x(mlt_properties_get( properties, "title" )) ); + if ( mlt_properties_get_position( properties, "in" ) ) + xmlNewProp( child, _x("in"), _x( mlt_properties_get_time( properties, "in", context->time_format ) ) ); + if ( mlt_properties_get_position( properties, "out" ) ) + xmlNewProp( child, _x("out"), _x( mlt_properties_get_time( properties, "out", context->time_format ) ) ); + + serialise_properties( context, properties, child ); + serialise_service_filters( context, service, child ); + } +} + +static void serialise_chain( serialise_context context, mlt_service service, xmlNode *node ) +{ + int i = 0; + xmlNode *child = node; + mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); + + if ( context->pass == 0 ) + { + // Get a new id - if already allocated, do nothing + char *id = xml_get_id( context, service, xml_chain ); + if ( id == NULL ) + return; + + child = xmlNewChild( node, NULL, _x("chain"), NULL ); + + // Set the id + xmlNewProp( child, _x("id"), _x(id) ); + if ( mlt_properties_get( properties, "title" ) ) + xmlNewProp( child, _x("title"), _x(mlt_properties_get( properties, "title" )) ); + if ( mlt_properties_get_position( properties, "in" ) ) + xmlNewProp( child, _x("in"), _x( mlt_properties_get_time( properties, "in", context->time_format ) ) ); + if ( mlt_properties_get_position( properties, "out" ) ) + xmlNewProp( child, _x("out"), _x( mlt_properties_get_time( properties, "out", context->time_format ) ) ); + + serialise_properties( context, properties, child ); + + // Serialize links + for ( i = 0; i < mlt_chain_link_count( MLT_CHAIN( service ) ); i++ ) + { + mlt_link link = mlt_chain_link( MLT_CHAIN( service ), i ); + if ( link ) + { + serialise_link( context, MLT_LINK_SERVICE(link), child ); + } + } + + serialise_service_filters( context, service, child ); + } +} + static void serialise_service( serialise_context context, mlt_service service, xmlNode *node ) { // Iterate over consumer/producer connections @@ -664,6 +742,15 @@ static void serialise_service( serialise_context context, mlt_service service, x break; } + // Treat it as a normal chain + else if ( mlt_properties_get_int( properties, "_original_type" ) == chain_type ) + { + serialise_chain( context, service, node ); + mlt_properties_set( properties, "mlt_type", "chain" ); + if ( mlt_properties_get( properties, "xml" ) != NULL ) + break; + } + // Treat it as a normal producer else { @@ -673,6 +760,13 @@ static void serialise_service( serialise_context context, mlt_service service, x } } + // Tell about a chain + else if ( strcmp( mlt_type, "chain" ) == 0 ) + { + serialise_chain( context, service, node ); + break; + } + // Tell about a filter else if ( strcmp( mlt_type, "filter" ) == 0 ) { @@ -807,6 +901,7 @@ xmlDocPtr xml_make_doc( mlt_consumer consumer, mlt_service service ) context->hide_map = mlt_properties_new(); // Ensure producer is a framework producer + mlt_properties_set_int( properties, "_original_type", mlt_service_identify( service ) ); mlt_properties_set( MLT_SERVICE_PROPERTIES( service ), "mlt_type", "mlt_producer" ); // In pass one, we serialise the end producers and playlists, diff --git a/src/modules/xml/producer_xml.c b/src/modules/xml/producer_xml.c index ad3ad02dd..3283aad8b 100644 --- a/src/modules/xml/producer_xml.c +++ b/src/modules/xml/producer_xml.c @@ -60,7 +60,9 @@ enum service_type mlt_dummy_filter_type, mlt_dummy_transition_type, mlt_dummy_producer_type, - mlt_dummy_consumer_type + mlt_dummy_consumer_type, + mlt_chain_type, + mlt_link_type, }; struct deserialise_context_s @@ -571,6 +573,194 @@ static void on_end_playlist( deserialise_context context, const xmlChar *name ) } } +static void on_start_chain( deserialise_context context, const xmlChar *name, const xmlChar **atts) +{ + mlt_chain chain = mlt_chain_init( context->profile ); + mlt_service service = MLT_CHAIN_SERVICE( chain ); + mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); + + track_service( context->destructors, service, (mlt_destructor) mlt_chain_close ); + + for ( ; atts != NULL && *atts != NULL; atts += 2 ) + { + mlt_properties_set_string( properties, (const char*) atts[0], atts[1] == NULL ? "" : (const char*) atts[1] ); + + // Out will be overwritten later as we append, so we need to save it + if ( xmlStrcmp( atts[ 0 ], _x("out") ) == 0 ) + mlt_properties_set_string( properties, "_xml.out", ( const char* )atts[ 1 ] ); + } + + if ( mlt_properties_get( properties, "id" ) != NULL ) + mlt_properties_set_data( context->producer_map, mlt_properties_get( properties, "id" ), service, 0, NULL, NULL ); + + context_push_service( context, service, mlt_chain_type ); +} + +static void on_end_chain( deserialise_context context, const xmlChar *name ) +{ + // Get the chain from the stack + enum service_type type; + mlt_service service = context_pop_service( context, &type ); + + if ( service != NULL && type == mlt_chain_type ) + { + mlt_chain chain = MLT_CHAIN( service ); + mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); + mlt_position in = -1; + mlt_position out = -1; + mlt_producer source = NULL; + + qualify_property( context, properties, "resource" ); + char *resource = mlt_properties_get( properties, "resource" ); + + // Let Kino-SMIL src be a synonym for resource + if ( resource == NULL ) + { + qualify_property( context, properties, "src" ); + resource = mlt_properties_get( properties, "src" ); + } + + // Instantiate the producer + if ( mlt_properties_get( properties, "mlt_service" ) != NULL ) + { + char *service_name = trim( mlt_properties_get( properties, "mlt_service" ) ); + if ( resource ) + { + // If a document was saved as +INVALID.txt (see below), then ignore the mlt_service and + // try to load it just from the resource. This is an attempt to recover the failed + // producer in case, for example, a file returns. + if (!strcmp("qtext", service_name)) { + const char *text = mlt_properties_get( properties, "text" ); + if (text && !strcmp("INVALID", text)) { + service_name = NULL; + } + } else if (!strcmp("pango", service_name)) { + const char *markup = mlt_properties_get( properties, "markup" ); + if (markup && !strcmp("INVALID", markup)) { + service_name = NULL; + } + } + if (service_name) { + char *temp = calloc( 1, strlen( service_name ) + strlen( resource ) + 2 ); + strcat( temp, service_name ); + strcat( temp, ":" ); + strcat( temp, resource ); + source = mlt_factory_producer( context->profile, NULL, temp ); + free( temp ); + } + } + else + { + source = mlt_factory_producer( context->profile, NULL, service_name ); + } + } + + // Just in case the plugin requested doesn't exist... + if ( !source && resource ) + source = mlt_factory_producer( context->profile, NULL, resource ); + if ( !source ) { + mlt_log_error( NULL, "[producer_xml] failed to load producer \"%s\"\n", resource ); + source = mlt_factory_producer( context->profile, NULL, "+INVALID.txt" ); + if (source) { + // Save the original mlt_service for the consumer to serialize it as original. + mlt_properties_set_string( properties, "_xml_mlt_service", + mlt_properties_get( properties, "mlt_service" ) ); + } + } + if ( !source ) + source = mlt_factory_producer( context->profile, NULL, "colour:red" ); + // Add the source producer to the chain + mlt_chain_set_source( chain, source ); + + // See if the chain should be added to a playlist or multitrack + if ( mlt_properties_get( properties, "in" ) ) + in = mlt_properties_get_position( properties, "in" ); + if ( mlt_properties_get( properties, "out" ) ) + out = mlt_properties_get_position( properties, "out" ); + if ( add_producer( context, service, in, out ) == 0 ) + context_push_service( context, service, type ); + } + else + { + mlt_log_error( NULL, "[producer_xml] Invalid state of chain end %d\n", type ); + } +} + +static void on_start_link( deserialise_context context, const xmlChar *name, const xmlChar **atts) +{ + // Store properties until the service type is known + mlt_service service = calloc( 1, sizeof( struct mlt_service_s ) ); + mlt_service_init( service, NULL ); + context_push_service( context, service, mlt_link_type ); +} + +static void on_end_link( deserialise_context context, const xmlChar *name ) +{ + enum service_type type; + mlt_service service = context_pop_service( context, &type ); + mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); + + enum service_type parent_type = mlt_invalid_type; + mlt_service parent = context_pop_service( context, &parent_type ); + + if ( service != NULL && type == mlt_link_type ) + { + char *id = trim( mlt_properties_get( properties, "mlt_service" ) ); + mlt_service link = MLT_SERVICE( mlt_factory_link( id, NULL ) ); + mlt_properties link_props = MLT_SERVICE_PROPERTIES( link ); + + if ( !link ) + { + mlt_log_error( NULL, "[producer_xml] failed to load link \"%s\"\n", id ); + if ( parent ) + context_push_service( context, parent, parent_type ); + mlt_service_close( service ); + free( service ); + return; + } + + track_service( context->destructors, link, (mlt_destructor) mlt_link_close ); + mlt_properties_set_lcnumeric( MLT_SERVICE_PROPERTIES( link ), context->lc_numeric ); + + // Do not let XML overwrite these important properties set by mlt_factory. + mlt_properties_set_string( properties, "mlt_type", NULL ); + mlt_properties_set_string( properties, "mlt_service", NULL ); + + // Propagate the properties + mlt_properties_inherit( link_props, properties ); + + // Attach the link to the chain + if ( parent != NULL ) + { + if ( parent_type == mlt_chain_type ) + { + mlt_chain_attach( MLT_CHAIN( parent ), MLT_LINK( link ) ); + } + else + { + mlt_log_error( NULL, "[producer_xml] link can only be added to a chain...\n" ); + } + + // Put the parent back on the stack + context_push_service( context, parent, parent_type ); + } + else + { + mlt_log_error( NULL, "[producer_xml] link closed with invalid parent...\n" ); + } + } + else + { + mlt_log_error( NULL, "[producer_xml] Invalid top of stack on link close\n" ); + } + + if ( service ) + { + mlt_service_close( service ); + free(service); + } +} + static void on_start_producer( deserialise_context context, const xmlChar *name, const xmlChar **atts) { // use a dummy service to hold properties to allow arbitrary nesting @@ -1412,6 +1602,10 @@ static void on_start_element( void *ctx, const xmlChar *name, const xmlChar **at on_start_filter( context, name, atts ); else if ( xmlStrcmp( name, _x("transition") ) == 0 ) on_start_transition( context, name, atts ); + else if ( xmlStrcmp( name, _x("chain") ) == 0 ) + on_start_chain( context, name, atts ); + else if ( xmlStrcmp( name, _x("link") ) == 0 ) + on_start_link( context, name, atts ); else if ( xmlStrcmp( name, _x("property") ) == 0 ) on_start_property( context, name, atts ); else if ( xmlStrcmp( name, _x("consumer") ) == 0 ) @@ -1453,6 +1647,10 @@ static void on_end_element( void *ctx, const xmlChar *name ) on_end_filter( context, name ); else if ( xmlStrcmp( name, _x("transition") ) == 0 ) on_end_transition( context, name ); + else if ( xmlStrcmp( name, _x("chain") ) == 0 ) + on_end_chain( context, name ); + else if ( xmlStrcmp( name, _x("link") ) == 0 ) + on_end_link( context, name ); else if ( xmlStrcmp( name, _x("consumer") ) == 0 ) on_end_consumer( context, name ); @@ -1956,9 +2154,9 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype, if ( well_formed && service != NULL ) { // Verify it is a producer service (mlt_type="mlt_producer") - // (producer, playlist, multitrack) + // (producer, chain, playlist, multitrack) char *type = mlt_properties_get( MLT_SERVICE_PROPERTIES( service ), "mlt_type" ); - if ( type == NULL || ( strcmp( type, "mlt_producer" ) != 0 && strcmp( type, "producer" ) != 0 ) ) + if ( type == NULL || ( strcmp( type, "mlt_producer" ) != 0 && strcmp( type, "producer" ) != 0 && strcmp( type, "chain" ) != 0 ) ) service = NULL; } From b75eaf9b3ab8b76b91289a1fd6e89f9f0d8e3ac5 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 14 Nov 2020 18:12:04 -0600 Subject: [PATCH 002/122] Add speed status as read only parameter --- src/modules/core/link_timeremap.c | 25 +++++++++++++++---------- src/modules/core/link_timeremap.yml | 5 +++++ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/modules/core/link_timeremap.c b/src/modules/core/link_timeremap.c index 536a9a2e5..76ab35358 100644 --- a/src/modules/core/link_timeremap.c +++ b/src/modules/core/link_timeremap.c @@ -43,13 +43,9 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form double source_time = mlt_properties_get_double( unique_properties, "source_time" ); double source_duration = mlt_properties_get_double( unique_properties, "source_duration" ); double source_fps = mlt_properties_get_double( unique_properties, "source_fps" ); + double source_speed = mlt_properties_get_double( unique_properties, "source_speed" ); + source_speed = fabs( source_speed ); double link_fps = mlt_producer_get_fps( MLT_LINK_PRODUCER( self ) ); - double frame_duration = 1.0 / link_fps; - double speed = 0.0; - if ( source_duration != 0.0 ) - { - speed = fabs(source_duration) / frame_duration; - } // Validate the request *channels = *channels <= 0 ? 2 : *channels; @@ -63,7 +59,7 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form *frequency = 48000; } - if ( speed < 0.1 || speed > 10 ) + if ( source_speed < 0.1 || source_speed > 10 ) { // Return silent samples for speeds less than 0.1 or > 10 mlt_position position = mlt_frame_original_position( frame ); @@ -77,7 +73,7 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form else { int sample_count = mlt_sample_calculator( link_fps, *frequency, mlt_frame_get_position( frame ) ); - sample_count = lrint( (double)sample_count * speed ); + sample_count = lrint( (double)sample_count * source_speed ); mlt_position in_frame_pos = floor( source_time * source_fps ); // Calculate the samples to get from the input frames @@ -151,7 +147,7 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form mlt_audio_reverse( &out ); } - out.frequency = lrint( (double)out.frequency * speed ); + out.frequency = lrint( (double)out.frequency * source_speed ); mlt_frame_set_audio( frame, out.data, out.format, 0, out.release_data ); mlt_audio_get_values( &out, audio, frequency, format, samples, channels ); return 0; @@ -273,6 +269,7 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) double source_time = 0.0; double source_duration = 0.0; double source_fps = mlt_producer_get_fps( self->next ); + double link_fps = mlt_producer_get_fps( MLT_LINK_PRODUCER( self ) ); int result = 0; @@ -284,7 +281,6 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) // Calculate the frames from the next link to be used if ( !mlt_properties_exists( properties, "map" ) ) { - double link_fps = mlt_producer_get_fps( MLT_LINK_PRODUCER( self ) ); source_time = (double)position / link_fps; source_duration = 1.0 / link_fps; } @@ -295,9 +291,17 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) source_duration = next_source_time - source_time; } + double frame_duration = 1.0 / link_fps; + double source_speed = 0.0; + if ( source_duration != 0.0 ) + { + source_speed = source_duration / frame_duration; + } + mlt_properties_set_double( unique_properties, "source_fps", source_fps ); mlt_properties_set_double( unique_properties, "source_time", source_time ); mlt_properties_set_double( unique_properties, "source_duration", source_duration ); + mlt_properties_set_double( unique_properties, "source_speed", source_speed ); mlt_log_debug( MLT_LINK_SERVICE(self), "Get Frame: %f -> %f\t%d\n", source_fps, mlt_producer_get_fps( MLT_LINK_PRODUCER(self) ), position ); @@ -396,6 +400,7 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) } mlt_producer_prepare_next( MLT_LINK_PRODUCER( self ) ); + mlt_properties_set_double( properties, "speed", source_speed ); return result; } diff --git a/src/modules/core/link_timeremap.yml b/src/modules/core/link_timeremap.yml index e2ddc2e29..e0121d458 100644 --- a/src/modules/core/link_timeremap.yml +++ b/src/modules/core/link_timeremap.yml @@ -25,3 +25,8 @@ parameters: - nearest # Output the nearest frame - blend # Blend the frames that make up the output mutable: yes + - identifier: speed + title: Speed + type: float + description: The instantaneous speed of the last frame that was processed. + readonly: yes From 91979a740bb18d4fe78d4ec755fe452bff56147e Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 21 Nov 2020 12:03:38 -0600 Subject: [PATCH 003/122] Fix in point for timeremap filter --- src/framework/mlt_chain.c | 7 +++-- src/framework/mlt_link.c | 44 ++++++++++++++++++++++++++++--- src/framework/mlt_link.h | 2 +- src/framework/mlt_producer.c | 10 +++++++ src/framework/mlt_producer.h | 19 +++++++++++++ src/modules/core/link_timeremap.c | 15 +++++++---- 6 files changed, 86 insertions(+), 11 deletions(-) diff --git a/src/framework/mlt_chain.c b/src/framework/mlt_chain.c index 46e06f219..73c3e1e5f 100644 --- a/src/framework/mlt_chain.c +++ b/src/framework/mlt_chain.c @@ -163,7 +163,7 @@ void mlt_chain_set_source( mlt_chain self, mlt_producer source ) } // If a length has not been specified for this chain, copy in/out/length from the source producer if ( !mlt_producer_get_length( MLT_CHAIN_PRODUCER(self) ) ) { - mlt_properties_set_int( MLT_CHAIN_PROPERTIES(self), "length", mlt_producer_get_length( base->source ) ); + mlt_properties_set_position( MLT_CHAIN_PROPERTIES(self), "length", mlt_producer_get_length( base->source ) ); mlt_producer_set_in_and_out( MLT_CHAIN_PRODUCER(self), mlt_producer_get_in( base->source ), mlt_producer_get_out( base->source ) ); } mlt_events_unblock( MLT_CHAIN_PROPERTIES(self), self ); @@ -174,8 +174,11 @@ void mlt_chain_set_source( mlt_chain self, mlt_producer source ) // Save the native source producer profile mlt_profile_from_producer( base->source_profile, base->source ); - // This chain will control the speed + // This chain will control the speed and in/out mlt_producer_set_speed( base->source, 0.0 ); + // Approximate infinite length + mlt_properties_set_position( MLT_PRODUCER_PROPERTIES( base->source ), "length", 0x7fffffff ); + mlt_producer_set_in_and_out( base->source, 0, mlt_producer_get_length( base->source ) - 1 ); // Reconfigure the chain relink_chain( self ); diff --git a/src/framework/mlt_link.c b/src/framework/mlt_link.c index f10872cb5..b02fba391 100644 --- a/src/framework/mlt_link.c +++ b/src/framework/mlt_link.c @@ -31,6 +31,8 @@ */ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int track ); +static int producer_seek( mlt_producer parent, mlt_position position ); +static int producer_set_in_and_out( mlt_producer, mlt_position, mlt_position ); /** Construct a link. * @@ -58,6 +60,8 @@ mlt_link mlt_link_init( ) mlt_properties_clear( properties, "length"); mlt_properties_clear( properties, "eof"); producer->get_frame = producer_get_frame; + producer->seek = producer_seek; + producer->set_in_and_out = producer_set_in_and_out; producer->close = ( mlt_destructor )mlt_link_close; producer->close_object = self; } @@ -75,16 +79,16 @@ mlt_link mlt_link_init( ) * \public \memberof mlt_link_s * \param self a link * \param next the producer to get frames from - * \param default_profile a profile to use if needed (some links derive their frame rate from the next producer) + * \param chain_profile a profile to use if needed (some links derive their frame rate from the next producer) * \return true on error */ -int mlt_link_connect_next( mlt_link self, mlt_producer next, mlt_profile default_profile ) +int mlt_link_connect_next( mlt_link self, mlt_producer next, mlt_profile chain_profile ) { self->next = next; if ( self->configure ) { - self->configure( self, default_profile ); + self->configure( self, chain_profile ); } return 0; } @@ -128,3 +132,37 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int ind } return 1; } + +int producer_seek( mlt_producer parent, mlt_position position ) +{ + // Unlike mlt_producer_seek(), a link does not do bounds checking when seeking + if ( parent && parent->child ) + { + mlt_link self = parent->child; + mlt_properties properties = MLT_LINK_PROPERTIES( self ); + int use_points = 1 - mlt_properties_get_int( properties, "ignore_points" ); + + // Set the position + mlt_properties_set_position( properties, "_position", position ); + + // Calculate the absolute frame + mlt_properties_set_position( properties, "_frame", use_points * mlt_producer_get_in( parent ) + position ); + } + return 0; +} + + +int producer_set_in_and_out( mlt_producer parent, mlt_position in, mlt_position out ) +{ + // Unlike mlt_producer_set_in_and_out(), a link does not do bounds checking against length + if ( parent && parent->child ) + { + mlt_link self = parent->child; + mlt_properties properties = MLT_PRODUCER_PROPERTIES( self ); + mlt_events_block( properties, properties ); + mlt_properties_set_position( properties, "in", in ); + mlt_events_unblock( properties, properties ); + mlt_properties_set_position( properties, "out", out ); + } + return 0; +} diff --git a/src/framework/mlt_link.h b/src/framework/mlt_link.h index bd8c61d81..faaa72a33 100644 --- a/src/framework/mlt_link.h +++ b/src/framework/mlt_link.h @@ -68,7 +68,7 @@ struct mlt_link_s #define MLT_LINK_PROPERTIES( link ) MLT_SERVICE_PROPERTIES( MLT_LINK_SERVICE( link ) ) extern mlt_link mlt_link_init( ); -extern int mlt_link_connect_next( mlt_link self, mlt_producer next, mlt_profile default_profile ); +extern int mlt_link_connect_next( mlt_link self, mlt_producer next, mlt_profile chain_profile ); extern void mlt_link_close( mlt_link self ); #endif diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index 30d288503..cda53fbc0 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -310,6 +310,11 @@ mlt_properties mlt_producer_properties( mlt_producer self ) int mlt_producer_seek( mlt_producer self, mlt_position position ) { + if ( self->seek ) + { + return self->seek( self, position ); + } + // Determine eof handling mlt_properties properties = MLT_PRODUCER_PROPERTIES( self ); char *eof = mlt_properties_get( properties, "eof" ); @@ -458,6 +463,11 @@ double mlt_producer_get_fps( mlt_producer self ) int mlt_producer_set_in_and_out( mlt_producer self, mlt_position in, mlt_position out ) { + if ( self->set_in_and_out ) + { + return self->set_in_and_out( self, in, out ); + } + mlt_properties properties = MLT_PRODUCER_PROPERTIES( self ); // Correct ins and outs if necessary diff --git a/src/framework/mlt_producer.h b/src/framework/mlt_producer.h index eee87830d..beb81f2d4 100644 --- a/src/framework/mlt_producer.h +++ b/src/framework/mlt_producer.h @@ -80,6 +80,25 @@ struct mlt_producer_s */ int ( *get_frame )( mlt_producer, mlt_frame_ptr, int ); + /** Seek to s specified position (virtual function). + * + * \param mlt_producer a producer + * \param mlt_position a frame pointer by reference + * \param position set the "play head" position of the producer + * \return false + */ + int ( *seek )( mlt_producer, mlt_position ); + + /** Set the in and out points. + * + * \param mlt_producer a producer + * \param mlt_position the relative starting time; a negative value is the same as 0 + * \param mlt_position the relative ending time; a negative value is the same as length - 1 + * \return false + */ + int ( *set_in_and_out )( mlt_producer, mlt_position, mlt_position ); + + /** the destructor virtual function */ mlt_destructor close; void *close_object; /**< the object supplied to the close virtual function */ diff --git a/src/modules/core/link_timeremap.c b/src/modules/core/link_timeremap.c index 76ab35358..2b5d7e291 100644 --- a/src/modules/core/link_timeremap.c +++ b/src/modules/core/link_timeremap.c @@ -27,9 +27,11 @@ #include #include -static void link_configure( mlt_link self, mlt_profile default_profile ) +static void link_configure( mlt_link self, mlt_profile chain_profile ) { - mlt_service_set_profile( MLT_LINK_SERVICE( self ), default_profile ); + // Timeremap must always work with the same profile as the chain so that + // animation, in and out will work. + mlt_service_set_profile( MLT_LINK_SERVICE( self ), chain_profile ); } static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* format, int* frequency, int* channels, int* samples ) @@ -286,8 +288,11 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) } else { - source_time = mlt_properties_anim_get_double( properties, "map", position, length ); - double next_source_time = mlt_properties_anim_get_double( properties, "map", position + 1, length ); + // Assume that the user wants normal speed before the in point. + mlt_position in = mlt_producer_get_in( MLT_LINK_PRODUCER(self) ); + double in_time = (double)in / link_fps; + source_time = mlt_properties_anim_get_double( properties, "map", position - in, length ) + in_time; + double next_source_time = mlt_properties_anim_get_double( properties, "map", position - in + 1, length ) + in_time; source_duration = next_source_time - source_time; } @@ -303,7 +308,7 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) mlt_properties_set_double( unique_properties, "source_duration", source_duration ); mlt_properties_set_double( unique_properties, "source_speed", source_speed ); - mlt_log_debug( MLT_LINK_SERVICE(self), "Get Frame: %f -> %f\t%d\n", source_fps, mlt_producer_get_fps( MLT_LINK_PRODUCER(self) ), position ); + mlt_log_debug( MLT_LINK_SERVICE(self), "Get Frame: %f -> %f\t%d\t%d\n", source_fps, link_fps, position, mlt_producer_get_in( MLT_LINK_PRODUCER(self) ) ); // Get frames from the next link and pass them along with the new frame int in_frame_count = 0; From aaf54bbc961c80a6d6ada7bf464e2ef33dc894dc Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Thu, 3 Dec 2020 22:15:28 -0600 Subject: [PATCH 004/122] Improve sample continuity in timeremap --- src/modules/core/link_timeremap.c | 40 +++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/modules/core/link_timeremap.c b/src/modules/core/link_timeremap.c index 2b5d7e291..571d318f6 100644 --- a/src/modules/core/link_timeremap.c +++ b/src/modules/core/link_timeremap.c @@ -74,12 +74,37 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form } else { - int sample_count = mlt_sample_calculator( link_fps, *frequency, mlt_frame_get_position( frame ) ); - sample_count = lrint( (double)sample_count * source_speed ); + // Calculate the samples to get from the input frames + int link_sample_count = mlt_sample_calculator( link_fps, *frequency, mlt_frame_get_position( frame ) ); + int sample_count = lrint( (double)link_sample_count * source_speed ); mlt_position in_frame_pos = floor( source_time * source_fps ); + int64_t first_out_sample = llrint(source_time * (double)*frequency); + + // Attempt to maintain sample continuity with the previous frame + static const int64_t SAMPLE_CONTINUITY_ERROR_MARGIN = 4; + int64_t continuity_sample = mlt_properties_get_int64( MLT_LINK_PROPERTIES( self ), "_continuity_sample" ); + int64_t continuity_delta = continuity_sample - first_out_sample; + if ( source_duration > 0.0 && continuity_delta != 0 ) + { + // Forward: Continue from where the previous frame left off if within the margin of error + if ( continuity_delta > -SAMPLE_CONTINUITY_ERROR_MARGIN && continuity_delta < SAMPLE_CONTINUITY_ERROR_MARGIN ) + { + sample_count = sample_count - continuity_delta; + first_out_sample = continuity_sample; + mlt_log_debug( MLT_LINK_SERVICE(self), "Maintain Forward Continuity: %d\n", (int)continuity_delta ); + } + } + else if ( source_duration < 0.0 && continuity_delta != sample_count ) + { + // Reverse: End where the previous frame left off if within the margin of error + continuity_delta -= sample_count; + if ( continuity_delta > -SAMPLE_CONTINUITY_ERROR_MARGIN && continuity_delta < SAMPLE_CONTINUITY_ERROR_MARGIN ) + { + sample_count = sample_count + continuity_delta; + mlt_log_debug( MLT_LINK_SERVICE(self), "Maintain Reverse Continuity: %d\n", (int)continuity_delta ); + } + } - // Calculate the samples to get from the input frames - int64_t first_out_sample = source_time * (double)*frequency; int64_t first_in_sample = mlt_sample_calculator_to_now( source_fps, *frequency, in_frame_pos ); int samples_to_skip = first_out_sample - first_in_sample; if ( samples_to_skip < 0 ) @@ -147,9 +172,14 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form { // Going backwards mlt_audio_reverse( &out ); + mlt_properties_set_int64( MLT_LINK_PROPERTIES( self ), "_continuity_sample", first_out_sample ); + } + else + { + mlt_properties_set_int64( MLT_LINK_PROPERTIES( self ), "_continuity_sample", first_out_sample + sample_count ); } - out.frequency = lrint( (double)out.frequency * source_speed ); + out.frequency = lrint( (double)out.frequency * (double)sample_count / (double)link_sample_count ); mlt_frame_set_audio( frame, out.data, out.format, 0, out.release_data ); mlt_audio_get_values( &out, audio, frequency, format, samples, channels ); return 0; From 2ccee265650caba7f787c95f8f29dfb9f01ae9b3 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 14 Dec 2020 20:30:14 -0600 Subject: [PATCH 005/122] Set correct mlt version --- src/framework/mlt.vers | 2 +- src/mlt++/mlt++.vers | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index da44f6019..083a36131 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -577,7 +577,7 @@ MLT_6.22.0 { mlt_audio_channel_layout_default; } MLT_6.20.0; -MLT_6.24.0 { +MLT_6.26.0 { global: mlt_factory_link; mlt_chain_init; diff --git a/src/mlt++/mlt++.vers b/src/mlt++/mlt++.vers index 87f4d4475..f01c2aa4b 100644 --- a/src/mlt++/mlt++.vers +++ b/src/mlt++/mlt++.vers @@ -613,7 +613,7 @@ MLTPP_6.22.0 { }; } MLTPP_6.20.0; -MLTPP_6.24.0 { +MLTPP_6.26.0 { global: extern "C++" { "Mlt::Link::Link()"; From ab15734da290119d29365385aec3ef0dc3c1d49d Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 14 Dec 2020 22:03:41 -0600 Subject: [PATCH 006/122] Add chain and link to melt documentation --- docs/melt.1 | 18 +++++++++++++++--- src/melt/melt.c | 2 ++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/melt.1 b/docs/melt.1 index b44d57ed6..f4829f40b 100644 --- a/docs/melt.1 +++ b/docs/melt.1 @@ -1,4 +1,4 @@ -.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.4. +.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.13. .TH MELT "1" "December 2020" "melt 6.24.0" "User Commands" .SH NAME melt \- author, play, and encode multitrack audio/video compositions @@ -24,6 +24,9 @@ Add an audio\-only track \fB\-blank\fR frames Add blank silence to a track .TP +\fB\-chain\fR id[:arg] [name=value]* +Add a producer as a chain +.TP \fB\-consumer\fR id[:arg] [name=value]* Set the consumer (sink) .TP @@ -33,6 +36,9 @@ Set the logging level to debug \fB\-filter\fR filter[:arg] [name=value]* Add a filter to the current track .TP +\fB\-getc\fR +Get keyboard input using getc +.TP \fB\-group\fR [name=value]* Apply properties repeatedly .TP @@ -45,6 +51,9 @@ Enable JACK transport synchronization \fB\-join\fR clips Join multiple clips into one cut .TP +\fB\-link\fR id[:arg] [name=value]* +Add a link to a chain +.TP \fB\-mix\fR length Add a mix between the last two cuts .TP @@ -91,7 +100,7 @@ List audio codecs List video codecs .TP \fB\-quiet\fR -Set the logging level to quiet and do not display position/transport +Set the logging level to quiet .TP \fB\-remove\fR Remove the most recent cut @@ -100,7 +109,7 @@ Remove the most recent cut Repeat the last cut .TP \fB\-repository\fR path -Set the directory of MLT plugins +Set the directory of MLT modules .TP \fB\-serialise\fR [filename] Write the commands to a text file @@ -123,6 +132,9 @@ Add a transition \fB\-verbose\fR Set the logging level to verbose .TP +\fB\-timings\fR +Set the logging level to timings +.TP \fB\-version\fR Show the version and copyright .TP diff --git a/src/melt/melt.c b/src/melt/melt.c index dad5c4a3e..0327fb0d9 100644 --- a/src/melt/melt.c +++ b/src/melt/melt.c @@ -495,6 +495,7 @@ static void show_usage( char *program_name ) " -attach-clip filter[:arg] [name=value]* Attach a filter to a producer\n" " -audio-track | -hide-video Add an audio-only track\n" " -blank frames Add blank silence to a track\n" +" -chain id[:arg] [name=value]* Add a producer as a chain\n" " -consumer id[:arg] [name=value]* Set the consumer (sink)\n" " -debug Set the logging level to debug\n" " -filter filter[:arg] [name=value]* Add a filter to the current track\n" @@ -503,6 +504,7 @@ static void show_usage( char *program_name ) " -help Show this message\n" " -jack Enable JACK transport synchronization\n" " -join clips Join multiple clips into one cut\n" +" -link id[:arg] [name=value]* Add a link to a chain\n" " -mix length Add a mix between the last two cuts\n" " -mixer transition Add a transition to the mix\n" " -null-track | -hide-track Add a hidden track\n" From b6678e715e29fa07727f29ad9efb0243ba1be8c6 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 14 Dec 2020 22:04:09 -0600 Subject: [PATCH 007/122] Add chain and link to mlt_parser --- src/framework/mlt_parser.c | 42 ++++++++++++++++++++++++++++++++++++++ src/framework/mlt_parser.h | 4 ++++ 2 files changed, 46 insertions(+) diff --git a/src/framework/mlt_parser.c b/src/framework/mlt_parser.c index 105bb427c..6783198a4 100644 --- a/src/framework/mlt_parser.c +++ b/src/framework/mlt_parser.c @@ -103,6 +103,27 @@ static int on_end_transition( mlt_parser self, mlt_transition object ) return 0; } + +static int on_start_chain( mlt_parser self, mlt_chain object ) +{ + return 0; +} + +static int on_end_chain( mlt_parser self, mlt_chain object ) +{ + return 0; +} + +static int on_start_link( mlt_parser self, mlt_link object ) +{ + return 0; +} + +static int on_end_link( mlt_parser self, mlt_link object ) +{ + return 0; +} + mlt_parser mlt_parser_new( ) { mlt_parser self = calloc( 1, sizeof( struct mlt_parser_s ) ); @@ -124,6 +145,10 @@ mlt_parser mlt_parser_new( ) self->on_end_filter = on_end_filter; self->on_start_transition = on_start_transition; self->on_end_transition = on_end_transition; + self->on_start_chain = on_start_chain; + self->on_end_chain = on_end_chain; + self->on_start_link = on_start_link; + self->on_end_link = on_end_link; } return self; } @@ -228,6 +253,23 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) break; case consumer_type: break; + case chain_type: + error = self->on_start_chain( self, ( mlt_chain )object ); + if ( error == 0 ) + { + int i = 0; + while ( error == 0 && i < mlt_chain_link( ( mlt_chain )object, i ) != NULL ) + mlt_parser_start( self, ( mlt_service )mlt_chain_link( ( mlt_chain )object, i ++ ) ); + i = 0; + while ( error == 0 && mlt_producer_filter( MLT_CHAIN_PRODUCER(object), i ) != NULL ) + error = mlt_parser_start( self, ( mlt_service )mlt_producer_filter( MLT_CHAIN_PRODUCER(object), i ++ ) ); + } + error = self->on_end_chain( self, ( mlt_chain )object ); + break; + case link_type: + error = self->on_start_link( self, ( mlt_link )object ); + error = self->on_end_link( self, ( mlt_link )object ); + break; } return error; } diff --git a/src/framework/mlt_parser.h b/src/framework/mlt_parser.h index e7e8e7241..54613d8c9 100644 --- a/src/framework/mlt_parser.h +++ b/src/framework/mlt_parser.h @@ -49,6 +49,10 @@ struct mlt_parser_s int ( *on_end_filter )( mlt_parser self, mlt_filter object ); int ( *on_start_transition )( mlt_parser self, mlt_transition object ); int ( *on_end_transition )( mlt_parser self, mlt_transition object ); + int ( *on_start_chain )( mlt_parser self, mlt_chain object ); + int ( *on_end_chain )( mlt_parser self, mlt_chain object ); + int ( *on_start_link )( mlt_parser self, mlt_producer object ); + int ( *on_end_link )( mlt_parser self, mlt_link object ); }; extern mlt_parser mlt_parser_new( ); From e29dac14ec484fc48b47e99be44026fd049a99dc Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 14 Dec 2020 22:05:02 -0600 Subject: [PATCH 008/122] Add chain and link to xml dtd --- src/modules/xml/mlt-xml.dtd | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/modules/xml/mlt-xml.dtd b/src/modules/xml/mlt-xml.dtd index c4473e820..ececaf39a 100644 --- a/src/modules/xml/mlt-xml.dtd +++ b/src/modules/xml/mlt-xml.dtd @@ -39,6 +39,19 @@ title CDATA #IMPLIED mlt_service CDATA #IMPLIED > + + + + Date: Mon, 14 Dec 2020 22:05:21 -0600 Subject: [PATCH 009/122] Fix typos in mlt_producer comments --- src/framework/mlt_producer.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/framework/mlt_producer.h b/src/framework/mlt_producer.h index beb81f2d4..0a9f22f77 100644 --- a/src/framework/mlt_producer.h +++ b/src/framework/mlt_producer.h @@ -80,10 +80,9 @@ struct mlt_producer_s */ int ( *get_frame )( mlt_producer, mlt_frame_ptr, int ); - /** Seek to s specified position (virtual function). + /** Seek to a specified position (virtual function). * * \param mlt_producer a producer - * \param mlt_position a frame pointer by reference * \param position set the "play head" position of the producer * \return false */ From 74ce1205e713069d76989004629bc428251f5fb4 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Tue, 15 Dec 2020 20:16:20 -0600 Subject: [PATCH 010/122] Add mlt_service prefix to service type enum --- src/framework/mlt_chain.c | 2 +- src/framework/mlt_factory.c | 16 +- src/framework/mlt_field.c | 6 +- src/framework/mlt_parser.c | 24 +-- src/framework/mlt_producer.c | 4 +- src/framework/mlt_repository.c | 20 +-- src/framework/mlt_service.c | 30 ++-- src/framework/mlt_tractor.c | 8 +- src/framework/mlt_types.h | 24 +-- src/melt/melt.c | 32 ++-- src/mlt++/MltChain.cpp | 2 +- src/mlt++/MltConsumer.cpp | 2 +- src/mlt++/MltFilter.cpp | 2 +- src/mlt++/MltMultitrack.cpp | 2 +- src/mlt++/MltPlaylist.cpp | 2 +- src/mlt++/MltProducer.cpp | 6 +- src/mlt++/MltTractor.cpp | 4 +- src/mlt++/MltTransition.cpp | 2 +- src/modules/avformat/factory.c | 46 +++--- src/modules/core/factory.c | 176 ++++++++++----------- src/modules/core/producer_timewarp.c | 2 +- src/modules/decklink/consumer_decklink.cpp | 12 +- src/modules/dv/factory.c | 8 +- src/modules/frei0r/factory.c | 34 ++-- src/modules/frei0r/frei0r_helper.c | 10 +- src/modules/gdk/factory.c | 12 +- src/modules/gtk2/factory.c | 4 +- src/modules/jackrack/factory.c | 26 +-- src/modules/kdenlive/factory.c | 16 +- src/modules/kino/factory.c | 2 +- src/modules/linsys/factory.c | 4 +- src/modules/motion_est/factory.c | 20 +-- src/modules/ndi/factory.c | 8 +- src/modules/normalize/factory.c | 8 +- src/modules/oldfilm/factory.c | 24 +-- src/modules/opencv/factory.c | 4 +- src/modules/opengl/factory.c | 72 ++++----- src/modules/plus/factory.c | 88 +++++------ src/modules/plusgpl/factory.c | 22 +-- src/modules/qt/factory.c | 50 +++--- src/modules/resample/factory.c | 4 +- src/modules/rtaudio/consumer_rtaudio.cpp | 4 +- src/modules/rubberband/factory.c | 4 +- src/modules/sdl/factory.c | 20 +-- src/modules/sdl2/factory.c | 8 +- src/modules/sox/factory.c | 10 +- src/modules/swfdec/producer_swfdec.c | 4 +- src/modules/vid.stab/factory.c | 8 +- src/modules/videostab/factory.c | 8 +- src/modules/vmfx/factory.c | 20 +-- src/modules/vorbis/factory.c | 4 +- src/modules/xine/factory.c | 2 +- src/modules/xml/consumer_xml.c | 2 +- src/modules/xml/factory.c | 16 +- src/modules/xml/producer_xml.c | 6 +- src/tests/test_service/test_service.cpp | 22 +-- 56 files changed, 489 insertions(+), 489 deletions(-) diff --git a/src/framework/mlt_chain.c b/src/framework/mlt_chain.c index 73c3e1e5f..54641351b 100644 --- a/src/framework/mlt_chain.c +++ b/src/framework/mlt_chain.c @@ -126,7 +126,7 @@ void mlt_chain_set_source( mlt_chain self, mlt_producer source ) // they can be passed between the source producer and this chain. base->source_parameters = mlt_properties_new(); mlt_repository repository = mlt_factory_repository(); - mlt_properties source_metadata = mlt_repository_metadata( repository, producer_type, mlt_properties_get( source_properties, "mlt_service" ) ); + mlt_properties source_metadata = mlt_repository_metadata( repository, mlt_service_producer_type, mlt_properties_get( source_properties, "mlt_service" ) ); if ( source_metadata ) { mlt_properties params = (mlt_properties) mlt_properties_get_data( source_metadata, "parameters", NULL ); diff --git a/src/framework/mlt_factory.c b/src/framework/mlt_factory.c index 818d211f6..4867faca2 100644 --- a/src/framework/mlt_factory.c +++ b/src/framework/mlt_factory.c @@ -359,12 +359,12 @@ mlt_producer mlt_factory_producer( mlt_profile profile, const char *service, con // Try to instantiate via the specified service if ( obj == NULL ) { - obj = mlt_repository_create( repository, profile, producer_type, service, resource ); + obj = mlt_repository_create( repository, profile, mlt_service_producer_type, service, resource ); mlt_events_fire( event_object, "producer-create-done", service, resource, obj, NULL ); if ( obj != NULL ) { mlt_properties properties = MLT_PRODUCER_PROPERTIES( obj ); - if ( mlt_service_identify( MLT_PRODUCER_SERVICE( obj ) ) == chain_type ) + if ( mlt_service_identify( MLT_PRODUCER_SERVICE( obj ) ) == mlt_service_chain_type ) { // XML producer may return a chain set_common_properties( properties, profile, "chain", service ); @@ -395,7 +395,7 @@ mlt_filter mlt_factory_filter( mlt_profile profile, const char *service, const v if ( obj == NULL ) { - obj = mlt_repository_create( repository, profile, filter_type, service, input ); + obj = mlt_repository_create( repository, profile, mlt_service_filter_type, service, input ); mlt_events_fire( event_object, "filter-create-done", service, input, obj, NULL ); } @@ -423,7 +423,7 @@ mlt_link mlt_factory_link( const char *service, const void *input ) if ( obj == NULL ) { - obj = mlt_repository_create( repository, NULL, link_type, service, input ); + obj = mlt_repository_create( repository, NULL, mlt_service_link_type, service, input ); mlt_events_fire( event_object, "link-create-done", service, input, obj, NULL ); } @@ -452,7 +452,7 @@ mlt_transition mlt_factory_transition( mlt_profile profile, const char *service, if ( obj == NULL ) { - obj = mlt_repository_create( repository, profile, transition_type, service, input ); + obj = mlt_repository_create( repository, profile, mlt_service_transition_type, service, input ); mlt_events_fire( event_object, "transition-create-done", service, input, obj, NULL ); } @@ -484,7 +484,7 @@ mlt_consumer mlt_factory_consumer( mlt_profile profile, const char *service, con if ( obj == NULL ) { - obj = mlt_repository_create( repository, profile, consumer_type, service, input ); + obj = mlt_repository_create( repository, profile, mlt_service_consumer_type, service, input ); } if ( obj == NULL ) @@ -492,12 +492,12 @@ mlt_consumer mlt_factory_consumer( mlt_profile profile, const char *service, con if ( !strcmp( service, "sdl2" ) ) { service = "sdl"; - obj = mlt_repository_create( repository, profile, consumer_type, service, input ); + obj = mlt_repository_create( repository, profile, mlt_service_consumer_type, service, input ); } else if ( !strcmp( service, "sdl_audio" ) ) { service = "sdl2_audio"; - obj = mlt_repository_create( repository, profile, consumer_type, service, input ); + obj = mlt_repository_create( repository, profile, mlt_service_consumer_type, service, input ); } } diff --git a/src/framework/mlt_field.c b/src/framework/mlt_field.c index 72a68de54..79ff773a5 100644 --- a/src/framework/mlt_field.c +++ b/src/framework/mlt_field.c @@ -250,16 +250,16 @@ void mlt_field_disconnect_service( mlt_field self, mlt_service service ) int i; switch ( mlt_service_identify(c) ) { - case filter_type: + case mlt_service_filter_type: i = mlt_filter_get_track( MLT_FILTER(c) ); mlt_service_connect_producer( c, p, i ); break; - case transition_type: + case mlt_service_transition_type: i = mlt_transition_get_a_track ( MLT_TRANSITION(c) ); mlt_service_connect_producer( c, p, i ); MLT_TRANSITION(c)->producer = p; break; - case tractor_type: + case mlt_service_tractor_type: self->producer = p; mlt_tractor_connect( MLT_TRACTOR(c), p ); default: diff --git a/src/framework/mlt_parser.c b/src/framework/mlt_parser.c index 6783198a4..09a0f2549 100644 --- a/src/framework/mlt_parser.c +++ b/src/framework/mlt_parser.c @@ -164,13 +164,13 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) mlt_service_type type = mlt_service_identify( object ); switch( type ) { - case invalid_type: + case mlt_service_invalid_type: error = self->on_invalid( self, object ); break; - case unknown_type: + case mlt_service_unknown_type: error = self->on_unknown( self, object ); break; - case producer_type: + case mlt_service_producer_type: if ( mlt_producer_is_cut( ( mlt_producer )object ) ) error = mlt_parser_start( self, ( mlt_service )mlt_producer_cut_parent( ( mlt_producer )object ) ); error = self->on_start_producer( self, ( mlt_producer )object ); @@ -182,7 +182,7 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) } error = self->on_end_producer( self, ( mlt_producer )object ); break; - case playlist_type: + case mlt_service_playlist_type: error = self->on_start_playlist( self, ( mlt_playlist )object ); if ( error == 0 ) { @@ -195,7 +195,7 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) } error = self->on_end_playlist( self, ( mlt_playlist )object ); break; - case tractor_type: + case mlt_service_tractor_type: error = self->on_start_tractor( self, ( mlt_tractor )object ); if ( error == 0 ) { @@ -212,7 +212,7 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) } error = self->on_end_tractor( self, ( mlt_tractor )object ); break; - case multitrack_type: + case mlt_service_multitrack_type: error = self->on_start_multitrack( self, ( mlt_multitrack )object ); if ( error == 0 ) { @@ -229,7 +229,7 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) } error = self->on_end_multitrack( self, ( mlt_multitrack )object ); break; - case filter_type: + case mlt_service_filter_type: error = self->on_start_filter( self, ( mlt_filter )object ); if ( error == 0 ) { @@ -239,7 +239,7 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) } error = self->on_end_filter( self, ( mlt_filter )object ); break; - case transition_type: + case mlt_service_transition_type: error = self->on_start_transition( self, ( mlt_transition )object ); if ( error == 0 ) { @@ -249,11 +249,11 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) } error = self->on_end_transition( self, ( mlt_transition )object ); break; - case field_type: + case mlt_service_field_type: break; - case consumer_type: + case mlt_service_consumer_type: break; - case chain_type: + case mlt_service_chain_type: error = self->on_start_chain( self, ( mlt_chain )object ); if ( error == 0 ) { @@ -266,7 +266,7 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) } error = self->on_end_chain( self, ( mlt_chain )object ); break; - case link_type: + case mlt_service_link_type: error = self->on_start_link( self, ( mlt_link )object ); error = self->on_end_link( self, ( mlt_link )object ); break; diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index cda53fbc0..582e112ab 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -326,7 +326,7 @@ int mlt_producer_seek( mlt_producer self, mlt_position position ) mlt_producer_seek( mlt_producer_cut_parent( self ), position + mlt_producer_get_in( self ) ); // Check bounds - if( mlt_service_identify( MLT_PRODUCER_SERVICE(self) ) == link_type ) + if( mlt_service_identify( MLT_PRODUCER_SERVICE(self) ) == mlt_service_link_type ) { // Do not bounds check a link. } @@ -946,7 +946,7 @@ static int on_start_producer( mlt_parser self, mlt_producer object ) mlt_properties properties = mlt_parser_properties( self ); mlt_properties producers = mlt_properties_get_data( properties, "producers", NULL ); mlt_producer parent = mlt_producer_cut_parent( object ); - if ( mlt_service_identify( ( mlt_service )mlt_producer_cut_parent( object ) ) == producer_type && mlt_producer_is_cut( object ) ) + if ( mlt_service_identify( ( mlt_service )mlt_producer_cut_parent( object ) ) == mlt_service_producer_type && mlt_producer_is_cut( object ) ) { int ref_count = 0; clip_references *old_refs = NULL; diff --git a/src/framework/mlt_repository.c b/src/framework/mlt_repository.c index d5638280a..a999ead64 100644 --- a/src/framework/mlt_repository.c +++ b/src/framework/mlt_repository.c @@ -174,19 +174,19 @@ void mlt_repository_register( mlt_repository self, mlt_service_type service_type // Add the entry point to the corresponding service list switch ( service_type ) { - case consumer_type: + case mlt_service_consumer_type: mlt_properties_set_data( self->consumers, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); break; - case filter_type: + case mlt_service_filter_type: mlt_properties_set_data( self->filters, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); break; - case link_type: + case mlt_service_link_type: mlt_properties_set_data( self->links, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); break; - case producer_type: + case mlt_service_producer_type: mlt_properties_set_data( self->producers, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); break; - case transition_type: + case mlt_service_transition_type: mlt_properties_set_data( self->transitions, service, new_service( symbol ), 0, ( mlt_destructor )mlt_properties_close, NULL ); break; default: @@ -211,19 +211,19 @@ static mlt_properties get_service_properties( mlt_repository self, mlt_service_t // Get the entry point from the corresponding service list switch ( type ) { - case consumer_type: + case mlt_service_consumer_type: service_properties = mlt_properties_get_data( self->consumers, service, NULL ); break; - case filter_type: + case mlt_service_filter_type: service_properties = mlt_properties_get_data( self->filters, service, NULL ); break; - case link_type: + case mlt_service_link_type: service_properties = mlt_properties_get_data( self->links, service, NULL ); break; - case producer_type: + case mlt_service_producer_type: service_properties = mlt_properties_get_data( self->producers, service, NULL ); break; - case transition_type: + case mlt_service_transition_type: service_properties = mlt_properties_get_data( self->transitions, service, NULL ); break; default: diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c index 05f8a7079..26c1e43c9 100644 --- a/src/framework/mlt_service.c +++ b/src/framework/mlt_service.c @@ -157,36 +157,36 @@ void mlt_service_unlock( mlt_service self ) mlt_service_type mlt_service_identify( mlt_service self ) { - mlt_service_type type = invalid_type; + mlt_service_type type = mlt_service_invalid_type; if ( self != NULL ) { mlt_properties properties = MLT_SERVICE_PROPERTIES( self ); char *mlt_type = mlt_properties_get( properties, "mlt_type" ); char *resource = mlt_properties_get( properties, "resource" ); if ( mlt_type == NULL ) - type = unknown_type; + type = mlt_service_unknown_type; else if (resource != NULL && !strcmp( resource, "" ) ) - type = playlist_type; + type = mlt_service_playlist_type; else if (resource != NULL && !strcmp( resource, "" ) ) - type = tractor_type; + type = mlt_service_tractor_type; else if (resource != NULL && !strcmp( resource, "" ) ) - type = multitrack_type; + type = mlt_service_multitrack_type; else if ( !strcmp( mlt_type, "mlt_producer" ) ) - type = producer_type; + type = mlt_service_producer_type; else if ( !strcmp( mlt_type, "producer" ) ) - type = producer_type; + type = mlt_service_producer_type; else if ( !strcmp( mlt_type, "filter" ) ) - type = filter_type; + type = mlt_service_filter_type; else if ( !strcmp( mlt_type, "transition" ) ) - type = transition_type; + type = mlt_service_transition_type; else if ( !strcmp( mlt_type, "chain" ) ) - type = chain_type; + type = mlt_service_chain_type; else if ( !strcmp( mlt_type, "consumer" ) ) - type = consumer_type; + type = mlt_service_consumer_type; else if ( !strcmp( mlt_type, "link" ) ) - type = link_type; + type = mlt_service_link_type; else - type = unknown_type; + type = mlt_service_unknown_type; } return type; } @@ -594,7 +594,7 @@ int mlt_service_get_frame( mlt_service self, mlt_frame_ptr frame, int index ) mlt_properties properties = MLT_SERVICE_PROPERTIES( self ); mlt_position in = mlt_properties_get_position( properties, "in" ); mlt_position out = mlt_properties_get_position( properties, "out" ); - mlt_position position = mlt_service_identify( self ) == producer_type ? mlt_producer_position( MLT_PRODUCER( self ) ) : -1; + mlt_position position = mlt_service_identify( self ) == mlt_service_producer_type ? mlt_producer_position( MLT_PRODUCER( self ) ) : -1; result = self->get_frame( self, frame, index ); @@ -611,7 +611,7 @@ int mlt_service_get_frame( mlt_service self, mlt_frame_ptr frame, int index ) mlt_service_apply_filters( self, *frame, 1 ); mlt_deque_push_back( MLT_FRAME_SERVICE_STACK( *frame ), self ); - if ( mlt_service_identify( self ) == producer_type && + if ( mlt_service_identify( self ) == mlt_service_producer_type && mlt_properties_get_int( MLT_SERVICE_PROPERTIES( self ), "_need_previous_next" ) ) { // Save the new position from self->get_frame diff --git a/src/framework/mlt_tractor.c b/src/framework/mlt_tractor.c index 74a53bc9e..b466b343c 100644 --- a/src/framework/mlt_tractor.c +++ b/src/framework/mlt_tractor.c @@ -267,7 +267,7 @@ int mlt_tractor_insert_track( mlt_tractor self, mlt_producer producer, int index mlt_service_type type = mlt_service_identify( service ); mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); - if ( type == transition_type ) + if ( type == mlt_service_transition_type ) { mlt_transition transition = MLT_TRANSITION( service ); int a_track = mlt_transition_get_a_track( transition ); @@ -280,7 +280,7 @@ int mlt_tractor_insert_track( mlt_tractor self, mlt_producer producer, int index mlt_transition_set_tracks( transition, a_track, b_track ); } } - else if ( type == filter_type ) + else if ( type == mlt_service_filter_type ) { int current_track = mlt_properties_get_int( properties, "track" ); if ( current_track >= index ) @@ -313,7 +313,7 @@ int mlt_tractor_remove_track( mlt_tractor self, int index ) mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); int track_max = MAX( mlt_multitrack_count( mlt_tractor_multitrack( self ) ) - 1, 0 ); - if ( type == transition_type ) + if ( type == mlt_service_transition_type ) { mlt_transition transition = MLT_TRANSITION( service ); int a_track = mlt_transition_get_a_track( transition ); @@ -326,7 +326,7 @@ int mlt_tractor_remove_track( mlt_tractor self, int index ) mlt_transition_set_tracks( transition, a_track, b_track ); } } - else if ( type == filter_type ) + else if ( type == mlt_service_filter_type ) { int current_track = mlt_properties_get_int( properties, "track" ); if ( current_track >= index ) diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index 583c0c733..5c9df5417 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -139,18 +139,18 @@ mlt_whence; typedef enum { - invalid_type = 0, /**< invalid service */ - unknown_type, /**< unknown class */ - producer_type, /**< Producer class */ - tractor_type, /**< Tractor class */ - playlist_type, /**< Playlist class */ - multitrack_type, /**< Multitrack class */ - filter_type, /**< Filter class */ - transition_type, /**< Transition class */ - consumer_type, /**< Consumer class */ - field_type, /**< Field class */ - link_type, /**< Link class */ - chain_type /**< Chain class */ + mlt_service_invalid_type = 0, /**< invalid service */ + mlt_service_unknown_type, /**< unknown class */ + mlt_service_producer_type, /**< Producer class */ + mlt_service_tractor_type, /**< Tractor class */ + mlt_service_playlist_type, /**< Playlist class */ + mlt_service_multitrack_type, /**< Multitrack class */ + mlt_service_filter_type, /**< Filter class */ + mlt_service_transition_type, /**< Transition class */ + mlt_service_consumer_type, /**< Consumer class */ + mlt_service_field_type, /**< Field class */ + mlt_service_link_type, /**< Link class */ + mlt_service_chain_type /**< Chain class */ } mlt_service_type; diff --git a/src/melt/melt.c b/src/melt/melt.c index 0327fb0d9..667ecbfb2 100644 --- a/src/melt/melt.c +++ b/src/melt/melt.c @@ -584,19 +584,19 @@ static void query_services( mlt_repository repo, mlt_service_type type ) const char *typestr = NULL; switch ( type ) { - case consumer_type: + case mlt_service_consumer_type: services = mlt_repository_consumers( repo ); typestr = "consumers"; break; - case filter_type: + case mlt_service_filter_type: services = mlt_repository_filters( repo ); typestr = "filters"; break; - case producer_type: + case mlt_service_producer_type: services = mlt_repository_producers( repo ); typestr = "producers"; break; - case transition_type: + case mlt_service_transition_type: services = mlt_repository_transitions( repo ); typestr = "transitions"; break; @@ -811,13 +811,13 @@ int main( int argc, char **argv ) if ( pname && pname[0] != '-' ) { if ( !strcmp( pname, "consumers" ) || !strcmp( pname, "consumer" ) ) - query_services( repo, consumer_type ); + query_services( repo, mlt_service_consumer_type ); else if ( !strcmp( pname, "filters" ) || !strcmp( pname, "filter" ) ) - query_services( repo, filter_type ); + query_services( repo, mlt_service_filter_type ); else if ( !strcmp( pname, "producers" ) || !strcmp( pname, "producer" ) ) - query_services( repo, producer_type ); + query_services( repo, mlt_service_producer_type ); else if ( !strcmp( pname, "transitions" ) || !strcmp( pname, "transition" ) ) - query_services( repo, transition_type ); + query_services( repo, mlt_service_transition_type ); else if ( !strcmp( pname, "profiles" ) || !strcmp( pname, "profile" ) ) query_profiles(); else if ( !strcmp( pname, "presets" ) || !strcmp( pname, "preset" ) ) @@ -830,13 +830,13 @@ int main( int argc, char **argv ) query_vcodecs(); else if ( !strncmp( pname, "consumer=", 9 ) ) - query_metadata( repo, consumer_type, "consumer", strchr( pname, '=' ) + 1 ); + query_metadata( repo, mlt_service_consumer_type, "consumer", strchr( pname, '=' ) + 1 ); else if ( !strncmp( pname, "filter=", 7 ) ) - query_metadata( repo, filter_type, "filter", strchr( pname, '=' ) + 1 ); + query_metadata( repo, mlt_service_filter_type, "filter", strchr( pname, '=' ) + 1 ); else if ( !strncmp( pname, "producer=", 9 ) ) - query_metadata( repo, producer_type, "producer", strchr( pname, '=' ) + 1 ); + query_metadata( repo, mlt_service_producer_type, "producer", strchr( pname, '=' ) + 1 ); else if ( !strncmp( pname, "transition=", 11 ) ) - query_metadata( repo, transition_type, "transition", strchr( pname, '=' ) + 1 ); + query_metadata( repo, mlt_service_transition_type, "transition", strchr( pname, '=' ) + 1 ); else if ( !strncmp( pname, "profile=", 8 ) ) query_profile( strchr( pname, '=' ) + 1 ); else if ( !strncmp( pname, "preset=", 7 ) ) @@ -847,10 +847,10 @@ int main( int argc, char **argv ) else { query_all: - query_services( repo, consumer_type ); - query_services( repo, filter_type ); - query_services( repo, producer_type ); - query_services( repo, transition_type ); + query_services( repo, mlt_service_consumer_type ); + query_services( repo, mlt_service_filter_type ); + query_services( repo, mlt_service_producer_type ); + query_services( repo, mlt_service_transition_type ); fprintf( stdout, "# You can query the metadata for a specific service using:\n" "# -query =\n" "# where is one of: consumer, filter, producer, or transition.\n" ); diff --git a/src/mlt++/MltChain.cpp b/src/mlt++/MltChain.cpp index 94aee894d..d1df6147f 100644 --- a/src/mlt++/MltChain.cpp +++ b/src/mlt++/MltChain.cpp @@ -62,7 +62,7 @@ Chain::Chain( Chain* chain ) : Chain::Chain( Service& chain ) : instance( NULL ) { - if ( chain.type( ) == chain_type ) + if ( chain.type( ) == mlt_service_chain_type ) { instance = ( mlt_chain )chain.get_service( ); inc_ref( ); diff --git a/src/mlt++/MltConsumer.cpp b/src/mlt++/MltConsumer.cpp index b70e24724..891ed502e 100644 --- a/src/mlt++/MltConsumer.cpp +++ b/src/mlt++/MltConsumer.cpp @@ -68,7 +68,7 @@ Consumer::Consumer( mlt_profile profile, const char *id, const char *arg ) : Consumer::Consumer( Service &consumer ) : instance( NULL ) { - if ( consumer.type( ) == consumer_type ) + if ( consumer.type( ) == mlt_service_consumer_type ) { instance = ( mlt_consumer )consumer.get_service( ); inc_ref( ); diff --git a/src/mlt++/MltFilter.cpp b/src/mlt++/MltFilter.cpp index 3fb8c2f29..45aad9e80 100644 --- a/src/mlt++/MltFilter.cpp +++ b/src/mlt++/MltFilter.cpp @@ -61,7 +61,7 @@ Filter::Filter( mlt_profile profile, const char *id, const char *arg ) : Filter::Filter( Service &filter ) : instance( NULL ) { - if ( filter.type( ) == filter_type ) + if ( filter.type( ) == mlt_service_filter_type ) { instance = ( mlt_filter )filter.get_service( ); inc_ref( ); diff --git a/src/mlt++/MltMultitrack.cpp b/src/mlt++/MltMultitrack.cpp index f76a42ff3..68951e7ad 100644 --- a/src/mlt++/MltMultitrack.cpp +++ b/src/mlt++/MltMultitrack.cpp @@ -31,7 +31,7 @@ Multitrack::Multitrack( mlt_multitrack multitrack ) : Multitrack::Multitrack( Service &multitrack ) : instance( NULL ) { - if ( multitrack.type( ) == multitrack_type ) + if ( multitrack.type( ) == mlt_service_multitrack_type ) { instance = ( mlt_multitrack )multitrack.get_service( ); inc_ref( ); diff --git a/src/mlt++/MltPlaylist.cpp b/src/mlt++/MltPlaylist.cpp index d0735176d..a1730680f 100644 --- a/src/mlt++/MltPlaylist.cpp +++ b/src/mlt++/MltPlaylist.cpp @@ -95,7 +95,7 @@ Playlist::Playlist( Profile& profile ) : Playlist::Playlist( Service &producer ) : instance( NULL ) { - if ( producer.type( ) == playlist_type ) + if ( producer.type( ) == mlt_service_playlist_type ) { instance = ( mlt_playlist )producer.get_service( ); inc_ref( ); diff --git a/src/mlt++/MltProducer.cpp b/src/mlt++/MltProducer.cpp index 4a061695f..00f79b834 100644 --- a/src/mlt++/MltProducer.cpp +++ b/src/mlt++/MltProducer.cpp @@ -50,9 +50,9 @@ Producer::Producer( Service &producer ) : parent_( NULL ) { mlt_service_type type = producer.type( ); - if ( type == producer_type || type == playlist_type || - type == tractor_type || type == multitrack_type || - type == chain_type || type == link_type ) + if ( type == mlt_service_producer_type || type == mlt_service_playlist_type || + type == mlt_service_tractor_type || type == mlt_service_multitrack_type || + type == mlt_service_chain_type || type == mlt_service_link_type ) { instance = ( mlt_producer )producer.get_service( ); inc_ref( ); diff --git a/src/mlt++/MltTractor.cpp b/src/mlt++/MltTractor.cpp index 3cf7b6c4f..b0e26a6f1 100644 --- a/src/mlt++/MltTractor.cpp +++ b/src/mlt++/MltTractor.cpp @@ -40,7 +40,7 @@ Tractor::Tractor( Profile& profile ) : Tractor::Tractor( Service &tractor ) : instance( NULL ) { - if ( tractor.type( ) == tractor_type ) + if ( tractor.type( ) == mlt_service_tractor_type ) { instance = ( mlt_tractor )tractor.get_service( ); inc_ref( ); @@ -69,7 +69,7 @@ Tractor::Tractor( mlt_profile profile, char *id, char *resource ) : instance( NULL ) { Producer producer( profile, id, resource ); - if ( producer.is_valid( ) && producer.type( ) == tractor_type ) + if ( producer.is_valid( ) && producer.type( ) == mlt_service_tractor_type ) { instance = ( mlt_tractor )producer.get_producer( ); inc_ref( ); diff --git a/src/mlt++/MltTransition.cpp b/src/mlt++/MltTransition.cpp index 29491d4d4..85dccf0f4 100644 --- a/src/mlt++/MltTransition.cpp +++ b/src/mlt++/MltTransition.cpp @@ -62,7 +62,7 @@ Transition::Transition( mlt_profile profile, const char *id, const char *arg ) : Transition::Transition( Service &transition ) : instance( NULL ) { - if ( transition.type( ) == transition_type ) + if ( transition.type( ) == mlt_service_transition_type ) { instance = ( mlt_transition )transition.get_service( ); inc_ref( ); diff --git a/src/modules/avformat/factory.c b/src/modules/avformat/factory.c index c05dcbc97..e5c555f75 100644 --- a/src/modules/avformat/factory.c +++ b/src/modules/avformat/factory.c @@ -112,9 +112,9 @@ static void *create_service( mlt_profile profile, mlt_service_type type, const c #ifdef CODECS if ( !strncmp( id, "avformat", 8 ) ) { - if ( type == producer_type ) + if ( type == mlt_service_producer_type ) return producer_avformat_init( profile, id, arg ); - else if ( type == consumer_type ) + else if ( type == mlt_service_consumer_type ) return consumer_avformat_init( profile, arg ); } #endif @@ -294,23 +294,23 @@ static mlt_properties avformat_metadata( mlt_service_type type, const char *id, // Convert the service type to a string. switch ( type ) { - case consumer_type: + case mlt_service_consumer_type: service_type = "consumer"; break; - case filter_type: + case mlt_service_filter_type: service_type = "filter"; break; - case producer_type: + case mlt_service_producer_type: service_type = "producer"; break; - case transition_type: + case mlt_service_transition_type: service_type = "transition"; break; default: return NULL; } - if ( type == producer_type && !strcmp( id, "avformat-novalidate" ) ) + if ( type == mlt_service_producer_type && !strcmp( id, "avformat-novalidate" ) ) { id = "avformat"; } @@ -318,17 +318,17 @@ static mlt_properties avformat_metadata( mlt_service_type type, const char *id, // Load the yaml file snprintf( file, PATH_MAX, "%s/avformat/%s_%s.yml", mlt_environment( "MLT_DATA" ), service_type, id ); result = mlt_properties_parse_yaml( file ); - if ( result && ( type == consumer_type || type == producer_type ) ) + if ( result && ( type == mlt_service_consumer_type || type == mlt_service_producer_type ) ) { // Annotate the yaml properties with AVOptions. mlt_properties params = (mlt_properties) mlt_properties_get_data( result, "parameters", NULL ); AVFormatContext *avformat = avformat_alloc_context(); AVCodecContext *avcodec = avcodec_alloc_context3( NULL ); - int flags = ( type == consumer_type )? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM; + int flags = ( type == mlt_service_consumer_type )? AV_OPT_FLAG_ENCODING_PARAM : AV_OPT_FLAG_DECODING_PARAM; add_parameters( params, avformat, flags, NULL, NULL, NULL ); avformat_init(); - if ( type == producer_type ) + if ( type == mlt_service_producer_type ) { AVInputFormat *f = NULL; while ( ( f = av_iformat_next( f ) ) ) @@ -426,18 +426,18 @@ static mlt_properties avfilter_metadata( mlt_service_type type, const char *id, MLT_REPOSITORY { #ifdef CODECS - MLT_REGISTER( consumer_type, "avformat", create_service ); - MLT_REGISTER( producer_type, "avformat", create_service ); - MLT_REGISTER( producer_type, "avformat-novalidate", create_service ); - MLT_REGISTER_METADATA( consumer_type, "avformat", avformat_metadata, NULL ); - MLT_REGISTER_METADATA( producer_type, "avformat", avformat_metadata, NULL ); - MLT_REGISTER_METADATA( producer_type, "avformat-novalidate", avformat_metadata, NULL ); + MLT_REGISTER( mlt_service_consumer_type, "avformat", create_service ); + MLT_REGISTER( mlt_service_producer_type, "avformat", create_service ); + MLT_REGISTER( mlt_service_producer_type, "avformat-novalidate", create_service ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "avformat", avformat_metadata, NULL ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "avformat", avformat_metadata, NULL ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "avformat-novalidate", avformat_metadata, NULL ); #endif #ifdef FILTERS - MLT_REGISTER( filter_type, "avcolour_space", create_service ); - MLT_REGISTER( filter_type, "avcolor_space", create_service ); - MLT_REGISTER( filter_type, "avdeinterlace", create_service ); - MLT_REGISTER( filter_type, "swscale", create_service ); + MLT_REGISTER( mlt_service_filter_type, "avcolour_space", create_service ); + MLT_REGISTER( mlt_service_filter_type, "avcolor_space", create_service ); + MLT_REGISTER( mlt_service_filter_type, "avdeinterlace", create_service ); + MLT_REGISTER( mlt_service_filter_type, "swscale", create_service ); #ifdef AVFILTER char dirname[PATH_MAX]; @@ -464,14 +464,14 @@ MLT_REPOSITORY { char service_name[1024]="avfilter."; strncat( service_name, f->name, sizeof( service_name ) - strlen( service_name ) -1 ); - MLT_REGISTER( filter_type, service_name, filter_avfilter_init ); - MLT_REGISTER_METADATA( filter_type, service_name, avfilter_metadata, (void*)f->name ); + MLT_REGISTER( mlt_service_filter_type, service_name, filter_avfilter_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, service_name, avfilter_metadata, (void*)f->name ); } } mlt_properties_close( blacklist ); #endif // AVFILTER #endif #ifdef SWRESAMPLE - MLT_REGISTER( filter_type, "swresample", create_service ); + MLT_REGISTER( mlt_service_filter_type, "swresample", create_service ); #endif } diff --git a/src/modules/core/factory.c b/src/modules/core/factory.c index 9828c8198..6c0bff5e8 100644 --- a/src/modules/core/factory.c +++ b/src/modules/core/factory.c @@ -74,93 +74,93 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "multi", consumer_multi_init ); - MLT_REGISTER( consumer_type, "null", consumer_null_init ); - MLT_REGISTER( filter_type, "audiochannels", filter_audiochannels_init ); - MLT_REGISTER( filter_type, "audioconvert", filter_audioconvert_init ); - MLT_REGISTER( filter_type, "audiomap", filter_audiomap_init ); - MLT_REGISTER( filter_type, "audiowave", filter_audiowave_init ); - MLT_REGISTER( filter_type, "brightness", filter_brightness_init ); - MLT_REGISTER( filter_type, "channelcopy", filter_channelcopy_init ); - MLT_REGISTER( filter_type, "channelswap", filter_channelcopy_init ); - MLT_REGISTER( filter_type, "choppy", filter_choppy_init ); - MLT_REGISTER( filter_type, "crop", filter_crop_init ); - MLT_REGISTER( filter_type, "data_feed", filter_data_feed_init ); - MLT_REGISTER( filter_type, "data_show", filter_data_show_init ); - MLT_REGISTER( filter_type, "fieldorder", filter_fieldorder_init ); - MLT_REGISTER( filter_type, "gamma", filter_gamma_init ); - MLT_REGISTER( filter_type, "greyscale", filter_greyscale_init ); - MLT_REGISTER( filter_type, "grayscale", filter_greyscale_init ); - MLT_REGISTER( filter_type, "imageconvert", filter_imageconvert_init ); - MLT_REGISTER( filter_type, "luma", filter_luma_init ); - MLT_REGISTER( filter_type, "mask_apply", filter_mask_apply_init ); - MLT_REGISTER( filter_type, "mask_start", filter_mask_start_init ); - MLT_REGISTER( filter_type, "mirror", filter_mirror_init ); - MLT_REGISTER( filter_type, "mono", filter_mono_init ); - MLT_REGISTER( filter_type, "obscure", filter_obscure_init ); - MLT_REGISTER( filter_type, "panner", filter_panner_init ); - MLT_REGISTER( filter_type, "region", filter_region_init ); - MLT_REGISTER( filter_type, "rescale", filter_rescale_init ); - MLT_REGISTER( filter_type, "resize", filter_resize_init ); - MLT_REGISTER( filter_type, "transition", filter_transition_init ); - MLT_REGISTER( filter_type, "watermark", filter_watermark_init ); - MLT_REGISTER( link_type, "timeremap", link_timeremap_init ); - MLT_REGISTER( producer_type, "abnormal", producer_loader_init ); - MLT_REGISTER( producer_type, "color", producer_colour_init ); - MLT_REGISTER( producer_type, "colour", producer_colour_init ); - MLT_REGISTER( producer_type, "consumer", producer_consumer_init ); - MLT_REGISTER( producer_type, "hold", producer_hold_init ); - MLT_REGISTER( producer_type, "loader", producer_loader_init ); - MLT_REGISTER( producer_type, "melt", producer_melt_init ); - MLT_REGISTER( producer_type, "melt_file", producer_melt_file_init ); - MLT_REGISTER( producer_type, "noise", producer_noise_init ); - MLT_REGISTER( producer_type, "timewarp", producer_timewarp_init ); - MLT_REGISTER( producer_type, "tone", producer_tone_init ); - MLT_REGISTER( transition_type, "composite", transition_composite_init ); - MLT_REGISTER( transition_type, "luma", transition_luma_init ); - MLT_REGISTER( transition_type, "mix", transition_mix_init ); - MLT_REGISTER( transition_type, "matte", transition_matte_init ); - MLT_REGISTER( transition_type, "region", transition_region_init ); + MLT_REGISTER( mlt_service_consumer_type, "multi", consumer_multi_init ); + MLT_REGISTER( mlt_service_consumer_type, "null", consumer_null_init ); + MLT_REGISTER( mlt_service_filter_type, "audiochannels", filter_audiochannels_init ); + MLT_REGISTER( mlt_service_filter_type, "audioconvert", filter_audioconvert_init ); + MLT_REGISTER( mlt_service_filter_type, "audiomap", filter_audiomap_init ); + MLT_REGISTER( mlt_service_filter_type, "audiowave", filter_audiowave_init ); + MLT_REGISTER( mlt_service_filter_type, "brightness", filter_brightness_init ); + MLT_REGISTER( mlt_service_filter_type, "channelcopy", filter_channelcopy_init ); + MLT_REGISTER( mlt_service_filter_type, "channelswap", filter_channelcopy_init ); + MLT_REGISTER( mlt_service_filter_type, "choppy", filter_choppy_init ); + MLT_REGISTER( mlt_service_filter_type, "crop", filter_crop_init ); + MLT_REGISTER( mlt_service_filter_type, "data_feed", filter_data_feed_init ); + MLT_REGISTER( mlt_service_filter_type, "data_show", filter_data_show_init ); + MLT_REGISTER( mlt_service_filter_type, "fieldorder", filter_fieldorder_init ); + MLT_REGISTER( mlt_service_filter_type, "gamma", filter_gamma_init ); + MLT_REGISTER( mlt_service_filter_type, "greyscale", filter_greyscale_init ); + MLT_REGISTER( mlt_service_filter_type, "grayscale", filter_greyscale_init ); + MLT_REGISTER( mlt_service_filter_type, "imageconvert", filter_imageconvert_init ); + MLT_REGISTER( mlt_service_filter_type, "luma", filter_luma_init ); + MLT_REGISTER( mlt_service_filter_type, "mask_apply", filter_mask_apply_init ); + MLT_REGISTER( mlt_service_filter_type, "mask_start", filter_mask_start_init ); + MLT_REGISTER( mlt_service_filter_type, "mirror", filter_mirror_init ); + MLT_REGISTER( mlt_service_filter_type, "mono", filter_mono_init ); + MLT_REGISTER( mlt_service_filter_type, "obscure", filter_obscure_init ); + MLT_REGISTER( mlt_service_filter_type, "panner", filter_panner_init ); + MLT_REGISTER( mlt_service_filter_type, "region", filter_region_init ); + MLT_REGISTER( mlt_service_filter_type, "rescale", filter_rescale_init ); + MLT_REGISTER( mlt_service_filter_type, "resize", filter_resize_init ); + MLT_REGISTER( mlt_service_filter_type, "transition", filter_transition_init ); + MLT_REGISTER( mlt_service_filter_type, "watermark", filter_watermark_init ); + MLT_REGISTER( mlt_service_link_type, "timeremap", link_timeremap_init ); + MLT_REGISTER( mlt_service_producer_type, "abnormal", producer_loader_init ); + MLT_REGISTER( mlt_service_producer_type, "color", producer_colour_init ); + MLT_REGISTER( mlt_service_producer_type, "colour", producer_colour_init ); + MLT_REGISTER( mlt_service_producer_type, "consumer", producer_consumer_init ); + MLT_REGISTER( mlt_service_producer_type, "hold", producer_hold_init ); + MLT_REGISTER( mlt_service_producer_type, "loader", producer_loader_init ); + MLT_REGISTER( mlt_service_producer_type, "melt", producer_melt_init ); + MLT_REGISTER( mlt_service_producer_type, "melt_file", producer_melt_file_init ); + MLT_REGISTER( mlt_service_producer_type, "noise", producer_noise_init ); + MLT_REGISTER( mlt_service_producer_type, "timewarp", producer_timewarp_init ); + MLT_REGISTER( mlt_service_producer_type, "tone", producer_tone_init ); + MLT_REGISTER( mlt_service_transition_type, "composite", transition_composite_init ); + MLT_REGISTER( mlt_service_transition_type, "luma", transition_luma_init ); + MLT_REGISTER( mlt_service_transition_type, "mix", transition_mix_init ); + MLT_REGISTER( mlt_service_transition_type, "matte", transition_matte_init ); + MLT_REGISTER( mlt_service_transition_type, "region", transition_region_init ); - MLT_REGISTER_METADATA( consumer_type, "multi", metadata, "consumer_multi.yml" ); - MLT_REGISTER_METADATA( filter_type, "audiomap", metadata, "filter_audiomap.yml" ); - MLT_REGISTER_METADATA( filter_type, "audiowave", metadata, "filter_audiowave.yml" ); - MLT_REGISTER_METADATA( filter_type, "brightness", metadata, "filter_brightness.yml" ); - MLT_REGISTER_METADATA( filter_type, "channelcopy", metadata, "filter_channelcopy.yml" ); - MLT_REGISTER_METADATA( filter_type, "channelswap", metadata, "filter_channelcopy.yml" ); - MLT_REGISTER_METADATA( filter_type, "choppy", metadata, "filter_choppy.yml" ); - MLT_REGISTER_METADATA( filter_type, "crop", metadata, "filter_crop.yml" ); - MLT_REGISTER_METADATA( filter_type, "data_show", metadata, "filter_data_show.yml" ); - MLT_REGISTER_METADATA( filter_type, "fieldorder", metadata, "filter_fieldorder.yml" ); - MLT_REGISTER_METADATA( filter_type, "gamma", metadata, "filter_gamma.yml" ); - MLT_REGISTER_METADATA( filter_type, "greyscale", metadata, "filter_greyscale.yml" ); - MLT_REGISTER_METADATA( filter_type, "grayscale", metadata, "filter_greyscale.yml" ); - MLT_REGISTER_METADATA( filter_type, "luma", metadata, "filter_luma.yml" ); - MLT_REGISTER_METADATA( filter_type, "mask_apply", metadata, "filter_mask_apply.yml" ); - MLT_REGISTER_METADATA( filter_type, "mask_start", metadata, "filter_mask_start.yml" ); - MLT_REGISTER_METADATA( filter_type, "mirror", metadata, "filter_mirror.yml" ); - MLT_REGISTER_METADATA( filter_type, "mono", metadata, "filter_mono.yml" ); - MLT_REGISTER_METADATA( filter_type, "obscure", metadata, "filter_obscure.yml" ); - MLT_REGISTER_METADATA( filter_type, "panner", metadata, "filter_panner.yml" ); - MLT_REGISTER_METADATA( filter_type, "region", metadata, "filter_region.yml" ); - MLT_REGISTER_METADATA( filter_type, "rescale", metadata, "filter_rescale.yml" ); - MLT_REGISTER_METADATA( filter_type, "resize", metadata, "filter_resize.yml" ); - MLT_REGISTER_METADATA( filter_type, "transition", metadata, "filter_transition.yml" ); - MLT_REGISTER_METADATA( filter_type, "watermark", metadata, "filter_watermark.yml" ); - MLT_REGISTER_METADATA( link_type, "timeremap", metadata, "link_timeremap.yml" ); - MLT_REGISTER_METADATA( producer_type, "colour", metadata, "producer_colour.yml" ); - MLT_REGISTER_METADATA( producer_type, "color", metadata, "producer_colour.yml" ); - MLT_REGISTER_METADATA( producer_type, "consumer", metadata, "producer_consumer.yml" ); - MLT_REGISTER_METADATA( producer_type, "hold", metadata, "producer_hold.yml" ); - MLT_REGISTER_METADATA( producer_type, "loader", metadata, "producer_loader.yml" ); - MLT_REGISTER_METADATA( producer_type, "melt", metadata, "producer_melt.yml" ); - MLT_REGISTER_METADATA( producer_type, "melt_file", metadata, "producer_melt_file.yml" ); - MLT_REGISTER_METADATA( producer_type, "noise", metadata, "producer_noise.yml" ); - MLT_REGISTER_METADATA( producer_type, "timewarp", metadata, "producer_timewarp.yml" ); - MLT_REGISTER_METADATA( producer_type, "tone", metadata, "producer_tone.yml" ); - MLT_REGISTER_METADATA( transition_type, "composite", metadata, "transition_composite.yml" ); - MLT_REGISTER_METADATA( transition_type, "luma", metadata, "transition_luma.yml" ); - MLT_REGISTER_METADATA( transition_type, "mix", metadata, "transition_mix.yml" ); - MLT_REGISTER_METADATA( transition_type, "matte", metadata, "transition_matte.yml" ); - MLT_REGISTER_METADATA( transition_type, "region", metadata, "transition_region.yml" ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "multi", metadata, "consumer_multi.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "audiomap", metadata, "filter_audiomap.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "audiowave", metadata, "filter_audiowave.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "brightness", metadata, "filter_brightness.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "channelcopy", metadata, "filter_channelcopy.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "channelswap", metadata, "filter_channelcopy.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "choppy", metadata, "filter_choppy.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "crop", metadata, "filter_crop.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "data_show", metadata, "filter_data_show.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "fieldorder", metadata, "filter_fieldorder.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "gamma", metadata, "filter_gamma.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "greyscale", metadata, "filter_greyscale.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "grayscale", metadata, "filter_greyscale.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "luma", metadata, "filter_luma.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "mask_apply", metadata, "filter_mask_apply.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "mask_start", metadata, "filter_mask_start.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "mirror", metadata, "filter_mirror.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "mono", metadata, "filter_mono.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "obscure", metadata, "filter_obscure.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "panner", metadata, "filter_panner.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "region", metadata, "filter_region.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "rescale", metadata, "filter_rescale.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "resize", metadata, "filter_resize.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "transition", metadata, "filter_transition.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "watermark", metadata, "filter_watermark.yml" ); + MLT_REGISTER_METADATA( mlt_service_link_type, "timeremap", metadata, "link_timeremap.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "colour", metadata, "producer_colour.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "color", metadata, "producer_colour.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "consumer", metadata, "producer_consumer.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "hold", metadata, "producer_hold.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "loader", metadata, "producer_loader.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "melt", metadata, "producer_melt.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "melt_file", metadata, "producer_melt_file.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "noise", metadata, "producer_noise.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "timewarp", metadata, "producer_timewarp.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "tone", metadata, "producer_tone.yml" ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "composite", metadata, "transition_composite.yml" ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "luma", metadata, "transition_luma.yml" ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "mix", metadata, "transition_mix.yml" ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "matte", metadata, "transition_matte.yml" ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "region", metadata, "transition_region.yml" ); } diff --git a/src/modules/core/producer_timewarp.c b/src/modules/core/producer_timewarp.c index e4ff3b3cb..e3dcf943f 100644 --- a/src/modules/core/producer_timewarp.c +++ b/src/modules/core/producer_timewarp.c @@ -278,7 +278,7 @@ mlt_producer producer_timewarp_init( mlt_profile profile, mlt_service_type type, // they can be passed between the clip producer and this producer. pdata->clip_parameters = mlt_properties_new(); mlt_repository repository = mlt_factory_repository(); - mlt_properties clip_metadata = mlt_repository_metadata( repository, producer_type, mlt_properties_get( clip_properties, "mlt_service" ) ); + mlt_properties clip_metadata = mlt_repository_metadata( repository, mlt_service_producer_type, mlt_properties_get( clip_properties, "mlt_service" ) ); if ( clip_metadata ) { mlt_properties params = (mlt_properties) mlt_properties_get_data( clip_metadata, "parameters", NULL ); diff --git a/src/modules/decklink/consumer_decklink.cpp b/src/modules/decklink/consumer_decklink.cpp index 7a8a4de8f..6f79f0130 100644 --- a/src/modules/decklink/consumer_decklink.cpp +++ b/src/modules/decklink/consumer_decklink.cpp @@ -1017,10 +1017,10 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat const char *service_type = NULL; switch ( type ) { - case consumer_type: + case mlt_service_consumer_type: service_type = "consumer"; break; - case producer_type: + case mlt_service_producer_type: service_type = "producer"; break; default: @@ -1032,10 +1032,10 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "decklink", consumer_decklink_init ); - MLT_REGISTER( producer_type, "decklink", producer_decklink_init ); - MLT_REGISTER_METADATA( consumer_type, "decklink", metadata, NULL ); - MLT_REGISTER_METADATA( producer_type, "decklink", metadata, NULL ); + MLT_REGISTER( mlt_service_consumer_type, "decklink", consumer_decklink_init ); + MLT_REGISTER( mlt_service_producer_type, "decklink", producer_decklink_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "decklink", metadata, NULL ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "decklink", metadata, NULL ); } } // extern C diff --git a/src/modules/dv/factory.c b/src/modules/dv/factory.c index f3befb7db..d5bc2bf53 100644 --- a/src/modules/dv/factory.c +++ b/src/modules/dv/factory.c @@ -33,9 +33,9 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "libdv", consumer_libdv_init ); - MLT_REGISTER( producer_type, "libdv", producer_libdv_init ); + MLT_REGISTER( mlt_service_consumer_type, "libdv", consumer_libdv_init ); + MLT_REGISTER( mlt_service_producer_type, "libdv", producer_libdv_init ); - MLT_REGISTER_METADATA( consumer_type, "libdv", metadata, "consumer_libdv.yml" ); - MLT_REGISTER_METADATA( producer_type, "libdv", metadata, "producer_libdv.yml" ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "libdv", metadata, "consumer_libdv.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "libdv", metadata, "producer_libdv.yml" ); } diff --git a/src/modules/frei0r/factory.c b/src/modules/frei0r/factory.c index dd72b2ba2..da25f4a18 100644 --- a/src/modules/frei0r/factory.c +++ b/src/modules/frei0r/factory.c @@ -100,13 +100,13 @@ static mlt_properties fill_param_info(mlt_service_type type, const char *service struct stat stat_buff; switch (type) { - case producer_type: + case mlt_service_producer_type: strcpy(servicetype, "producer"); break; - case filter_type: + case mlt_service_filter_type: strcpy(servicetype, "filter"); break; - case transition_type: + case mlt_service_transition_type: strcpy(servicetype, "transition"); break; default: @@ -158,13 +158,13 @@ static mlt_properties fill_param_info(mlt_service_type type, const char *service mlt_properties_set(metadata, "description" , info.explanation); mlt_properties_set(metadata, "creator" , info.author); switch (type) { - case producer_type: + case mlt_service_producer_type: mlt_properties_set(metadata, "type", "producer"); break; - case filter_type: + case mlt_service_filter_type: mlt_properties_set(metadata, "type", "filter"); break; - case transition_type: + case mlt_service_transition_type: mlt_properties_set(metadata, "type", "transition"); break; default: @@ -265,7 +265,7 @@ static void* load_lib(mlt_profile profile, mlt_service_type type , void* handle, mlt_properties properties = NULL; char minor[12]; - if (type == producer_type && info.plugin_type == F0R_PLUGIN_TYPE_SOURCE) { + if (type == mlt_service_producer_type && info.plugin_type == F0R_PLUGIN_TYPE_SOURCE) { mlt_producer producer = mlt_producer_new(profile); if (producer) { @@ -281,7 +281,7 @@ static void* load_lib(mlt_profile profile, mlt_service_type type , void* handle, ret = producer; } - } else if (type == filter_type && info.plugin_type == F0R_PLUGIN_TYPE_FILTER) { + } else if (type == mlt_service_filter_type && info.plugin_type == F0R_PLUGIN_TYPE_FILTER) { mlt_filter filter = mlt_filter_new(); if (filter) { @@ -297,7 +297,7 @@ static void* load_lib(mlt_profile profile, mlt_service_type type , void* handle, ret = filter; } - } else if (type == transition_type && info.plugin_type == F0R_PLUGIN_TYPE_MIXER2) { + } else if (type == mlt_service_transition_type && info.plugin_type == F0R_PLUGIN_TYPE_MIXER2) { mlt_transition transition = mlt_transition_new(); if (transition) { @@ -469,8 +469,8 @@ MLT_REPOSITORY dlclose(handle); continue; } - MLT_REGISTER(producer_type, pluginname, create_frei0r_item); - MLT_REGISTER_METADATA(producer_type, pluginname, fill_param_info, name); + MLT_REGISTER(mlt_service_producer_type, pluginname, create_frei0r_item); + MLT_REGISTER_METADATA(mlt_service_producer_type, pluginname, fill_param_info, name); } else if (firstname && info.plugin_type == F0R_PLUGIN_TYPE_FILTER) { if (mlt_properties_get(mlt_repository_filters(repository), pluginname)) @@ -478,8 +478,8 @@ MLT_REPOSITORY dlclose(handle); continue; } - MLT_REGISTER(filter_type, pluginname, create_frei0r_item); - MLT_REGISTER_METADATA(filter_type, pluginname, fill_param_info, name); + MLT_REGISTER(mlt_service_filter_type, pluginname, create_frei0r_item); + MLT_REGISTER_METADATA(mlt_service_filter_type, pluginname, fill_param_info, name); } else if (firstname && info.plugin_type==F0R_PLUGIN_TYPE_MIXER2 ) { if (mlt_properties_get(mlt_repository_transitions(repository), pluginname)) @@ -487,8 +487,8 @@ MLT_REPOSITORY dlclose(handle); continue; } - MLT_REGISTER(transition_type, pluginname, create_frei0r_item); - MLT_REGISTER_METADATA(transition_type, pluginname, fill_param_info, name); + MLT_REGISTER(mlt_service_transition_type, pluginname, create_frei0r_item); + MLT_REGISTER_METADATA(mlt_service_transition_type, pluginname, fill_param_info, name); } } dlclose(handle); @@ -499,6 +499,6 @@ MLT_REPOSITORY mlt_tokeniser_close(tokeniser); mlt_properties_close(blacklist); free(frei0r_path); - MLT_REGISTER(filter_type, "cairoblend_mode", filter_cairoblend_mode_init); - MLT_REGISTER_METADATA(filter_type, "cairoblend_mode", metadata, "filter_cairoblend_mode.yml"); + MLT_REGISTER(mlt_service_filter_type, "cairoblend_mode", filter_cairoblend_mode_init); + MLT_REGISTER_METADATA(mlt_service_filter_type, "cairoblend_mode", metadata, "filter_cairoblend_mode.yml"); } diff --git a/src/modules/frei0r/frei0r_helper.c b/src/modules/frei0r/frei0r_helper.c index 6cff2911a..fef61bf5a 100644 --- a/src/modules/frei0r/frei0r_helper.c +++ b/src/modules/frei0r/frei0r_helper.c @@ -233,20 +233,20 @@ int process_frei0r_item( mlt_service service, mlt_position position, double time uint32_t *dest = result; if (info.color_model == F0R_COLOR_MODEL_BGRA8888) { - if (type == producer_type) { + if (type == mlt_service_producer_type) { dest = source[0]; } else { rgba_bgra(image[0], (uint8_t*) result, *width, *height); source[0] = result; dest = (uint32_t*) image[0]; - if (type == transition_type && f0r_update2) { + if (type == mlt_service_transition_type && f0r_update2) { extra = mlt_pool_alloc(video_area * sizeof(uint32_t)); rgba_bgra(image[1], (uint8_t*) extra, *width, *height); source[1] = extra; } } } - if (type == producer_type) { + if (type == mlt_service_producer_type) { if (slice_count > 0) { struct update_context ctx = { .frei0r = inst, @@ -261,7 +261,7 @@ int process_frei0r_item( mlt_service service, mlt_position position, double time } else { f0r_update(inst, time, NULL, dest); } - } else if (type == filter_type) { + } else if (type == mlt_service_filter_type) { if (slice_count > 0) { struct update_context ctx = { .frei0r = inst, @@ -276,7 +276,7 @@ int process_frei0r_item( mlt_service service, mlt_position position, double time } else { f0r_update(inst, time, source[0], dest); } - } else if (type == transition_type && f0r_update2) { + } else if (type == mlt_service_transition_type && f0r_update2) { if (slice_count > 0) { struct update_context ctx = { .frei0r = inst, diff --git a/src/modules/gdk/factory.c b/src/modules/gdk/factory.c index c66f48157..5692be1ea 100644 --- a/src/modules/gdk/factory.c +++ b/src/modules/gdk/factory.c @@ -87,11 +87,11 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "gtkrescale", create_service ); - MLT_REGISTER( producer_type, "pango", create_service ); - MLT_REGISTER( producer_type, "pixbuf", create_service ); + MLT_REGISTER( mlt_service_filter_type, "gtkrescale", create_service ); + MLT_REGISTER( mlt_service_producer_type, "pango", create_service ); + MLT_REGISTER( mlt_service_producer_type, "pixbuf", create_service ); - MLT_REGISTER_METADATA( filter_type, "gtkrescale", metadata, "filter_rescale.yml" ); - MLT_REGISTER_METADATA( producer_type, "pango", metadata, "producer_pango.yml" ); - MLT_REGISTER_METADATA( producer_type, "pixbuf", metadata, "producer_pixbuf.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "gtkrescale", metadata, "filter_rescale.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "pango", metadata, "producer_pango.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "pixbuf", metadata, "producer_pixbuf.yml" ); } diff --git a/src/modules/gtk2/factory.c b/src/modules/gtk2/factory.c index 96bb20843..85857ddf7 100644 --- a/src/modules/gtk2/factory.c +++ b/src/modules/gtk2/factory.c @@ -57,7 +57,7 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "gtk2_preview", create_service ); + MLT_REGISTER( mlt_service_consumer_type, "gtk2_preview", create_service ); - MLT_REGISTER_METADATA( consumer_type, "gtk2_preview", metadata, "consumer_gtk2_preview.yml" ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "gtk2_preview", metadata, "consumer_gtk2_preview.yml" ); } diff --git a/src/modules/jackrack/factory.c b/src/modules/jackrack/factory.c index 6ec3a47f0..e7338dfe6 100644 --- a/src/modules/jackrack/factory.c +++ b/src/modules/jackrack/factory.c @@ -88,7 +88,7 @@ static void add_port_to_metadata( mlt_properties p, plugin_desc_t* desc, int j ) static mlt_properties metadata( mlt_service_type type, const char *id, char *data ) { char file[ PATH_MAX ]; - if( type == filter_type ) + if( type == mlt_service_filter_type ) { snprintf( file, PATH_MAX, "%s/jackrack/%s", mlt_environment( "MLT_DATA" ), strncmp( id, "ladspa.", 7 ) ? data : "filter_ladspa.yml" ); @@ -158,7 +158,7 @@ static mlt_properties metadata( mlt_service_type type, const char *id, char *dat mlt_properties_set( p, "type", "integer" ); mlt_properties_set( p, "readonly", "yes" ); - if( type == filter_type ) + if( type == mlt_service_filter_type ) { p = mlt_properties_new(); snprintf( key, sizeof(key), "%d", mlt_properties_count( params ) ); @@ -193,25 +193,25 @@ MLT_REPOSITORY if( desc->has_input ) { - MLT_REGISTER( filter_type, s, filter_ladspa_init ); - MLT_REGISTER_METADATA( filter_type, s, metadata, NULL ); + MLT_REGISTER( mlt_service_filter_type, s, filter_ladspa_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, s, metadata, NULL ); } else { - MLT_REGISTER( producer_type, s, producer_ladspa_init ); - MLT_REGISTER_METADATA( producer_type, s, metadata, NULL ); + MLT_REGISTER( mlt_service_producer_type, s, producer_ladspa_init ); + MLT_REGISTER_METADATA( mlt_service_producer_type, s, metadata, NULL ); } free( s ); } mlt_factory_register_for_clean_up( g_jackrack_plugin_mgr, (mlt_destructor) plugin_mgr_destroy ); - MLT_REGISTER( filter_type, "jack", filter_jackrack_init ); - MLT_REGISTER( filter_type, "jackrack", filter_jackrack_init ); - MLT_REGISTER_METADATA( filter_type, "jackrack", metadata, "filter_jackrack.yml" ); - MLT_REGISTER( filter_type, "ladspa", filter_ladspa_init ); - MLT_REGISTER_METADATA( filter_type, "ladspa", metadata, "filter_ladspa.yml" ); + MLT_REGISTER( mlt_service_filter_type, "jack", filter_jackrack_init ); + MLT_REGISTER( mlt_service_filter_type, "jackrack", filter_jackrack_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "jackrack", metadata, "filter_jackrack.yml" ); + MLT_REGISTER( mlt_service_filter_type, "ladspa", filter_ladspa_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "ladspa", metadata, "filter_ladspa.yml" ); #endif - MLT_REGISTER( consumer_type, "jack", consumer_jack_init ); - MLT_REGISTER_METADATA( consumer_type, "jack", metadata, "consumer_jack.yml" ); + MLT_REGISTER( mlt_service_consumer_type, "jack", consumer_jack_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "jack", metadata, "consumer_jack.yml" ); } diff --git a/src/modules/kdenlive/factory.c b/src/modules/kdenlive/factory.c index b715f6b8e..b55cd7818 100644 --- a/src/modules/kdenlive/factory.c +++ b/src/modules/kdenlive/factory.c @@ -35,13 +35,13 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "boxblur", filter_boxblur_init ); - MLT_REGISTER( filter_type, "freeze", filter_freeze_init ); - MLT_REGISTER( filter_type, "wave", filter_wave_init ); - MLT_REGISTER( producer_type, "framebuffer", producer_framebuffer_init ); + MLT_REGISTER( mlt_service_filter_type, "boxblur", filter_boxblur_init ); + MLT_REGISTER( mlt_service_filter_type, "freeze", filter_freeze_init ); + MLT_REGISTER( mlt_service_filter_type, "wave", filter_wave_init ); + MLT_REGISTER( mlt_service_producer_type, "framebuffer", producer_framebuffer_init ); - MLT_REGISTER_METADATA( filter_type, "boxblur", metadata, "filter_boxblur.yml" ); - MLT_REGISTER_METADATA( filter_type, "freeze", metadata, "filter_freeze.yml" ); - MLT_REGISTER_METADATA( filter_type, "wave", metadata, "filter_wave.yml" ); - MLT_REGISTER_METADATA( producer_type, "framebuffer", metadata, "producer_framebuffer.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "boxblur", metadata, "filter_boxblur.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "freeze", metadata, "filter_freeze.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "wave", metadata, "filter_wave.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "framebuffer", metadata, "producer_framebuffer.yml" ); } diff --git a/src/modules/kino/factory.c b/src/modules/kino/factory.c index 46cde7cc9..1ccdfd898 100644 --- a/src/modules/kino/factory.c +++ b/src/modules/kino/factory.c @@ -24,5 +24,5 @@ extern mlt_producer producer_kino_init( mlt_profile profile, mlt_service_type ty MLT_REPOSITORY { - MLT_REGISTER( producer_type, "kino", producer_kino_init ); + MLT_REGISTER( mlt_service_producer_type, "kino", producer_kino_init ); } diff --git a/src/modules/linsys/factory.c b/src/modules/linsys/factory.c index 9519e0df8..e34b3a67f 100644 --- a/src/modules/linsys/factory.c +++ b/src/modules/linsys/factory.c @@ -17,6 +17,6 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "sdi", consumer_SDIstream_init ); - MLT_REGISTER_METADATA( consumer_type, "sdi", metadata, "consumer_sdi.yml" ); + MLT_REGISTER( mlt_service_consumer_type, "sdi", consumer_SDIstream_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdi", metadata, "consumer_sdi.yml" ); } diff --git a/src/modules/motion_est/factory.c b/src/modules/motion_est/factory.c index d234b9788..b25709eba 100644 --- a/src/modules/motion_est/factory.c +++ b/src/modules/motion_est/factory.c @@ -33,15 +33,15 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "motion_est", filter_motion_est_init ); - MLT_REGISTER( filter_type, "vismv", filter_vismv_init ); - MLT_REGISTER( filter_type, "crop_detect", filter_crop_detect_init ); - MLT_REGISTER( filter_type, "autotrack_rectangle", filter_autotrack_rectangle_init ); - MLT_REGISTER( producer_type, "slowmotion", producer_slowmotion_init ); + MLT_REGISTER( mlt_service_filter_type, "motion_est", filter_motion_est_init ); + MLT_REGISTER( mlt_service_filter_type, "vismv", filter_vismv_init ); + MLT_REGISTER( mlt_service_filter_type, "crop_detect", filter_crop_detect_init ); + MLT_REGISTER( mlt_service_filter_type, "autotrack_rectangle", filter_autotrack_rectangle_init ); + MLT_REGISTER( mlt_service_producer_type, "slowmotion", producer_slowmotion_init ); - MLT_REGISTER_METADATA( filter_type, "motion_est", metadata, "filter_motion_est.yml" ); - MLT_REGISTER_METADATA( filter_type, "vismv", metadata, "filter_vismv.yml" ); - MLT_REGISTER_METADATA( filter_type, "crop_detect", metadata, "filter_crop_detect.yml" ); - MLT_REGISTER_METADATA( filter_type, "autotrack_rectangle", metadata, "filter_autotrack_rectangle.yml" ); - MLT_REGISTER_METADATA( producer_type, "slowmotion", metadata, "producer_slowmotion.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "motion_est", metadata, "filter_motion_est.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "vismv", metadata, "filter_vismv.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "crop_detect", metadata, "filter_crop_detect.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "autotrack_rectangle", metadata, "filter_autotrack_rectangle.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "slowmotion", metadata, "producer_slowmotion.yml" ); } diff --git a/src/modules/ndi/factory.c b/src/modules/ndi/factory.c index da63a50ba..e2b477970 100644 --- a/src/modules/ndi/factory.c +++ b/src/modules/ndi/factory.c @@ -110,9 +110,9 @@ static void *create_service( mlt_profile profile, mlt_service_type type, const c return NULL; } - if ( type == producer_type ) + if ( type == mlt_service_producer_type ) return producer_ndi_init( profile, type, id, (char*)arg ); - else if ( type == consumer_type ) + else if ( type == mlt_service_consumer_type ) return consumer_ndi_init( profile, type, id, (char*)arg ); return NULL; @@ -120,6 +120,6 @@ static void *create_service( mlt_profile profile, mlt_service_type type, const c MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "ndi", create_service ); - MLT_REGISTER( producer_type, "ndi", create_service ); + MLT_REGISTER( mlt_service_consumer_type, "ndi", create_service ); + MLT_REGISTER( mlt_service_producer_type, "ndi", create_service ); } diff --git a/src/modules/normalize/factory.c b/src/modules/normalize/factory.c index cd222de60..7bd19784d 100644 --- a/src/modules/normalize/factory.c +++ b/src/modules/normalize/factory.c @@ -33,8 +33,8 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "audiolevel", filter_audiolevel_init ); - MLT_REGISTER( filter_type, "volume", filter_volume_init ); - MLT_REGISTER_METADATA( filter_type, "audiolevel", metadata, "filter_audiolevel.yml" ); - MLT_REGISTER_METADATA( filter_type, "volume", metadata, "filter_volume.yml" ); + MLT_REGISTER( mlt_service_filter_type, "audiolevel", filter_audiolevel_init ); + MLT_REGISTER( mlt_service_filter_type, "volume", filter_volume_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "audiolevel", metadata, "filter_audiolevel.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "volume", metadata, "filter_volume.yml" ); } diff --git a/src/modules/oldfilm/factory.c b/src/modules/oldfilm/factory.c index f957c9d61..0e3d8d766 100644 --- a/src/modules/oldfilm/factory.c +++ b/src/modules/oldfilm/factory.c @@ -37,19 +37,19 @@ static mlt_properties oldfilm_metadata( mlt_service_type type, const char *id, v MLT_REPOSITORY { - MLT_REGISTER( filter_type, "oldfilm", filter_oldfilm_init ); - MLT_REGISTER( filter_type, "dust", filter_dust_init ); - MLT_REGISTER( filter_type, "lines", filter_lines_init ); - MLT_REGISTER( filter_type, "grain", filter_grain_init ); - MLT_REGISTER( filter_type, "tcolor", filter_tcolor_init ); - MLT_REGISTER( filter_type, "vignette", filter_vignette_init ); + MLT_REGISTER( mlt_service_filter_type, "oldfilm", filter_oldfilm_init ); + MLT_REGISTER( mlt_service_filter_type, "dust", filter_dust_init ); + MLT_REGISTER( mlt_service_filter_type, "lines", filter_lines_init ); + MLT_REGISTER( mlt_service_filter_type, "grain", filter_grain_init ); + MLT_REGISTER( mlt_service_filter_type, "tcolor", filter_tcolor_init ); + MLT_REGISTER( mlt_service_filter_type, "vignette", filter_vignette_init ); - MLT_REGISTER_METADATA( filter_type, "vignette", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "tcolor", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "grain", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "lines", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "dust", oldfilm_metadata, NULL ); - MLT_REGISTER_METADATA( filter_type, "oldfilm", oldfilm_metadata, NULL ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "vignette", oldfilm_metadata, NULL ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "tcolor", oldfilm_metadata, NULL ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "grain", oldfilm_metadata, NULL ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "lines", oldfilm_metadata, NULL ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "dust", oldfilm_metadata, NULL ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "oldfilm", oldfilm_metadata, NULL ); } diff --git a/src/modules/opencv/factory.c b/src/modules/opencv/factory.c index b3b0ccc30..2bfceed97 100644 --- a/src/modules/opencv/factory.c +++ b/src/modules/opencv/factory.c @@ -33,6 +33,6 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "opencv.tracker", filter_tracker_init ); - MLT_REGISTER_METADATA( filter_type, "opencv.tracker", metadata, "filter_opencv_tracker.yml" ); + MLT_REGISTER( mlt_service_filter_type, "opencv.tracker", filter_tracker_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "opencv.tracker", metadata, "filter_opencv_tracker.yml" ); } diff --git a/src/modules/opengl/factory.c b/src/modules/opengl/factory.c index d92ddb894..989c4f29a 100644 --- a/src/modules/opengl/factory.c +++ b/src/modules/opengl/factory.c @@ -55,42 +55,42 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { #if !defined(__APPLE__) && !defined(_WIN32) - MLT_REGISTER( consumer_type, "xgl", consumer_xgl_init ); + MLT_REGISTER( mlt_service_consumer_type, "xgl", consumer_xgl_init ); #endif - MLT_REGISTER( filter_type, "glsl.manager", filter_glsl_manager_init ); - MLT_REGISTER( filter_type, "movit.blur", filter_movit_blur_init ); - MLT_REGISTER( filter_type, "movit.convert", filter_movit_convert_init ); - MLT_REGISTER( filter_type, "movit.crop", filter_movit_crop_init ); - MLT_REGISTER( filter_type, "movit.diffusion", filter_movit_diffusion_init ); - MLT_REGISTER( filter_type, "movit.flip", filter_movit_flip_init ); - MLT_REGISTER( filter_type, "movit.glow", filter_movit_glow_init ); - MLT_REGISTER( filter_type, "movit.lift_gamma_gain", filter_lift_gamma_gain_init ); - MLT_REGISTER( filter_type, "movit.mirror", filter_movit_mirror_init ); - MLT_REGISTER( filter_type, "movit.opacity", filter_movit_opacity_init ); - MLT_REGISTER( filter_type, "movit.rect", filter_movit_rect_init ); - MLT_REGISTER( filter_type, "movit.resample", filter_movit_resample_init ); - MLT_REGISTER( filter_type, "movit.resize", filter_movit_resize_init ); - MLT_REGISTER( filter_type, "movit.saturation", filter_movit_saturation_init ); - MLT_REGISTER( filter_type, "movit.sharpen", filter_deconvolution_sharpen_init ); - MLT_REGISTER( filter_type, "movit.vignette", filter_movit_vignette_init ); - MLT_REGISTER( filter_type, "movit.white_balance", filter_white_balance_init ); - MLT_REGISTER( transition_type, "movit.luma_mix", transition_movit_luma_init ); - MLT_REGISTER( transition_type, "movit.mix", transition_movit_mix_init ); - MLT_REGISTER( transition_type, "movit.overlay", transition_movit_overlay_init ); + MLT_REGISTER( mlt_service_filter_type, "glsl.manager", filter_glsl_manager_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.blur", filter_movit_blur_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.convert", filter_movit_convert_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.crop", filter_movit_crop_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.diffusion", filter_movit_diffusion_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.flip", filter_movit_flip_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.glow", filter_movit_glow_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.lift_gamma_gain", filter_lift_gamma_gain_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.mirror", filter_movit_mirror_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.opacity", filter_movit_opacity_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.rect", filter_movit_rect_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.resample", filter_movit_resample_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.resize", filter_movit_resize_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.saturation", filter_movit_saturation_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.sharpen", filter_deconvolution_sharpen_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.vignette", filter_movit_vignette_init ); + MLT_REGISTER( mlt_service_filter_type, "movit.white_balance", filter_white_balance_init ); + MLT_REGISTER( mlt_service_transition_type, "movit.luma_mix", transition_movit_luma_init ); + MLT_REGISTER( mlt_service_transition_type, "movit.mix", transition_movit_mix_init ); + MLT_REGISTER( mlt_service_transition_type, "movit.overlay", transition_movit_overlay_init ); - MLT_REGISTER_METADATA( filter_type, "movit.blur", metadata, "filter_movit_blur.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.diffusion", metadata, "filter_movit_diffusion.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.flip", metadata, "filter_movit_flip.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.glow", metadata, "filter_movit_glow.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.lift_gamma_gain", metadata, "filter_movit_lift_gamma_gain.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.mirror", metadata, "filter_movit_mirror.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.opacity", metadata, "filter_movit_opacity.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.rect", metadata, "filter_movit_rect.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.saturation", metadata, "filter_movit_saturation.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.sharpen", metadata, "filter_movit_deconvolution_sharpen.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.vignette", metadata, "filter_movit_vignette.yml" ); - MLT_REGISTER_METADATA( filter_type, "movit.white_balance", metadata, "filter_movit_white_balance.yml" ); - MLT_REGISTER_METADATA( transition_type, "movit.luma_mix", metadata, "transition_movit_luma.yml" ); - MLT_REGISTER_METADATA( transition_type, "movit.mix", metadata, "transition_movit_mix.yml" ); - MLT_REGISTER_METADATA( transition_type, "movit.overlay", metadata, "transition_movit_overlay.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.blur", metadata, "filter_movit_blur.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.diffusion", metadata, "filter_movit_diffusion.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.flip", metadata, "filter_movit_flip.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.glow", metadata, "filter_movit_glow.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.lift_gamma_gain", metadata, "filter_movit_lift_gamma_gain.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.mirror", metadata, "filter_movit_mirror.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.opacity", metadata, "filter_movit_opacity.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.rect", metadata, "filter_movit_rect.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.saturation", metadata, "filter_movit_saturation.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.sharpen", metadata, "filter_movit_deconvolution_sharpen.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.vignette", metadata, "filter_movit_vignette.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "movit.white_balance", metadata, "filter_movit_white_balance.yml" ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "movit.luma_mix", metadata, "transition_movit_luma.yml" ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "movit.mix", metadata, "transition_movit_mix.yml" ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "movit.overlay", metadata, "transition_movit_overlay.yml" ); } diff --git a/src/modules/plus/factory.c b/src/modules/plus/factory.c index 26e4eafac..e383da075 100644 --- a/src/modules/plus/factory.c +++ b/src/modules/plus/factory.c @@ -56,53 +56,53 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "blipflash", consumer_blipflash_init ); - MLT_REGISTER( filter_type, "affine", filter_affine_init ); - MLT_REGISTER( filter_type, "charcoal", filter_charcoal_init ); - MLT_REGISTER( filter_type, "dynamictext", filter_dynamictext_init ); - MLT_REGISTER( filter_type, "dynamic_loudness", filter_dynamic_loudness_init ); - MLT_REGISTER( filter_type, "invert", filter_invert_init ); - MLT_REGISTER( filter_type, "lift_gamma_gain", filter_lift_gamma_gain_init ); - MLT_REGISTER( filter_type, "loudness", filter_loudness_init ); - MLT_REGISTER( filter_type, "loudness_meter", filter_loudness_meter_init ); - MLT_REGISTER( filter_type, "lumakey", filter_lumakey_init ); - MLT_REGISTER( filter_type, "pillar_echo", filter_pillar_echo_init ); - MLT_REGISTER( filter_type, "rgblut", filter_rgblut_init ); - MLT_REGISTER( filter_type, "sepia", filter_sepia_init ); - MLT_REGISTER( filter_type, "spot_remover", filter_spot_remover_init ); - MLT_REGISTER( filter_type, "text", filter_text_init ); - MLT_REGISTER( filter_type, "timer", filter_timer_init ); - MLT_REGISTER( filter_type, "strobe", filter_strobe_init ); - MLT_REGISTER( producer_type, "blipflash", producer_blipflash_init ); - MLT_REGISTER( producer_type, "count", producer_count_init ); - MLT_REGISTER( transition_type, "affine", transition_affine_init ); + MLT_REGISTER( mlt_service_consumer_type, "blipflash", consumer_blipflash_init ); + MLT_REGISTER( mlt_service_filter_type, "affine", filter_affine_init ); + MLT_REGISTER( mlt_service_filter_type, "charcoal", filter_charcoal_init ); + MLT_REGISTER( mlt_service_filter_type, "dynamictext", filter_dynamictext_init ); + MLT_REGISTER( mlt_service_filter_type, "dynamic_loudness", filter_dynamic_loudness_init ); + MLT_REGISTER( mlt_service_filter_type, "invert", filter_invert_init ); + MLT_REGISTER( mlt_service_filter_type, "lift_gamma_gain", filter_lift_gamma_gain_init ); + MLT_REGISTER( mlt_service_filter_type, "loudness", filter_loudness_init ); + MLT_REGISTER( mlt_service_filter_type, "loudness_meter", filter_loudness_meter_init ); + MLT_REGISTER( mlt_service_filter_type, "lumakey", filter_lumakey_init ); + MLT_REGISTER( mlt_service_filter_type, "pillar_echo", filter_pillar_echo_init ); + MLT_REGISTER( mlt_service_filter_type, "rgblut", filter_rgblut_init ); + MLT_REGISTER( mlt_service_filter_type, "sepia", filter_sepia_init ); + MLT_REGISTER( mlt_service_filter_type, "spot_remover", filter_spot_remover_init ); + MLT_REGISTER( mlt_service_filter_type, "text", filter_text_init ); + MLT_REGISTER( mlt_service_filter_type, "timer", filter_timer_init ); + MLT_REGISTER( mlt_service_filter_type, "strobe", filter_strobe_init ); + MLT_REGISTER( mlt_service_producer_type, "blipflash", producer_blipflash_init ); + MLT_REGISTER( mlt_service_producer_type, "count", producer_count_init ); + MLT_REGISTER( mlt_service_transition_type, "affine", transition_affine_init ); #ifdef USE_FFTW - MLT_REGISTER( filter_type, "dance", filter_dance_init ); - MLT_REGISTER( filter_type, "fft", filter_fft_init ); + MLT_REGISTER( mlt_service_filter_type, "dance", filter_dance_init ); + MLT_REGISTER( mlt_service_filter_type, "fft", filter_fft_init ); #endif - MLT_REGISTER_METADATA( consumer_type, "blipflash", metadata, "consumer_blipflash.yml" ); - MLT_REGISTER_METADATA( filter_type, "affine", metadata, "filter_affine.yml" ); - MLT_REGISTER_METADATA( filter_type, "charcoal", metadata, "filter_charcoal.yml" ); - MLT_REGISTER_METADATA( filter_type, "dynamictext", metadata, "filter_dynamictext.yml" ); - MLT_REGISTER_METADATA( filter_type, "dynamic_loudness", metadata, "filter_dynamic_loudness.yml" ); - MLT_REGISTER_METADATA( filter_type, "invert", metadata, "filter_invert.yml" ); - MLT_REGISTER_METADATA( filter_type, "lift_gamma_gain", metadata, "filter_lift_gamma_gain.yml" ); - MLT_REGISTER_METADATA( filter_type, "loudness", metadata, "filter_loudness.yml" ); - MLT_REGISTER_METADATA( filter_type, "loudness_meter", metadata, "filter_loudness_meter.yml" ); - MLT_REGISTER_METADATA( filter_type, "lumakey", metadata, "filter_lumakey.yml" ); - MLT_REGISTER_METADATA( filter_type, "pillar_echo", metadata, "filter_pillar_echo.yml" ); - MLT_REGISTER_METADATA( filter_type, "rgblut", metadata, "filter_rgblut.yml" ); - MLT_REGISTER_METADATA( filter_type, "sepia", metadata, "filter_sepia.yml" ); - MLT_REGISTER_METADATA( filter_type, "spot_remover", metadata, "filter_spot_remover.yml" ); - MLT_REGISTER_METADATA( filter_type, "text", metadata, "filter_text.yml" ); - MLT_REGISTER_METADATA( filter_type, "timer", metadata, "filter_timer.yml" ); - MLT_REGISTER_METADATA( filter_type, "strobe", metadata, "filter_strobe.yml" ); - MLT_REGISTER_METADATA( producer_type, "blipflash", metadata, "producer_blipflash.yml" ); - MLT_REGISTER_METADATA( producer_type, "count", metadata, "producer_count.yml" ); - MLT_REGISTER_METADATA( transition_type, "affine", metadata, "transition_affine.yml" ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "blipflash", metadata, "consumer_blipflash.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "affine", metadata, "filter_affine.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "charcoal", metadata, "filter_charcoal.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "dynamictext", metadata, "filter_dynamictext.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "dynamic_loudness", metadata, "filter_dynamic_loudness.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "invert", metadata, "filter_invert.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "lift_gamma_gain", metadata, "filter_lift_gamma_gain.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "loudness", metadata, "filter_loudness.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "loudness_meter", metadata, "filter_loudness_meter.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "lumakey", metadata, "filter_lumakey.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "pillar_echo", metadata, "filter_pillar_echo.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "rgblut", metadata, "filter_rgblut.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "sepia", metadata, "filter_sepia.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "spot_remover", metadata, "filter_spot_remover.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "text", metadata, "filter_text.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "timer", metadata, "filter_timer.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "strobe", metadata, "filter_strobe.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "blipflash", metadata, "producer_blipflash.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "count", metadata, "producer_count.yml" ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "affine", metadata, "transition_affine.yml" ); #ifdef USE_FFTW - MLT_REGISTER_METADATA( filter_type, "dance", metadata, "filter_dance.yml" ); - MLT_REGISTER_METADATA( filter_type, "fft", metadata, "filter_fft.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "dance", metadata, "filter_dance.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "fft", metadata, "filter_fft.yml" ); #endif } diff --git a/src/modules/plusgpl/factory.c b/src/modules/plusgpl/factory.c index d6a5efbed..aa2fbc82c 100644 --- a/src/modules/plusgpl/factory.c +++ b/src/modules/plusgpl/factory.c @@ -36,16 +36,16 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "cbrts", consumer_cbrts_init ); - MLT_REGISTER( filter_type, "BurningTV", filter_burn_init ); - MLT_REGISTER( filter_type, "burningtv", filter_burn_init ); - MLT_REGISTER( filter_type, "lumaliftgaingamma", filter_lumaliftgaingamma_init ); - MLT_REGISTER( filter_type, "rotoscoping", filter_rotoscoping_init ); - MLT_REGISTER( filter_type, "telecide", filter_telecide_init ); + MLT_REGISTER( mlt_service_consumer_type, "cbrts", consumer_cbrts_init ); + MLT_REGISTER( mlt_service_filter_type, "BurningTV", filter_burn_init ); + MLT_REGISTER( mlt_service_filter_type, "burningtv", filter_burn_init ); + MLT_REGISTER( mlt_service_filter_type, "lumaliftgaingamma", filter_lumaliftgaingamma_init ); + MLT_REGISTER( mlt_service_filter_type, "rotoscoping", filter_rotoscoping_init ); + MLT_REGISTER( mlt_service_filter_type, "telecide", filter_telecide_init ); - MLT_REGISTER_METADATA( consumer_type, "cbrts", metadata, "consumer_cbrts.yml" ); - MLT_REGISTER_METADATA( filter_type, "BurningTV", metadata, "filter_burningtv.yml" ); - MLT_REGISTER_METADATA( filter_type, "burningtv", metadata, "filter_burningtv.yml" ); - MLT_REGISTER_METADATA( filter_type, "lumaliftgaingamma", metadata, "filter_lumaliftgaingamma.yml" ); - MLT_REGISTER_METADATA( filter_type, "rotoscoping", metadata, "filter_rotoscoping.yml" ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "cbrts", metadata, "consumer_cbrts.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "BurningTV", metadata, "filter_burningtv.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "burningtv", metadata, "filter_burningtv.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "lumaliftgaingamma", metadata, "filter_lumaliftgaingamma.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "rotoscoping", metadata, "filter_rotoscoping.yml" ); } diff --git a/src/modules/qt/factory.c b/src/modules/qt/factory.c index f3f4b61fb..ddb9ef831 100644 --- a/src/modules/qt/factory.c +++ b/src/modules/qt/factory.c @@ -51,36 +51,36 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { #ifdef USE_QT_OPENGL - MLT_REGISTER( consumer_type, "qglsl", consumer_qglsl_init ); + MLT_REGISTER( mlt_service_consumer_type, "qglsl", consumer_qglsl_init ); #endif - MLT_REGISTER( filter_type, "audiowaveform", filter_audiowaveform_init ); - MLT_REGISTER( filter_type, "qtext", filter_qtext_init ); - MLT_REGISTER( producer_type, "qimage", producer_qimage_init ); - MLT_REGISTER( producer_type, "qtext", producer_qtext_init ); - MLT_REGISTER( producer_type, "kdenlivetitle", producer_kdenlivetitle_init ); - MLT_REGISTER( transition_type, "qtblend", transition_qtblend_init ); - MLT_REGISTER( filter_type, "qtblend", filter_qtblend_init ); - MLT_REGISTER( filter_type, "qtcrop", filter_qtcrop_init ); - MLT_REGISTER( filter_type, "typewriter", filter_typewriter_init ); - MLT_REGISTER_METADATA( transition_type, "qtblend", metadata, "transition_qtblend.yml" ); - MLT_REGISTER_METADATA( filter_type, "qtblend", metadata, "filter_qtblend.yml" ); - MLT_REGISTER_METADATA( filter_type, "qtcrop", metadata, "filter_qtcrop.yml" ); + MLT_REGISTER( mlt_service_filter_type, "audiowaveform", filter_audiowaveform_init ); + MLT_REGISTER( mlt_service_filter_type, "qtext", filter_qtext_init ); + MLT_REGISTER( mlt_service_producer_type, "qimage", producer_qimage_init ); + MLT_REGISTER( mlt_service_producer_type, "qtext", producer_qtext_init ); + MLT_REGISTER( mlt_service_producer_type, "kdenlivetitle", producer_kdenlivetitle_init ); + MLT_REGISTER( mlt_service_transition_type, "qtblend", transition_qtblend_init ); + MLT_REGISTER( mlt_service_filter_type, "qtblend", filter_qtblend_init ); + MLT_REGISTER( mlt_service_filter_type, "qtcrop", filter_qtcrop_init ); + MLT_REGISTER( mlt_service_filter_type, "typewriter", filter_typewriter_init ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "qtblend", metadata, "transition_qtblend.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "qtblend", metadata, "filter_qtblend.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "qtcrop", metadata, "filter_qtcrop.yml" ); #ifdef USE_FFTW - MLT_REGISTER( filter_type, "audiospectrum", filter_audiospectrum_init ); - MLT_REGISTER( filter_type, "lightshow", filter_lightshow_init ); + MLT_REGISTER( mlt_service_filter_type, "audiospectrum", filter_audiospectrum_init ); + MLT_REGISTER( mlt_service_filter_type, "lightshow", filter_lightshow_init ); #endif - MLT_REGISTER_METADATA( filter_type, "audiowaveform", metadata, "filter_audiowaveform.yml" ); - MLT_REGISTER_METADATA( filter_type, "qtext", metadata, "filter_qtext.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "audiowaveform", metadata, "filter_audiowaveform.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "qtext", metadata, "filter_qtext.yml" ); #ifdef USE_FFTW - MLT_REGISTER_METADATA( filter_type, "lightshow", metadata, "filter_lightshow.yml" ); - MLT_REGISTER_METADATA( filter_type, "audiospectrum", metadata, "filter_audiospectrum.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "lightshow", metadata, "filter_lightshow.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "audiospectrum", metadata, "filter_audiospectrum.yml" ); #endif - MLT_REGISTER_METADATA( producer_type, "qimage", metadata, "producer_qimage.yml" ); - MLT_REGISTER_METADATA( producer_type, "qtext", metadata, "producer_qtext.yml" ); - MLT_REGISTER_METADATA( producer_type, "kdenlivetitle", metadata, "producer_kdenlivetitle.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "qimage", metadata, "producer_qimage.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "qtext", metadata, "producer_qtext.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "kdenlivetitle", metadata, "producer_kdenlivetitle.yml" ); #ifdef GPL3 - MLT_REGISTER( transition_type, "vqm", transition_vqm_init ); - MLT_REGISTER_METADATA( transition_type, "vqm", metadata, "transition_vqm.yml" ); + MLT_REGISTER( mlt_service_transition_type, "vqm", transition_vqm_init ); + MLT_REGISTER_METADATA( mlt_service_transition_type, "vqm", metadata, "transition_vqm.yml" ); #endif - MLT_REGISTER_METADATA( filter_type, "typewriter", metadata, "filter_typewriter.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "typewriter", metadata, "filter_typewriter.yml" ); } diff --git a/src/modules/resample/factory.c b/src/modules/resample/factory.c index da91a3e96..1499058d2 100644 --- a/src/modules/resample/factory.c +++ b/src/modules/resample/factory.c @@ -32,7 +32,7 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "resample", filter_resample_init ); + MLT_REGISTER( mlt_service_filter_type, "resample", filter_resample_init ); - MLT_REGISTER_METADATA( filter_type, "resample", metadata, "filter_resample.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "resample", metadata, "filter_resample.yml" ); } diff --git a/src/modules/rtaudio/consumer_rtaudio.cpp b/src/modules/rtaudio/consumer_rtaudio.cpp index fa31b55b0..722362383 100644 --- a/src/modules/rtaudio/consumer_rtaudio.cpp +++ b/src/modules/rtaudio/consumer_rtaudio.cpp @@ -885,8 +885,8 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "rtaudio", consumer_rtaudio_init ); - MLT_REGISTER_METADATA( consumer_type, "rtaudio", metadata, NULL ); + MLT_REGISTER( mlt_service_consumer_type, "rtaudio", consumer_rtaudio_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "rtaudio", metadata, NULL ); } } // extern C diff --git a/src/modules/rubberband/factory.c b/src/modules/rubberband/factory.c index 8df80d895..508201413 100644 --- a/src/modules/rubberband/factory.c +++ b/src/modules/rubberband/factory.c @@ -32,6 +32,6 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "rbpitch", filter_rbpitch_init ); - MLT_REGISTER_METADATA( filter_type, "rbpitch", metadata, "filter_rbpitch.yml" ); + MLT_REGISTER( mlt_service_filter_type, "rbpitch", filter_rbpitch_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "rbpitch", metadata, "filter_rbpitch.yml" ); } diff --git a/src/modules/sdl/factory.c b/src/modules/sdl/factory.c index b27fcfc48..6fe2d43c2 100644 --- a/src/modules/sdl/factory.c +++ b/src/modules/sdl/factory.c @@ -40,17 +40,17 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "sdl", consumer_sdl_init ); - MLT_REGISTER_METADATA( consumer_type, "sdl", metadata, "consumer_sdl.yml" ); - MLT_REGISTER( consumer_type, "sdl_audio", consumer_sdl_audio_init ); - MLT_REGISTER_METADATA( consumer_type, "sdl_audio", metadata, "consumer_sdl_audio.yml" ); + MLT_REGISTER( mlt_service_consumer_type, "sdl", consumer_sdl_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdl", metadata, "consumer_sdl.yml" ); + MLT_REGISTER( mlt_service_consumer_type, "sdl_audio", consumer_sdl_audio_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdl_audio", metadata, "consumer_sdl_audio.yml" ); - MLT_REGISTER( consumer_type, "sdl_preview", consumer_sdl_preview_init ); - MLT_REGISTER_METADATA( consumer_type, "sdl_preview", metadata, "consumer_sdl_preview.yml" ); - MLT_REGISTER( consumer_type, "sdl_still", consumer_sdl_still_init ); - MLT_REGISTER_METADATA( consumer_type, "sdl_still", metadata, "consumer_sdl_still.yml" ); + MLT_REGISTER( mlt_service_consumer_type, "sdl_preview", consumer_sdl_preview_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdl_preview", metadata, "consumer_sdl_preview.yml" ); + MLT_REGISTER( mlt_service_consumer_type, "sdl_still", consumer_sdl_still_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdl_still", metadata, "consumer_sdl_still.yml" ); #ifdef WITH_SDL_IMAGE - MLT_REGISTER( producer_type, "sdl_image", producer_sdl_image_init ); - MLT_REGISTER_METADATA( producer_type, "sdl_image", metadata, "consumer_sdl_image.yml" ); + MLT_REGISTER( mlt_service_producer_type, "sdl_image", producer_sdl_image_init ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "sdl_image", metadata, "consumer_sdl_image.yml" ); #endif } diff --git a/src/modules/sdl2/factory.c b/src/modules/sdl2/factory.c index d357e68ce..e07a789d7 100644 --- a/src/modules/sdl2/factory.c +++ b/src/modules/sdl2/factory.c @@ -34,8 +34,8 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "sdl2", consumer_sdl2_init ); - MLT_REGISTER_METADATA( consumer_type, "sdl2", metadata, "consumer_sdl2.yml" ); - MLT_REGISTER( consumer_type, "sdl2_audio", consumer_sdl2_audio_init ); - MLT_REGISTER_METADATA( consumer_type, "sdl2_audio", metadata, "consumer_sdl_audio.yml" ); + MLT_REGISTER( mlt_service_consumer_type, "sdl2", consumer_sdl2_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdl2", metadata, "consumer_sdl2.yml" ); + MLT_REGISTER( mlt_service_consumer_type, "sdl2_audio", consumer_sdl2_audio_init ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdl2_audio", metadata, "consumer_sdl_audio.yml" ); } diff --git a/src/modules/sox/factory.c b/src/modules/sox/factory.c index 8776ac162..297f362cb 100644 --- a/src/modules/sox/factory.c +++ b/src/modules/sox/factory.c @@ -37,7 +37,7 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat result = mlt_properties_parse_yaml( file ); #ifdef SOX14 - if ( result && ( type == filter_type ) && strcmp( id, "sox" ) ) + if ( result && ( type == mlt_service_filter_type ) && strcmp( id, "sox" ) ) { // Annotate the yaml properties with sox effect usage. mlt_properties params = mlt_properties_get_data( result, "parameters", NULL ); @@ -67,8 +67,8 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "sox", filter_sox_init ); - MLT_REGISTER_METADATA( filter_type, "sox", metadata, NULL ); + MLT_REGISTER( mlt_service_filter_type, "sox", filter_sox_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "sox", metadata, NULL ); #ifdef SOX14 int i; const sox_effect_handler_t *e; @@ -83,8 +83,8 @@ MLT_REPOSITORY ) { strcpy( name + 4, e->name ); - MLT_REGISTER( filter_type, name, filter_sox_init ); - MLT_REGISTER_METADATA( filter_type, name, metadata, NULL ); + MLT_REGISTER( mlt_service_filter_type, name, filter_sox_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, name, metadata, NULL ); } } #endif diff --git a/src/modules/swfdec/producer_swfdec.c b/src/modules/swfdec/producer_swfdec.c index da13acf4b..877dc4555 100644 --- a/src/modules/swfdec/producer_swfdec.c +++ b/src/modules/swfdec/producer_swfdec.c @@ -278,6 +278,6 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { swfdec_init(); - MLT_REGISTER( producer_type, "swfdec", producer_swfdec_init ); - MLT_REGISTER_METADATA( producer_type, "swfdec", metadata, "producer_swfdec.yml" ); + MLT_REGISTER( mlt_service_producer_type, "swfdec", producer_swfdec_init ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "swfdec", metadata, "producer_swfdec.yml" ); } diff --git a/src/modules/vid.stab/factory.c b/src/modules/vid.stab/factory.c index 0f54f239f..193aca2f8 100644 --- a/src/modules/vid.stab/factory.c +++ b/src/modules/vid.stab/factory.c @@ -33,9 +33,9 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "deshake", filter_deshake_init ); - MLT_REGISTER( filter_type, "vidstab", filter_vidstab_init ); + MLT_REGISTER( mlt_service_filter_type, "deshake", filter_deshake_init ); + MLT_REGISTER( mlt_service_filter_type, "vidstab", filter_vidstab_init ); - MLT_REGISTER_METADATA( filter_type, "deshake", metadata, "filter_deshake.yml" ); - MLT_REGISTER_METADATA( filter_type, "vidstab", metadata, "filter_vidstab.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "deshake", metadata, "filter_deshake.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "vidstab", metadata, "filter_vidstab.yml" ); } diff --git a/src/modules/videostab/factory.c b/src/modules/videostab/factory.c index cacffa69f..6cd47c7c5 100644 --- a/src/modules/videostab/factory.c +++ b/src/modules/videostab/factory.c @@ -33,10 +33,10 @@ static mlt_properties videostab_metadata( mlt_service_type type, const char *id, MLT_REPOSITORY { - MLT_REGISTER( filter_type, "videostab", filter_videostab_init ); - MLT_REGISTER_METADATA( filter_type, "videostab", videostab_metadata, NULL ); - MLT_REGISTER( filter_type, "videostab2", filter_videostab2_init ); - MLT_REGISTER_METADATA( filter_type, "videostab2", videostab_metadata, NULL ); + MLT_REGISTER( mlt_service_filter_type, "videostab", filter_videostab_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "videostab", videostab_metadata, NULL ); + MLT_REGISTER( mlt_service_filter_type, "videostab2", filter_videostab2_init ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "videostab2", videostab_metadata, NULL ); } diff --git a/src/modules/vmfx/factory.c b/src/modules/vmfx/factory.c index b10ef582b..5b8b30f16 100644 --- a/src/modules/vmfx/factory.c +++ b/src/modules/vmfx/factory.c @@ -37,15 +37,15 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( filter_type, "chroma", filter_chroma_init ); - MLT_REGISTER( filter_type, "chroma_hold", filter_chroma_hold_init ); - MLT_REGISTER( filter_type, "threshold", filter_mono_init ); - MLT_REGISTER( filter_type, "shape", filter_shape_init ); - MLT_REGISTER( producer_type, "pgm", producer_pgm_init ); + MLT_REGISTER( mlt_service_filter_type, "chroma", filter_chroma_init ); + MLT_REGISTER( mlt_service_filter_type, "chroma_hold", filter_chroma_hold_init ); + MLT_REGISTER( mlt_service_filter_type, "threshold", filter_mono_init ); + MLT_REGISTER( mlt_service_filter_type, "shape", filter_shape_init ); + MLT_REGISTER( mlt_service_producer_type, "pgm", producer_pgm_init ); - MLT_REGISTER_METADATA( filter_type, "chroma", metadata, "filter_chroma.yml" ); - MLT_REGISTER_METADATA( filter_type, "chroma_hold", metadata, "filter_chroma_hold.yml" ); - MLT_REGISTER_METADATA( filter_type, "threshold", metadata, "filter_mono.yml" ); - MLT_REGISTER_METADATA( filter_type, "shape", metadata, "filter_shape.yml" ); - MLT_REGISTER_METADATA( producer_type, "pgm", metadata, "producer_pgm.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "chroma", metadata, "filter_chroma.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "chroma_hold", metadata, "filter_chroma_hold.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "threshold", metadata, "filter_mono.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "shape", metadata, "filter_shape.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "pgm", metadata, "producer_pgm.yml" ); } diff --git a/src/modules/vorbis/factory.c b/src/modules/vorbis/factory.c index 112d66b95..eb90a87db 100644 --- a/src/modules/vorbis/factory.c +++ b/src/modules/vorbis/factory.c @@ -32,6 +32,6 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( producer_type, "vorbis", producer_vorbis_init ); - MLT_REGISTER_METADATA( producer_type, "vorbis", metadata, "producer_vorbis.yml" ); + MLT_REGISTER( mlt_service_producer_type, "vorbis", producer_vorbis_init ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "vorbis", metadata, "producer_vorbis.yml" ); } diff --git a/src/modules/xine/factory.c b/src/modules/xine/factory.c index 12e661a1c..4571f397b 100644 --- a/src/modules/xine/factory.c +++ b/src/modules/xine/factory.c @@ -24,5 +24,5 @@ extern mlt_filter filter_deinterlace_init( mlt_profile profile, mlt_service_type MLT_REPOSITORY { - MLT_REGISTER( filter_type, "deinterlace", filter_deinterlace_init ); + MLT_REGISTER( mlt_service_filter_type, "deinterlace", filter_deinterlace_init ); } diff --git a/src/modules/xml/consumer_xml.c b/src/modules/xml/consumer_xml.c index a9fadfaac..5812fe0a7 100644 --- a/src/modules/xml/consumer_xml.c +++ b/src/modules/xml/consumer_xml.c @@ -743,7 +743,7 @@ static void serialise_service( serialise_context context, mlt_service service, x } // Treat it as a normal chain - else if ( mlt_properties_get_int( properties, "_original_type" ) == chain_type ) + else if ( mlt_properties_get_int( properties, "_original_type" ) == mlt_service_chain_type ) { serialise_chain( context, service, node ); mlt_properties_set( properties, "mlt_type", "chain" ); diff --git a/src/modules/xml/factory.c b/src/modules/xml/factory.c index 03d379654..ac07441b2 100644 --- a/src/modules/xml/factory.c +++ b/src/modules/xml/factory.c @@ -33,13 +33,13 @@ static mlt_properties metadata( mlt_service_type type, const char *id, void *dat MLT_REPOSITORY { - MLT_REGISTER( consumer_type, "xml", consumer_xml_init ); - MLT_REGISTER( producer_type, "xml", producer_xml_init ); - MLT_REGISTER( producer_type, "xml-string", producer_xml_init ); - MLT_REGISTER( producer_type, "xml-nogl", producer_xml_init ); + MLT_REGISTER( mlt_service_consumer_type, "xml", consumer_xml_init ); + MLT_REGISTER( mlt_service_producer_type, "xml", producer_xml_init ); + MLT_REGISTER( mlt_service_producer_type, "xml-string", producer_xml_init ); + MLT_REGISTER( mlt_service_producer_type, "xml-nogl", producer_xml_init ); - MLT_REGISTER_METADATA( consumer_type, "xml", metadata, "consumer_xml.yml" ); - MLT_REGISTER_METADATA( producer_type, "xml", metadata, "producer_xml.yml" ); - MLT_REGISTER_METADATA( producer_type, "xml-string", metadata, "producer_xml-string.yml" ); - MLT_REGISTER_METADATA( producer_type, "xml-nogl", metadata, "producer_xml-nogl.yml" ); + MLT_REGISTER_METADATA( mlt_service_consumer_type, "xml", metadata, "consumer_xml.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "xml", metadata, "producer_xml.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "xml-string", metadata, "producer_xml-string.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "xml-nogl", metadata, "producer_xml-nogl.yml" ); } diff --git a/src/modules/xml/producer_xml.c b/src/modules/xml/producer_xml.c index 3283aad8b..dd605924f 100644 --- a/src/modules/xml/producer_xml.c +++ b/src/modules/xml/producer_xml.c @@ -2200,9 +2200,9 @@ mlt_producer producer_xml_init( mlt_profile profile, mlt_service_type servtype, { // Now assign additional properties if ( is_filename && ( - mlt_service_identify( service ) == tractor_type || - mlt_service_identify( service ) == playlist_type || - mlt_service_identify( service ) == multitrack_type ) ) + mlt_service_identify( service ) == mlt_service_tractor_type || + mlt_service_identify( service ) == mlt_service_playlist_type || + mlt_service_identify( service ) == mlt_service_multitrack_type ) ) { mlt_properties_set_int( properties, "_original_type", mlt_service_identify( service ) ); diff --git a/src/tests/test_service/test_service.cpp b/src/tests/test_service/test_service.cpp index 38cc9e0cc..969b000be 100644 --- a/src/tests/test_service/test_service.cpp +++ b/src/tests/test_service/test_service.cpp @@ -40,13 +40,13 @@ private Q_SLOTS: { Profile profile; Producer producer(profile, "color"); - QCOMPARE(mlt_service_identify(producer.get_service()), producer_type); + QCOMPARE(mlt_service_identify(producer.get_service()), mlt_service_producer_type); Filter filter(profile, "resize"); - QCOMPARE(mlt_service_identify(filter.get_service()), filter_type); + QCOMPARE(mlt_service_identify(filter.get_service()), mlt_service_filter_type); Transition transition(profile, "mix"); - QCOMPARE(mlt_service_identify(transition.get_service()), transition_type); + QCOMPARE(mlt_service_identify(transition.get_service()), mlt_service_transition_type); Consumer consumer(profile, "null"); - QCOMPARE(mlt_service_identify(consumer.get_service()), consumer_type); + QCOMPARE(mlt_service_identify(consumer.get_service()), mlt_service_consumer_type); } void CanIdentifyServicesFromAPI() @@ -54,19 +54,19 @@ private Q_SLOTS: mlt_profile profile = mlt_profile_init(NULL); mlt_playlist playlist = mlt_playlist_new(profile); - QCOMPARE(mlt_service_identify(MLT_PLAYLIST_SERVICE(playlist)), playlist_type); + QCOMPARE(mlt_service_identify(MLT_PLAYLIST_SERVICE(playlist)), mlt_service_playlist_type); mlt_tractor tractor = mlt_tractor_new(); - QCOMPARE(mlt_service_identify(MLT_TRACTOR_SERVICE(tractor)), tractor_type); - QCOMPARE(mlt_service_identify(MLT_MULTITRACK_SERVICE(mlt_tractor_multitrack(tractor))), multitrack_type); + QCOMPARE(mlt_service_identify(MLT_TRACTOR_SERVICE(tractor)), mlt_service_tractor_type); + QCOMPARE(mlt_service_identify(MLT_MULTITRACK_SERVICE(mlt_tractor_multitrack(tractor))), mlt_service_multitrack_type); mlt_producer producer = mlt_producer_new(profile); - QCOMPARE(mlt_service_identify(MLT_PRODUCER_SERVICE(producer)), producer_type); + QCOMPARE(mlt_service_identify(MLT_PRODUCER_SERVICE(producer)), mlt_service_producer_type); mlt_filter filter = mlt_filter_new(); - QCOMPARE(mlt_service_identify(MLT_FILTER_SERVICE(filter)), filter_type); + QCOMPARE(mlt_service_identify(MLT_FILTER_SERVICE(filter)), mlt_service_filter_type); mlt_transition transition = mlt_transition_new(); - QCOMPARE(mlt_service_identify(MLT_TRANSITION_SERVICE(transition)), transition_type); + QCOMPARE(mlt_service_identify(MLT_TRANSITION_SERVICE(transition)), mlt_service_transition_type); mlt_consumer consumer = mlt_consumer_new(profile); - QCOMPARE(mlt_service_identify(MLT_CONSUMER_SERVICE(consumer)), consumer_type); + QCOMPARE(mlt_service_identify(MLT_CONSUMER_SERVICE(consumer)), mlt_service_consumer_type); } private: From 614370400707edfbdd730870770361ac4188c6fa Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Thu, 17 Dec 2020 20:51:45 -0600 Subject: [PATCH 011/122] Reflect the source seekable flag in the chain --- src/framework/mlt_chain.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/framework/mlt_chain.c b/src/framework/mlt_chain.c index 54641351b..c5381241d 100644 --- a/src/framework/mlt_chain.c +++ b/src/framework/mlt_chain.c @@ -156,6 +156,7 @@ void mlt_chain_set_source( mlt_chain self, mlt_producer source ) if ( mlt_properties_get_int( base->source_parameters, name ) || !strcmp( name, "mlt_service" ) || !strcmp( name, "_mlt_service_hidden" ) || + !strcmp( name, "seekable" ) || !strncmp( name, "meta.", 5 ) ) { mlt_properties_pass_property( MLT_CHAIN_PROPERTIES(self), source_properties, name ); From 238a064d8d9219a53605a6e551a202c36c136943 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 19 Dec 2020 10:26:18 -0600 Subject: [PATCH 012/122] Add has_b_frames property to avformat producer This can be used to determine if the file is good to use time remap --- src/modules/avformat/producer_avformat.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index e06d48e6b..b785e5fc3 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -2351,6 +2351,8 @@ static int video_codec_init( producer_avformat self, int index, mlt_properties p break; } + mlt_properties_set_int( properties, "meta.media.has_b_frames", self->video_codec->has_b_frames ); + self->full_luma = 0; mlt_log_debug( MLT_PRODUCER_SERVICE(self->parent), "color_range %d\n", codec_context->color_range ); if ( codec_context->color_range == AVCOL_RANGE_JPEG ) From 38b3b01f48c5998a6c33145fc07e7e11fbfb738f Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 19 Dec 2020 16:46:02 -0600 Subject: [PATCH 013/122] Add chain and link to Mlt::Parser class --- src/framework/mlt_parser.h | 2 +- src/mlt++/MltParser.cpp | 58 ++++++++++++++++++++++++++++++++++++++ src/mlt++/MltParser.h | 4 +++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/framework/mlt_parser.h b/src/framework/mlt_parser.h index 54613d8c9..ab90a52cd 100644 --- a/src/framework/mlt_parser.h +++ b/src/framework/mlt_parser.h @@ -51,7 +51,7 @@ struct mlt_parser_s int ( *on_end_transition )( mlt_parser self, mlt_transition object ); int ( *on_start_chain )( mlt_parser self, mlt_chain object ); int ( *on_end_chain )( mlt_parser self, mlt_chain object ); - int ( *on_start_link )( mlt_parser self, mlt_producer object ); + int ( *on_start_link )( mlt_parser self, mlt_link object ); int ( *on_end_link )( mlt_parser self, mlt_link object ); }; diff --git a/src/mlt++/MltParser.cpp b/src/mlt++/MltParser.cpp index 34006c46b..d8f7f869f 100644 --- a/src/mlt++/MltParser.cpp +++ b/src/mlt++/MltParser.cpp @@ -147,6 +147,38 @@ static int on_end_transition_cb( mlt_parser self, mlt_transition object ) return parser->on_end_transition( &transition ); } +static int on_start_chain_cb( mlt_parser self, mlt_chain object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Chain chain( object ); + return parser->on_start_chain( &chain ); +} + +static int on_end_chain_cb( mlt_parser self, mlt_chain object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Chain chain( object ); + return parser->on_end_chain( &chain ); +} + +static int on_start_link_cb( mlt_parser self, mlt_link object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Link link( object ); + return parser->on_start_link( &link ); +} + +static int on_end_link_cb( mlt_parser self, mlt_link object ) +{ + mlt_properties properties = mlt_parser_properties( self ); + Parser *parser = ( Parser * )mlt_properties_get_data( properties, "_parser_object", NULL ); + Link link( object ); + return parser->on_end_link( &link ); +} + Parser::Parser( ) : Properties( false ) { @@ -168,6 +200,10 @@ Parser::Parser( ) : parser->on_end_filter = on_end_filter_cb; parser->on_start_transition = on_start_transition_cb; parser->on_end_transition = on_end_transition_cb; + parser->on_start_chain = on_start_chain_cb; + parser->on_end_chain = on_end_chain_cb; + parser->on_start_link = on_start_link_cb; + parser->on_end_link = on_end_link_cb; } Parser::~Parser( ) @@ -281,4 +317,26 @@ int Parser::on_end_transition( Transition *object ) return 0; } +int Parser::on_start_chain( Chain *object ) +{ + object->debug( "on_start_chain" ); + return 0; +} +int Parser::on_end_chain( Chain *object ) +{ + object->debug( "on_end_chain" ); + return 0; +} + +int Parser::on_start_link( Link *object ) +{ + object->debug( "on_start_link" ); + return 0; +} + +int Parser::on_end_link( Link *object ) +{ + object->debug( "on_end_link" ); + return 0; +} diff --git a/src/mlt++/MltParser.h b/src/mlt++/MltParser.h index 1cfe092c7..6213d5f90 100644 --- a/src/mlt++/MltParser.h +++ b/src/mlt++/MltParser.h @@ -62,6 +62,10 @@ namespace Mlt virtual int on_end_filter( Filter *object ); virtual int on_start_transition( Transition *object ); virtual int on_end_transition( Transition *object ); + virtual int on_start_chain( Chain *object ); + virtual int on_end_chain( Chain *object ); + virtual int on_start_link( Link *object ); + virtual int on_end_link( Link *object ); }; } From 64a693e4940b10419e17ec682f48b1f02976ae11 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 19 Dec 2020 21:44:49 -0600 Subject: [PATCH 014/122] Set version to 7.0.0 Also fix some incorrect\missing entries in the version map. --- CMakeLists.txt | 2 +- configure | 4 ++-- src/framework/mlt.vers | 2 +- src/framework/mlt_version.h | 4 ++-- src/mlt++/mlt++.vers | 19 ++++++++++++++++--- 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b71644a08..94da79df6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.14) project(MLT - VERSION 6.25.0 + VERSION 7.0.0 DESCRIPTION "Multimedia Framework" HOMEPAGE_URL "https://www.mltframework.org" LANGUAGES C CXX diff --git a/configure b/configure index de304b6b0..c17861c3c 100755 --- a/configure +++ b/configure @@ -1,7 +1,7 @@ #!/bin/sh -export version=6.25.0 -export soversion=6 +export version=7.0.0 +export soversion=7 show_help() { diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index 083a36131..9af69a788 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -577,7 +577,7 @@ MLT_6.22.0 { mlt_audio_channel_layout_default; } MLT_6.20.0; -MLT_6.26.0 { +MLT_7.0.0 { global: mlt_factory_link; mlt_chain_init; diff --git a/src/framework/mlt_version.h b/src/framework/mlt_version.h index 7c912cd36..7dd5f1426 100644 --- a/src/framework/mlt_version.h +++ b/src/framework/mlt_version.h @@ -26,8 +26,8 @@ #define MLT_STRINGIZE2(s) #s #define MLT_STRINGIZE(s) MLT_STRINGIZE2(s) -#define LIBMLT_VERSION_MAJOR 6 -#define LIBMLT_VERSION_MINOR 25 +#define LIBMLT_VERSION_MAJOR 7 +#define LIBMLT_VERSION_MINOR 0 #define LIBMLT_VERSION_REVISION 0 #define LIBMLT_VERSION_INT ((LIBMLT_VERSION_MAJOR<<16)+(LIBMLT_VERSION_MINOR<<8)+LIBMLT_VERSION_REVISION) #define LIBMLT_VERSION MLT_STRINGIZE(LIBMLT_VERSION_MAJOR.LIBMLT_VERSION_MINOR.LIBMLT_VERSION_REVISION) diff --git a/src/mlt++/mlt++.vers b/src/mlt++/mlt++.vers index f01c2aa4b..debe6c841 100644 --- a/src/mlt++/mlt++.vers +++ b/src/mlt++/mlt++.vers @@ -613,15 +613,24 @@ MLTPP_6.22.0 { }; } MLTPP_6.20.0; -MLTPP_6.26.0 { +MLTPP_7.0.0 { global: extern "C++" { + "typeinfo for Mlt::Audio"; + "typeinfo name for Mlt::Audio"; + "vtable for Mlt::Audio"; + "typeinfo for Mlt::Link"; + "typeinfo name for Mlt::Link"; + "vtable for Mlt::Link"; + "typeinfo for Mlt::Chain"; + "typeinfo name for Mlt::Chain"; + "vtable for Mlt::Chain"; "Mlt::Link::Link()"; "Mlt::Link::Link(mlt_link)"; "Mlt::Link::Link(char const*, char const*)"; "Mlt::Link::~Link()"; - "Mlt::Link::mlt_link get_link()"; - "Mlt::Link::mlt_producer get_producer()"; + "Mlt::Link::get_link()"; + "Mlt::Link::get_producer()"; "Mlt::Link::connect_next(Mlt::Producer&, Mlt::Profile&)"; "Mlt::Chain::Chain()"; "Mlt::Chain::Chain(Mlt::Profile&, char const*, char const*)"; @@ -641,5 +650,9 @@ MLTPP_6.26.0 { "Mlt::Chain::move_link(int, int)"; "Mlt::Chain::link(int)"; "Mlt::Repository::links() const"; + "Mlt::Parser::on_start_chain(Mlt::Chain*)"; + "Mlt::Parser::on_end_chain(Mlt::Chain*)"; + "Mlt::Parser::on_start_link(Mlt::Link*)"; + "Mlt::Parser::on_end_link(Mlt::Link*)"; }; } MLTPP_6.22.0; From 8fe5235c745e1e4aece4cc5f2334916812bb84df Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 19 Dec 2020 22:25:38 -0600 Subject: [PATCH 015/122] Do not register metadata for avformat-novalidate --- src/framework/mlt_chain.c | 8 +++++++- src/modules/avformat/factory.c | 1 - 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/framework/mlt_chain.c b/src/framework/mlt_chain.c index c5381241d..87e53b2c3 100644 --- a/src/framework/mlt_chain.c +++ b/src/framework/mlt_chain.c @@ -126,7 +126,13 @@ void mlt_chain_set_source( mlt_chain self, mlt_producer source ) // they can be passed between the source producer and this chain. base->source_parameters = mlt_properties_new(); mlt_repository repository = mlt_factory_repository(); - mlt_properties source_metadata = mlt_repository_metadata( repository, mlt_service_producer_type, mlt_properties_get( source_properties, "mlt_service" ) ); + char* source_metadata_name = strdup( mlt_properties_get( source_properties, "mlt_service" ) ); + // If the service name ends in "-novalidate", then drop the ending and search for the metadata of the main service. + // E.g. "avformat-novalidate" -> "avformat" + char* novalidate_ptr = strstr(source_metadata_name, "-novalidate"); + if ( novalidate_ptr ) *novalidate_ptr = '\0'; + mlt_properties source_metadata = mlt_repository_metadata( repository, mlt_service_producer_type, source_metadata_name ); + free( source_metadata_name ); if ( source_metadata ) { mlt_properties params = (mlt_properties) mlt_properties_get_data( source_metadata, "parameters", NULL ); diff --git a/src/modules/avformat/factory.c b/src/modules/avformat/factory.c index e5c555f75..cf80385a4 100644 --- a/src/modules/avformat/factory.c +++ b/src/modules/avformat/factory.c @@ -431,7 +431,6 @@ MLT_REPOSITORY MLT_REGISTER( mlt_service_producer_type, "avformat-novalidate", create_service ); MLT_REGISTER_METADATA( mlt_service_consumer_type, "avformat", avformat_metadata, NULL ); MLT_REGISTER_METADATA( mlt_service_producer_type, "avformat", avformat_metadata, NULL ); - MLT_REGISTER_METADATA( mlt_service_producer_type, "avformat-novalidate", avformat_metadata, NULL ); #endif #ifdef FILTERS MLT_REGISTER( mlt_service_filter_type, "avcolour_space", create_service ); From cb045d23da6c096bc1c00919d402dfa2fc7ad82f Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Wed, 3 Feb 2021 15:23:46 -0800 Subject: [PATCH 016/122] update C++ soversion to 7 This change makes it consistent with its versioned symbols and the C interface. --- src/mlt++/configure | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mlt++/configure b/src/mlt++/configure index fc42e4554..fa95b2499 100755 --- a/src/mlt++/configure +++ b/src/mlt++/configure @@ -1,5 +1,4 @@ #!/bin/sh -echo "soversion=3" > config.mak echo "mlt++ -I$includedir -I$includedir/mlt++ -D_REENTRANT -L$libdir -lmlt++" >> ../../packages.dat WARNINGS="-W -Wwrite-strings -Wcast-qual -Wpointer-arith -Wcast-align -Wredundant-decls" From 10b3a99abd17753c4316912be8abef827e7153dd Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Wed, 3 Feb 2021 16:01:21 -0800 Subject: [PATCH 017/122] fix compiling SWIG bindings --- src/mlt++/MltTransition.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mlt++/MltTransition.h b/src/mlt++/MltTransition.h index 92cea2a3a..82c7e0796 100644 --- a/src/mlt++/MltTransition.h +++ b/src/mlt++/MltTransition.h @@ -30,6 +30,8 @@ namespace Mlt class Service; class Profile; class Frame; + class Chain; + class Link; class MLTPP_DECLSPEC Transition : public Service { From 4d635c57597a8c32396e20b0e2081d3c2e167c68 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Wed, 3 Feb 2021 16:06:42 -0800 Subject: [PATCH 018/122] add link and animation to service metadata --- src/framework/metaschema.yaml | 7 +++++-- src/modules/core/link_timeremap.yml | 3 ++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/framework/metaschema.yaml b/src/framework/metaschema.yaml index 91e05e987..1c5fd8fba 100644 --- a/src/framework/metaschema.yaml +++ b/src/framework/metaschema.yaml @@ -1,5 +1,5 @@ --- # A metadata schema in Kwalify: http://www.kuwata-lab.com/kwalify/ -# Version: 0.3 +# Version: 7 type: map mapping: "schema_version": # This should match the version comment above @@ -11,7 +11,7 @@ mapping: "type": # A service type type: str required: yes - enum: [consumer, filter, producer, transition] + enum: [consumer, filter, link, producer, transition] "identifier": # The same value used to register and create the service type: str required: yes @@ -97,6 +97,9 @@ mapping: # processing the first frame type: bool default: no + "animation": # Does the property support the animation API for keyframes? + type: bool + default: no "widget": # A hint to the UI about how to let the user set this type: str enum: diff --git a/src/modules/core/link_timeremap.yml b/src/modules/core/link_timeremap.yml index e0121d458..4b087f2c6 100644 --- a/src/modules/core/link_timeremap.yml +++ b/src/modules/core/link_timeremap.yml @@ -1,4 +1,4 @@ -schema_version: 0.3 +schema_version: 7 type: link identifier: timeremap title: Time Remap @@ -17,6 +17,7 @@ parameters: description: > A map of input frame times to output frame times. mutable: yes + animation: yes - identifier: image_mode title: Image Mode type: string From feed93b73f8d1b4313208bffdd37823449c8aa33 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Sun, 7 Feb 2021 02:06:45 +0100 Subject: [PATCH 019/122] cmake: add mlt_chain & mlt_link --- src/framework/CMakeLists.txt | 4 ++++ src/mlt++/CMakeLists.txt | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 6b41d0a61..04469c432 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -2,6 +2,7 @@ add_library(mlt SHARED mlt_animation.c mlt_audio.c mlt_cache.c + mlt_chain.c mlt_consumer.c mlt_deque.c mlt_events.c @@ -10,6 +11,7 @@ add_library(mlt SHARED mlt_filter.c mlt_frame.c mlt_geometry.c + mlt_link.c mlt_log.c mlt_luma_map.c mlt_multitrack.c @@ -58,6 +60,7 @@ set(MLT_PUPLIC_HEADERS mlt_animation.h mlt_audio.h mlt_cache.h + mlt_chain.h mlt_consumer.h mlt_deque.h mlt_events.h @@ -66,6 +69,7 @@ set(MLT_PUPLIC_HEADERS mlt_filter.h mlt_frame.h mlt_geometry.h + mlt_link.h mlt_log.h mlt_luma_map.h mlt_multitrack.h diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index 3d167ae9a..c8e109ad7 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -1,6 +1,7 @@ add_library(mlt++ SHARED MltAnimation.cpp MltAudio.cpp + MltChain.cpp MltConsumer.cpp MltDeque.cpp MltEvent.cpp @@ -11,6 +12,7 @@ add_library(mlt++ SHARED MltFilteredProducer.cpp MltFrame.cpp MltGeometry.cpp + MltLink.cpp MltMultitrack.cpp MltParser.cpp MltPlaylist.cpp @@ -45,6 +47,7 @@ set(MLTPP_PUPLIC_HEADERS Mlt.h MltAnimation.h MltAudio.h + MltChain.h MltConfig.h MltConsumer.h MltDeque.h @@ -56,6 +59,7 @@ set(MLTPP_PUPLIC_HEADERS MltFilteredProducer.h MltFrame.h MltGeometry.h + MltLink.h MltMultitrack.h MltParser.h MltPlaylist.h From 624efffcc0bed75a1d1acf85df17d68842377ee6 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Sun, 7 Feb 2021 02:19:40 +0100 Subject: [PATCH 020/122] cmake: update C++ soversion to 7 --- src/mlt++/CMakeLists.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index c8e109ad7..456eeff51 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -34,12 +34,10 @@ target_include_directories(mlt++ PUBLIC $ ) -set(MLTPP_SOVERSION "3") - -set_target_properties(mlt++ PROPERTIES SOVERSION ${MLTPP_SOVERSION} VERSION ${MLT_VERSION}) +set_target_properties(mlt++ PROPERTIES SOVERSION ${MLT_VERSION_MAJOR} VERSION ${MLT_VERSION}) if(WIN32) - set_target_properties(mlt++ PROPERTIES OUTPUT_NAME "mlt++-${MLTPP_SOVERSION}") + set_target_properties(mlt++ PROPERTIES OUTPUT_NAME "mlt++-${MLT_VERSION_MAJOR}") target_compile_definitions(mlt++ PUBLIC MLTPP_EXPORTS) endif() From f853bca37a9986165605c3462b99fb16f9a8a8ca Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Sun, 7 Feb 2021 02:44:01 +0100 Subject: [PATCH 021/122] cmake: add link_timeremap --- src/modules/core/CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/core/CMakeLists.txt b/src/modules/core/CMakeLists.txt index dca1acc5a..ad7a8fc37 100644 --- a/src/modules/core/CMakeLists.txt +++ b/src/modules/core/CMakeLists.txt @@ -28,6 +28,7 @@ add_library(mltcore MODULE filter_resize.c filter_transition.c filter_watermark.c + link_timeremap.c producer_colour.c producer_consumer.c producer_hold.c @@ -82,6 +83,7 @@ install(FILES filter_resize.yml filter_transition.yml filter_watermark.yml + link_timeremap.yml producer_colour.yml producer_consumer.yml producer_hold.yml From 9f7d6a6e13397b7279bd4a7fc30958cc747e718b Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Sun, 7 Feb 2021 02:46:51 +0100 Subject: [PATCH 022/122] workflow/cmake: add --output-on-failure --- .github/workflows/build-linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index dbfbde98a..46f2df117 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -78,4 +78,4 @@ jobs: LD_LIBRARY_PATH: /usr/local/lib run: | sudo locale-gen de_DE.UTF-8 - cd build && ctest + cd build && ctest --output-on-failure From d06c6a3ce46d77acd9aeab62bf3469eac03bacad Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 8 Feb 2021 21:59:11 -0600 Subject: [PATCH 023/122] Remove deprecated dv module --- demo/README | 4 +- demo/consumers.ini | 1 - docs/framework.txt | 15 +- docs/install.txt | 2 - docs/melt.txt | 4 +- src/modules/core/loader.dict | 8 +- src/modules/dv/Makefile | 40 --- src/modules/dv/configure | 17 - src/modules/dv/consumer_libdv.c | 448 ----------------------- src/modules/dv/consumer_libdv.yml | 21 -- src/modules/dv/deprecated | 0 src/modules/dv/factory.c | 41 --- src/modules/dv/producer_libdv.c | 566 ------------------------------ src/modules/dv/producer_libdv.yml | 29 -- 14 files changed, 9 insertions(+), 1187 deletions(-) delete mode 100644 src/modules/dv/Makefile delete mode 100755 src/modules/dv/configure delete mode 100644 src/modules/dv/consumer_libdv.c delete mode 100644 src/modules/dv/consumer_libdv.yml delete mode 100644 src/modules/dv/deprecated delete mode 100644 src/modules/dv/factory.c delete mode 100644 src/modules/dv/producer_libdv.c delete mode 100644 src/modules/dv/producer_libdv.yml diff --git a/demo/README b/demo/README index 555d6ea86..4f75c3710 100644 --- a/demo/README +++ b/demo/README @@ -13,9 +13,7 @@ you to choose a consumer. A consumer is like a viewer, but it could also write to a stream/file. The "SDL" consumer is the popular Simple DirectMedia Layer audio and video output. The "xml" consumer generates an XML representation of the service network. That can be played directly due to the -XML producer plugin. See docs/mlt-xml.txt for more information. "/dev/dv1394/0" -refers to a device file for transmitting DV over FireWire using the Linux -dv1394 kernel module. +XML producer plugin. See docs/mlt-xml.txt for more information. These examples assume the numeric locale LC_NUMERIC decimal separator is a period. Therefore, the demo script sets LC_NUMERIC=C for you, but if you are diff --git a/demo/consumers.ini b/demo/consumers.ini index 5a3d57925..f7363bb41 100644 --- a/demo/consumers.ini +++ b/demo/consumers.ini @@ -4,6 +4,5 @@ SDL High Latency sdl buffer=12 rescale=none SDL Progressive sdl progressive=1 XML to Terminal xml XML to File xml: -libdv to /dev/dv1394/0 libdv:/dev/dv1394/0 rescale=nearest buffer=25 DeckLink decklink DeckLink Prog LL decklink progressive=1 buffer=1 diff --git a/docs/framework.txt b/docs/framework.txt index 32c9b56bb..57163483f 100644 --- a/docs/framework.txt +++ b/docs/framework.txt @@ -79,14 +79,8 @@ Structure and Flow: +--------+ +--------+ A typical consumer requests MLT Frame objects from the producer, does - something with them and when finished with a frame, closes it. - - /\ A common confusion with the producer/consumer terminology used here is - /!!\ that a consumer may 'produce' something. For example, the libdv consumer - \!!/ produces DV and the libdv producer seems to consume DV. However, the - \/ naming conventions refer only to producers and consumers of MLT Frames. - - To put it another way - a producer produces MLT Frame objects and a consumer + something with them and when finished with a frame, closes it. To put it + another way - a producer produces MLT Frame objects and a consumer consumes MLT Frame objects. An MLT Frame essentially provides an uncompressed image and its associated @@ -213,11 +207,6 @@ Hello World: This will play the video using the avformat producer directly, thus it will bypass the normalising functions. - $ MLT_CONSUMER=libdv ./hello file.avi > /dev/dv1394 - - This might, if you're lucky, do on the fly, realtime conversions of file.avi - to DV and broadcast it to your DV device. - Factories: diff --git a/docs/install.txt b/docs/install.txt index 24e458707..532ff59eb 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -24,7 +24,6 @@ Last Revision: 2013-09-07 * core - independent MLT services * decklink - Blackmagick Design SDI/HDMI services * dgraft - ports of Donald Graft's filters (*) - * dv - libdv dependent services * effectv - ports of !EffecTV filters (*) * feeds - templates for use with core's data filters * frei0r - adapter for frei0r video plugins @@ -75,7 +74,6 @@ Last Revision: 2013-09-07 | *Module* | *Description* | | avformat | [[http://www.ffmpeg.org][FFmpeg]] v4.0 or later | - | dv | [[http://libdv.sf.net][libdv]] 0.102 or later | | gtk2 | [[http://www.gtk.org][GTK2]] and associated dependencies | | jackrack | [[http://jackaudio.org][JACK]], [[http://www.xmlsoft.org/][libxml2]], and ladspa.h | | opengl | [[http://git.sesse.net/movit][Movit]] | diff --git a/docs/melt.txt b/docs/melt.txt index 3805dca8d..4e2c86cf7 100644 --- a/docs/melt.txt +++ b/docs/melt.txt @@ -83,8 +83,8 @@ General rules: Terminology: 'Producers' typically refer to files but may also indicate devices (such as - dv1394 input or video4linux). Hence, the more generic term is used [the more - generic usage is out of scope for now...]. + video4linux). Hence, the more generic term is used [the more generic usage + is out of scope for now...]. 'Filters' are frame modifiers - they always guarantee that for every frame they receive, they output *precisely* one frame. Never more, never less, diff --git a/src/modules/core/loader.dict b/src/modules/core/loader.dict index cac691b0c..977a700ab 100644 --- a/src/modules/core/loader.dict +++ b/src/modules/core/loader.dict @@ -9,11 +9,11 @@ plain:https://*=webvfx:plain: *.melt=melt_file *.inigo=melt_file *.asf=avformat -*.avi=mcdv,avformat,libdv +*.avi=mcdv,avformat *.bmp=qimage,pixbuf *.dds=qimage,avformat -*.dv=mcdv,avformat,libdv -*.dif=mcdv,avformat,libdv +*.dv=mcdv,avformat +*.dif=mcdv,avformat *.exr=qimage *.gif=qimage,pixbuf *.graphics=xml @@ -28,7 +28,7 @@ plain:https://*=webvfx:plain: *.kino=xml *.kra=qimage *.mp3=avformat -*.mov=mcdv,avformat,libdv +*.mov=mcdv,avformat *.mpg=mcmpeg,avformat *.mpeg=mcmpeg,avformat *.mpl=pango diff --git a/src/modules/dv/Makefile b/src/modules/dv/Makefile deleted file mode 100644 index 4252ef148..000000000 --- a/src/modules/dv/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt -lpthread - -include ../../../config.mak - -TARGET = ../libmltdv$(LIBSUF) - -OBJS = factory.o \ - producer_libdv.o \ - consumer_libdv.o - -CFLAGS += `pkg-config --cflags libdv` - -LDFLAGS += `pkg-config --libs libdv` - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" - install -d "$(DESTDIR)$(mltdatadir)/dv" - install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/dv" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/dv/configure b/src/modules/dv/configure deleted file mode 100755 index 6712ea613..000000000 --- a/src/modules/dv/configure +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - pkg-config libdv 2> /dev/null - disable_libdv=$? - - if [ "$disable_libdv" != "0" ] - then - echo "- libdv not found: disabling" - touch ../disable-dv - exit 0 - fi - -fi - diff --git a/src/modules/dv/consumer_libdv.c b/src/modules/dv/consumer_libdv.c deleted file mode 100644 index bef1f1b33..000000000 --- a/src/modules/dv/consumer_libdv.c +++ /dev/null @@ -1,448 +0,0 @@ -/* - * consumer_libdv.c -- a DV encoder based on libdv - * Copyright (C) 2003-2017 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -// mlt Header files -#include -#include - -// System header files -#include -#include -#include -#include - -// libdv header files -#include - -#define FRAME_SIZE_525_60 10 * 150 * 80 -#define FRAME_SIZE_625_50 12 * 150 * 80 - -// Forward references. -static int consumer_start( mlt_consumer this ); -static int consumer_stop( mlt_consumer this ); -static int consumer_is_stopped( mlt_consumer this ); -static int consumer_encode_video( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame ); -static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame ); -static void consumer_output( mlt_consumer this, uint8_t *dv_frame, int size, mlt_frame frame ); -static void *consumer_thread( void *arg ); -static void consumer_close( mlt_consumer this ); - -/** Initialise the dv consumer. -*/ - -mlt_consumer consumer_libdv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Allocate the consumer - mlt_consumer this = calloc( 1, sizeof( struct mlt_consumer_s ) ); - - // If memory allocated and initialises without error - if ( this != NULL && mlt_consumer_init( this, NULL, profile ) == 0 ) - { - // Get properties from the consumer - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Assign close callback - this->close = consumer_close; - - // Interpret the argument - if ( arg != NULL ) - mlt_properties_set( properties, "target", arg ); - - // Set the encode and output handling method - mlt_properties_set_data( properties, "video", consumer_encode_video, 0, NULL, NULL ); - mlt_properties_set_data( properties, "audio", consumer_encode_audio, 0, NULL, NULL ); - mlt_properties_set_data( properties, "output", consumer_output, 0, NULL, NULL ); - - // Terminate at end of the stream by default - mlt_properties_set_int( properties, "terminate_on_pause", 1 ); - - // Set up start/stop/terminated callbacks - this->start = consumer_start; - this->stop = consumer_stop; - this->is_stopped = consumer_is_stopped; - } - else - { - // Clean up in case of init failure - free( this ); - this = NULL; - } - - // Return this - return this; -} - -/** Start the consumer. -*/ - -static int consumer_start( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Check that we're not already running - if ( !mlt_properties_get_int( properties, "running" ) ) - { - // Allocate a thread - pthread_t *thread = calloc( 1, sizeof( pthread_t ) ); - - // Assign the thread to properties - mlt_properties_set_data( properties, "thread", thread, sizeof( pthread_t ), free, NULL ); - - // Set the running state - mlt_properties_set_int( properties, "running", 1 ); - - // Create the thread - pthread_create( thread, NULL, consumer_thread, this ); - } - return 0; -} - -/** Stop the consumer. -*/ - -static int consumer_stop( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Check that we're running - if ( mlt_properties_get_int( properties, "running" ) ) - { - // Get the thread - pthread_t *thread = mlt_properties_get_data( properties, "thread", NULL ); - - // Stop the thread - mlt_properties_set_int( properties, "running", 0 ); - - // Wait for termination - pthread_join( *thread, NULL ); - - // Close the output file :-) - this is obtuse - doesn't matter if output file - // exists or not - the destructor will kick in if it does - mlt_properties_set_data( properties, "output_file", NULL, 0, NULL, NULL ); - } - - return 0; -} - -/** Determine if the consumer is stopped. -*/ - -static int consumer_is_stopped( mlt_consumer this ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - return !mlt_properties_get_int( properties, "running" ); -} - -/** Get or create a new libdv encoder. -*/ - -static dv_encoder_t *libdv_get_encoder( mlt_consumer this, mlt_frame frame ) -{ - // Get the properties of the consumer - mlt_properties this_properties = MLT_CONSUMER_PROPERTIES( this ); - - // Obtain the dv_encoder - dv_encoder_t *encoder = mlt_properties_get_data( this_properties, "dv_encoder", NULL ); - - // Construct one if we don't have one - if ( encoder == NULL ) - { - // Get the fps of the consumer (for now - should be from frame) - double fps = mlt_properties_get_double( this_properties, "fps" ); - - // Create the encoder - encoder = dv_encoder_new( 0, 0, 0 ); - - // Encoder settings - encoder->isPAL = fps == 25; - encoder->is16x9 = 0; - encoder->vlc_encode_passes = 1; - encoder->static_qno = 0; - encoder->force_dct = DV_DCT_AUTO; - - // Store the encoder on the properties - mlt_properties_set_data( this_properties, "dv_encoder", encoder, 0, ( mlt_destructor )dv_encoder_free, NULL ); - } - - // Return the encoder - return encoder; -} - - -/** The libdv encode video method. -*/ - -static int consumer_encode_video( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame ) -{ - // Obtain the dv_encoder - dv_encoder_t *encoder = libdv_get_encoder( this, frame ); - - // Get the properties of the consumer - mlt_properties this_properties = MLT_CONSUMER_PROPERTIES( this ); - - // This will hold the size of the dv frame - int size = 0; - - // Is the image rendered - int rendered = mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "rendered" ); - - // Get width and height - int width = mlt_properties_get_int( this_properties, "width" ); - int height = mlt_properties_get_int( this_properties, "height" ); - - // If we get an encoder, then encode the image - if ( rendered && encoder != NULL ) - { - // Specify desired image properties - mlt_image_format fmt = mlt_image_yuv422; - uint8_t *image = NULL; - - // Get the image - mlt_frame_get_image( frame, &image, &fmt, &width, &height, 0 ); - - // Check that we get what we expected - if ( fmt != mlt_image_yuv422 || - width != mlt_properties_get_int( this_properties, "width" ) || - height != mlt_properties_get_int( this_properties, "height" ) || - image == NULL ) - { - // We should try to recover here - fprintf( stderr, "We have a problem houston...\n" ); - } - else - { - // Calculate the size of the dv frame - size = height == 576 ? FRAME_SIZE_625_50 : FRAME_SIZE_525_60; - } - - // Process the frame - if ( size != 0 ) - { - // Encode the image - dv_encode_full_frame( encoder, &image, e_dv_color_yuv, dv_frame ); - } - mlt_events_fire( this_properties, "consumer-frame-show", frame, NULL ); - } - else if ( encoder != NULL ) - { - // Calculate the size of the dv frame (duplicate of previous) - size = height == 576 ? FRAME_SIZE_625_50 : FRAME_SIZE_525_60; - } - - return size; -} - -/** The libdv encode audio method. -*/ - -static void consumer_encode_audio( mlt_consumer this, uint8_t *dv_frame, mlt_frame frame ) -{ - // Get the properties of the consumer - mlt_properties this_properties = MLT_CONSUMER_PROPERTIES( this ); - - // Get the properties of the frame - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - - // Obtain the dv_encoder - dv_encoder_t *encoder = libdv_get_encoder( this, frame ); - - // Only continue if we have an encoder - if ( encoder != NULL ) - { - // Get the frame count - int count = mlt_properties_get_int( this_properties, "count" ); - - // Default audio args - mlt_audio_format fmt = mlt_audio_s16; - int channels = 2; - int frequency = mlt_properties_get_int( this_properties, "frequency" ); - int samples = mlt_audio_calculate_frame_samples( mlt_properties_get_double( this_properties, "fps" ), frequency, count ); - int16_t *pcm = NULL; - - // Get the frame number - time_t start = time( NULL ); - int height = mlt_properties_get_int( this_properties, "height" ); - int is_pal = height == 576; - int is_wide = mlt_properties_get_int( this_properties, "display_aspect_num" ) == 16; - - // Temporary - audio buffer allocation - int16_t *audio_buffers[ 4 ]; - int i = 0; - int j = 0; - for ( i = 0 ; i < 4; i ++ ) - audio_buffers[ i ] = mlt_pool_alloc( 2 * DV_AUDIO_MAX_SAMPLES ); - - // Get the audio - mlt_frame_get_audio( frame, (void**) &pcm, &fmt, &frequency, &channels, &samples ); - - // Inform the encoder of the number of audio samples - encoder->samples_this_frame = samples; - - // Fill the audio buffers correctly - if ( mlt_properties_get_double( frame_properties, "_speed" ) == 1.0 ) - { - for ( i = 0; i < samples; i ++ ) - for ( j = 0; j < channels; j++ ) - audio_buffers[ j ][ i ] = *pcm ++; - } - else - { - for ( j = 0; j < channels; j++ ) - memset( audio_buffers[ j ], 0, 2 * DV_AUDIO_MAX_SAMPLES ); - } - - // Encode audio on frame - dv_encode_full_audio( encoder, audio_buffers, channels, frequency, dv_frame ); - - // Specify meta data on the frame - dv_encode_metadata( dv_frame, is_pal, is_wide, &start, count ); - dv_encode_timecode( dv_frame, is_pal, count ); - - // Update properties - mlt_properties_set_int( this_properties, "count", ++ count ); - - // Temporary - free audio buffers - for ( i = 0 ; i < 4; i ++ ) - mlt_pool_release( audio_buffers[ i ] ); - } -} - -/** The libdv output method. -*/ - -static void consumer_output( mlt_consumer this, uint8_t *dv_frame, int size, mlt_frame frame ) -{ - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - FILE *output = stdout; - char *target = mlt_properties_get( properties, "target" ); - - if ( target != NULL ) - { - output = mlt_properties_get_data( properties, "output_file", NULL ); - if ( output == NULL ) - { - output = mlt_fopen( target, "wb" ); - if ( output != NULL ) - mlt_properties_set_data( properties, "output_file", output, 0, ( mlt_destructor )fclose, 0 ); - } - } - - if ( output != NULL ) - { - fwrite( dv_frame, size, 1, output ); - fflush( output ); - } - else - { - fprintf( stderr, "Unable to open %s\n", target ); - } -} - -/** The main thread - the argument is simply the consumer. -*/ - -static void *consumer_thread( void *arg ) -{ - // Map the argument to the object - mlt_consumer this = arg; - - // Get the properties - mlt_properties properties = MLT_CONSUMER_PROPERTIES( this ); - - // Get the terminate_on_pause property - int top = mlt_properties_get_int( properties, "terminate_on_pause" ); - - // Get the handling methods - int ( *video )( mlt_consumer, uint8_t *, mlt_frame ) = mlt_properties_get_data( properties, "video", NULL ); - int ( *audio )( mlt_consumer, uint8_t *, mlt_frame ) = mlt_properties_get_data( properties, "audio", NULL ); - int ( *output )( mlt_consumer, uint8_t *, int, mlt_frame ) = mlt_properties_get_data( properties, "output", NULL ); - - // Allocate a single PAL frame for encoding - uint8_t *dv_frame = mlt_pool_alloc( FRAME_SIZE_625_50 ); - - // Frame and size - mlt_frame frame = NULL; - int size = 0; - - // Loop while running - while( mlt_properties_get_int( properties, "running" ) ) - { - // Get the frame - frame = mlt_consumer_rt_frame( this ); - - // Check that we have a frame to work with - if ( frame != NULL ) - { - // Terminate on pause - if ( top && mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ) == 0 ) - { - mlt_frame_close( frame ); - break; - } - - // Obtain the dv_encoder - if ( libdv_get_encoder( this, frame ) != NULL ) - { - // Encode the image - size = video( this, dv_frame, frame ); - - // Encode the audio - if ( size > 0 ) - audio( this, dv_frame, frame ); - - // Output the frame - output( this, dv_frame, size, frame ); - - // Close the frame - mlt_frame_close( frame ); - } - else - { - fprintf( stderr, "Unable to obtain dv encoder.\n" ); - } - } - } - - // Tidy up - mlt_pool_release( dv_frame ); - - mlt_consumer_stopped( this ); - - return NULL; -} - -/** Close the consumer. -*/ - -static void consumer_close( mlt_consumer this ) -{ - // Stop the consumer - mlt_consumer_stop( this ); - - // Close the parent - mlt_consumer_close( this ); - - // Free the memory - free( this ); -} diff --git a/src/modules/dv/consumer_libdv.yml b/src/modules/dv/consumer_libdv.yml deleted file mode 100644 index c00bd8547..000000000 --- a/src/modules/dv/consumer_libdv.yml +++ /dev/null @@ -1,21 +0,0 @@ -schema_version: 0.1 -type: consumer -identifier: libdv -title: libdv (*deprecated*) -version: 1 -copyright: Meltytech, LLC -creator: Charles Yates -license: LGPLv2.1 -language: en -tags: - - Audio - - Video -description: > - DV consumer using libdv. -parameters: - - identifier: argument - title: File - type: string - description: The filename to write to, e.g. /dev/dv1394. - required: yes - widget: filesave diff --git a/src/modules/dv/deprecated b/src/modules/dv/deprecated deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/modules/dv/factory.c b/src/modules/dv/factory.c deleted file mode 100644 index d5bc2bf53..000000000 --- a/src/modules/dv/factory.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -extern mlt_consumer consumer_libdv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_libdv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -static mlt_properties metadata( mlt_service_type type, const char *id, void *data ) -{ - char file[ PATH_MAX ]; - snprintf( file, PATH_MAX, "%s/dv/%s", mlt_environment( "MLT_DATA" ), (char*) data ); - return mlt_properties_parse_yaml( file ); -} - -MLT_REPOSITORY -{ - MLT_REGISTER( mlt_service_consumer_type, "libdv", consumer_libdv_init ); - MLT_REGISTER( mlt_service_producer_type, "libdv", producer_libdv_init ); - - MLT_REGISTER_METADATA( mlt_service_consumer_type, "libdv", metadata, "consumer_libdv.yml" ); - MLT_REGISTER_METADATA( mlt_service_producer_type, "libdv", metadata, "producer_libdv.yml" ); -} diff --git a/src/modules/dv/producer_libdv.c b/src/modules/dv/producer_libdv.c deleted file mode 100644 index c19a521b5..000000000 --- a/src/modules/dv/producer_libdv.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * producer_libdv.c -- simple libdv test case - * Copyright (C) 2003-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define FRAME_SIZE_525_60 10 * 150 * 80 -#define FRAME_SIZE_625_50 12 * 150 * 80 - -/** To conserve resources, we maintain a stack of dv decoders. -*/ - -static pthread_mutex_t decoder_lock = PTHREAD_MUTEX_INITIALIZER; -static mlt_properties dv_decoders = NULL; - -dv_decoder_t *dv_decoder_alloc( ) -{ - // We'll return a dv_decoder - dv_decoder_t *this = NULL; - - // Lock the mutex - pthread_mutex_lock( &decoder_lock ); - - // Create the properties if necessary - if ( dv_decoders == NULL ) - { - // Create the properties - dv_decoders = mlt_properties_new( ); - - // Create the stack - mlt_properties_set_data( dv_decoders, "stack", mlt_deque_init( ), 0, ( mlt_destructor )mlt_deque_close, NULL ); - - // Register the properties for clean up - mlt_factory_register_for_clean_up( dv_decoders, ( mlt_destructor )mlt_properties_close ); - } - - // Now try to obtain a decoder - if ( dv_decoders != NULL ) - { - // Obtain the stack - mlt_deque stack = mlt_properties_get_data( dv_decoders, "stack", NULL ); - - // Pop the top of the stack - this = mlt_deque_pop_back( stack ); - - // Create a new decoder if none available - if ( this == NULL ) - { - // We'll need a unique property ID for this - char label[ 256 ]; - - // Configure the decoder - this = dv_decoder_new( FALSE, FALSE, FALSE ); - this->quality = DV_QUALITY_COLOR | DV_QUALITY_AC_2; - this->audio->arg_audio_emphasis = 2; - dv_set_audio_correction( this, DV_AUDIO_CORRECT_AVERAGE ); - dv_set_error_log( this, NULL ); - - // Register it with the properties to ensure clean up - sprintf( label, "%p", this ); - mlt_properties_set_data( dv_decoders, label, this, 0, ( mlt_destructor )dv_decoder_free, NULL ); - } - } - - // Unlock the mutex - pthread_mutex_unlock( &decoder_lock ); - - return this; -} - -void dv_decoder_return( dv_decoder_t *this ) -{ - // Lock the mutex - pthread_mutex_lock( &decoder_lock ); - - // Now try to return the decoder - if ( dv_decoders != NULL ) - { - // Obtain the stack - mlt_deque stack = mlt_properties_get_data( dv_decoders, "stack", NULL ); - - // Push it back - mlt_deque_push_back( stack, this ); - } - - // Unlock the mutex - pthread_mutex_unlock( &decoder_lock ); -} - - -typedef struct producer_libdv_s *producer_libdv; - -struct producer_libdv_s -{ - struct mlt_producer_s parent; - int fd; - int is_pal; - uint64_t file_size; - int frame_size; - long frames_in_file; - mlt_producer alternative; -}; - -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); - -static int producer_collect_info( producer_libdv this, mlt_profile profile ); - -mlt_producer producer_libdv_init( mlt_profile profile, mlt_service_type type, const char *id, char *filename ) -{ - producer_libdv this = calloc( 1, sizeof( struct producer_libdv_s ) ); - - if ( filename != NULL && this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) - { - int destroy = 0; - mlt_producer producer = &this->parent; - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Set the resource property (required for all producers) - mlt_properties_set( properties, "resource", filename ); - - // Register transport implementation with the producer - producer->close = ( mlt_destructor )producer_close; - - // Register our get_frame implementation with the producer - producer->get_frame = producer_get_frame; - - // If we have mov or dv, then we'll use an alternative producer - if ( strchr( filename, '.' ) != NULL && ( - strncasecmp( strrchr( filename, '.' ), ".avi", 4 ) == 0 || - strncasecmp( strrchr( filename, '.' ), ".mov", 4 ) == 0 ) ) - { - // Load via an alternative mechanism - mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ); - this->alternative = mlt_factory_producer( profile, "kino", filename ); - - // If it's unavailable, then clean up - if ( this->alternative == NULL ) - destroy = 1; - else - mlt_properties_pass( properties, MLT_PRODUCER_PROPERTIES( this->alternative ), "" ); - this->is_pal = ( ( int ) mlt_producer_get_fps( producer ) ) == 25; - } - else - { - // Open the file if specified - this->fd = open( filename, O_RDONLY ); - - // Collect info - if ( this->fd == -1 || !producer_collect_info( this, profile ) ) - destroy = 1; - } - - // If we couldn't open the file, then destroy it now - if ( destroy ) - { - mlt_producer_close( producer ); - producer = NULL; - } - - // Return the producer - return producer; - } - free( this ); - return NULL; -} - -static int read_frame( int fd, uint8_t* frame_buf, int *isPAL ) -{ - int result = read( fd, frame_buf, FRAME_SIZE_525_60 ) == FRAME_SIZE_525_60; - if ( result ) - { - *isPAL = ( frame_buf[3] & 0x80 ); - if ( *isPAL ) - { - int diff = FRAME_SIZE_625_50 - FRAME_SIZE_525_60; - result = read( fd, frame_buf + FRAME_SIZE_525_60, diff ) == diff; - } - } - - return result; -} - -static int producer_collect_info( producer_libdv this, mlt_profile profile ) -{ - int valid = 0; - - uint8_t *dv_data = mlt_pool_alloc( FRAME_SIZE_625_50 ); - - if ( dv_data != NULL ) - { - // Read the first frame - valid = read_frame( this->fd, dv_data, &this->is_pal ); - - // If it looks like a valid frame, the get stats - if ( valid ) - { - double aspect_ratio; - - // Get the properties - mlt_properties properties = MLT_PRODUCER_PROPERTIES( &this->parent ); - - // Get a dv_decoder - dv_decoder_t *dv_decoder = dv_decoder_alloc( ); - - // Determine the file size - struct stat buf; - fstat( this->fd, &buf ); - - // Store the file size - this->file_size = buf.st_size; - - // Determine the frame size - this->frame_size = this->is_pal ? FRAME_SIZE_625_50 : FRAME_SIZE_525_60; - - // Determine the number of frames in the file - this->frames_in_file = this->file_size / this->frame_size; - - // Calculate default in/out points - int fps = 1000 * ( this->is_pal ? 25 : ( 30000.0 / 1001.0 ) ); - if ( ( int )( mlt_profile_fps( profile ) * 1000 ) == fps ) - { - if ( this->frames_in_file > 0 ) - { - mlt_properties_set_position( properties, "length", this->frames_in_file ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", this->frames_in_file - 1 ); - } - } - else - { - valid = 0; - } - - // Parse the header for meta info - dv_parse_header( dv_decoder, dv_data ); - if ( this->is_pal ) - { - if ( dv_format_wide( dv_decoder ) ) - aspect_ratio = 64.0 / 45.0; - else - aspect_ratio = 16.0 / 15.0; - } - else - { - if ( dv_format_wide( dv_decoder ) ) - aspect_ratio = 32.0 / 27.0; - else - aspect_ratio = 8 / 9; - } - mlt_properties_set_double( properties, "aspect_ratio", aspect_ratio); - mlt_properties_set_int( properties, "meta.media.nb_streams", 2 ); - mlt_properties_set_int( properties, "video_index", 0 ); - mlt_properties_set( properties, "meta.media.0.stream.type", "video" ); - mlt_properties_set( properties, "meta.media.0.codec.name", "dvvideo" ); - mlt_properties_set( properties, "meta.media.0.codec.long_name", "DV (Digital Video)" ); - mlt_properties_set_int( properties, "audio_index", 1 ); - mlt_properties_set( properties, "meta.media.1.stream.type", "audio" ); - mlt_properties_set( properties, "meta.media.1.codec.name", "pcm_s16le" ); - mlt_properties_set( properties, "meta.media.1.codec.long_name", "signed 16-bit little-endian PCM" ); - mlt_properties_set_int( properties, "meta.media.width", 720 ); - mlt_properties_set_int( properties, "meta.media.height", this->is_pal ? 576 : 480 ); - mlt_properties_set_int( properties, "meta.media.frame_rate_num", this->is_pal? 25 : 30000 ); - mlt_properties_set_int( properties, "meta.media.frame_rate_den", this->is_pal? 1 : 1001 ); - - // Return the decoder - dv_decoder_return( dv_decoder ); - } - - mlt_pool_release( dv_data ); - } - - return valid; -} - -static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - int pitches[3] = { 0, 0, 0 }; - uint8_t *pixels[3] = { NULL, NULL, NULL }; - - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get a dv_decoder - dv_decoder_t *decoder = dv_decoder_alloc( ); - - // Get the dv data - uint8_t *dv_data = mlt_properties_get_data( properties, "dv_data", NULL ); - - // Get and set the quality request - char *quality = mlt_frame_pop_service( this ); - - if ( quality != NULL ) - { - if ( strncmp( quality, "fast", 4 ) == 0 ) - decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_DC ); - else if ( strncmp( quality, "best", 4 ) == 0 ) - decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_AC_2 ); - else - decoder->quality = ( DV_QUALITY_COLOR | DV_QUALITY_AC_1 ); - } - - // Parse the header for meta info - dv_parse_header( decoder, dv_data ); - - // Assign width and height according to the frame - *width = 720; - *height = dv_data[ 3 ] & 0x80 ? 576 : 480; - - // Extract an image of the format requested - if ( *format != mlt_image_rgb24 ) - { - // Allocate an image - uint8_t *image = mlt_pool_alloc( *width * ( *height + 1 ) * 2 ); - - // Pass to properties for clean up - mlt_frame_set_image( this, image, *width * ( *height + 1 ) * 2, mlt_pool_release ); - - // Decode the image - pitches[ 0 ] = *width * 2; - pixels[ 0 ] = image; - dv_decode_full_frame( decoder, dv_data, e_dv_color_yuv, pixels, pitches ); - - // Assign result - *buffer = image; - *format = mlt_image_yuv422; - } - else - { - // Allocate an image - uint8_t *image = mlt_pool_alloc( *width * ( *height + 1 ) * 3 ); - - // Pass to properties for clean up - mlt_frame_set_image( this, image, *width * ( *height + 1 ) * 3, mlt_pool_release ); - - // Decode the frame - pitches[ 0 ] = 720 * 3; - pixels[ 0 ] = image; - dv_decode_full_frame( decoder, dv_data, e_dv_color_rgb, pixels, pitches ); - - // Assign result - *buffer = image; - *format = mlt_image_rgb24; - } - - // Return the decoder - dv_decoder_return( decoder ); - - return 0; -} - -static int producer_get_audio( mlt_frame this, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) -{ - int16_t *p; - int i, j; - int16_t *audio_channels[ 4 ]; - - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( this ); - - // Get a dv_decoder - dv_decoder_t *decoder = dv_decoder_alloc( ); - - // Get the dv data - uint8_t *dv_data = mlt_properties_get_data( properties, "dv_data", NULL ); - - // Parse the header for meta info - dv_parse_header( decoder, dv_data ); - - // Check that we have audio - if ( decoder->audio->num_channels > 0 ) - { - int size = *channels * DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ); - - // Obtain required values - *frequency = decoder->audio->frequency; - *samples = decoder->audio->samples_this_frame; - *channels = decoder->audio->num_channels; - *format = mlt_audio_s16; - - // Create a temporary workspace - for ( i = 0; i < 4; i++ ) - audio_channels[ i ] = mlt_pool_alloc( DV_AUDIO_MAX_SAMPLES * sizeof( int16_t ) ); - - // Create a workspace for the result - *buffer = mlt_pool_alloc( size ); - - // Pass the allocated audio buffer as a property - mlt_frame_set_audio( this, *buffer, *format, size, mlt_pool_release ); - - // Decode the audio - dv_decode_full_audio( decoder, dv_data, audio_channels ); - - // Interleave the audio - p = *buffer; - for ( i = 0; i < *samples; i++ ) - for ( j = 0; j < *channels; j++ ) - *p++ = audio_channels[ j ][ i ]; - - // Free the temporary work space - for ( i = 0; i < 4; i++ ) - mlt_pool_release( audio_channels[ i ] ); - } - else - { - // No audio available on the frame, so get test audio (silence) - mlt_frame_get_audio( this, buffer, format, frequency, channels, samples ); - } - - // Return the decoder - dv_decoder_return( decoder ); - - return 0; -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Access the private data - producer_libdv this = producer->child; - - // Will carry the frame data - uint8_t *data = NULL; - - // Obtain the current frame number - uint64_t position = mlt_producer_frame( producer ); - - if ( this->alternative == NULL ) - { - // Convert timecode to a file position (ensuring that we're on a frame boundary) - uint64_t offset = position * this->frame_size; - - // Allocate space - data = mlt_pool_alloc( FRAME_SIZE_625_50 ); - - // Create an empty frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - // Seek and fetch - if ( this->fd != 0 && - lseek( this->fd, offset, SEEK_SET ) == offset && - read_frame( this->fd, data, &this->is_pal ) ) - { - // Pass the dv data - mlt_properties_set_data( MLT_FRAME_PROPERTIES( *frame ), "dv_data", data, FRAME_SIZE_625_50, ( mlt_destructor )mlt_pool_release, NULL ); - } - else - { - mlt_pool_release( data ); - data = NULL; - } - } - else - { - // Seek - mlt_producer_seek( this->alternative, position ); - - // Fetch - mlt_service_get_frame( MLT_PRODUCER_SERVICE( this->alternative ), frame, 0 ); - - // Verify - if ( *frame != NULL ) - data = mlt_properties_get_data( MLT_FRAME_PROPERTIES( *frame ), "dv_data", NULL ); - } - - if ( data != NULL ) - { - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Get a dv_decoder - dv_decoder_t *dv_decoder = dv_decoder_alloc( ); - - mlt_properties_set_int( properties, "test_image", 0 ); - mlt_properties_set_int( properties, "test_audio", 0 ); - - // 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", !this->is_pal ? 0 : ( data[ 5 ] & 0x07 ) == 0 ? 0 : 1 ); - mlt_properties_set_int( properties, "colorspace", 601 ); - - // Parse the header for meta info - dv_parse_header( dv_decoder, data ); - //mlt_properties_set_int( properties, "progressive", dv_is_progressive( dv_decoder ) ); - mlt_properties_set_double( properties, "aspect_ratio", - dv_format_wide( dv_decoder ) ? ( this->is_pal ? 118.0/81.0 : 40.0/33.0 ) : ( this->is_pal ? 59.0/54.0 : 10.0/11.0 ) ); - - - mlt_properties_set_int( properties, "audio_frequency", dv_decoder->audio->frequency ); - mlt_properties_set_int( properties, "audio_channels", dv_decoder->audio->num_channels ); - - // Register audio callback - if ( mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "audio_index" ) > 0 ) - mlt_frame_push_audio( *frame, producer_get_audio ); - - if ( mlt_properties_get_int( MLT_PRODUCER_PROPERTIES( producer ), "video_index" ) > -1 ) - { - // Push the quality string - mlt_frame_push_service( *frame, mlt_properties_get( MLT_PRODUCER_PROPERTIES( producer ), "quality" ) ); - - // Push the get_image method on to the stack - mlt_frame_push_get_image( *frame, producer_get_image ); - } - - // Return the decoder - dv_decoder_return( dv_decoder ); - } - - // Update timecode on the frame we're creating - if ( *frame != NULL ) - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - // Obtain this - producer_libdv this = parent->child; - - // Close the file - if ( this->fd > 0 ) - close( this->fd ); - - if ( this->alternative ) - mlt_producer_close( this->alternative ); - - // Close the parent - parent->close = NULL; - mlt_producer_close( parent ); - - // Free the memory - free( this ); -} diff --git a/src/modules/dv/producer_libdv.yml b/src/modules/dv/producer_libdv.yml deleted file mode 100644 index a085a2737..000000000 --- a/src/modules/dv/producer_libdv.yml +++ /dev/null @@ -1,29 +0,0 @@ -schema_version: 0.1 -type: producer -identifier: libdv -title: libdv (*deprecated*) -version: 1 -copyright: Meltytech, LLC -creator: Charles Yates -license: LGPLv2.1 -language: en -tags: - - Audio - - Video -description: A libdv based decoder for video and audio. -parameters: - - identifier: argument - title: File - type: string - required: yes - readonly: no - widget: fileopen - - - identifier: quality - title: Quality - type: string - description: One of "best," "fast" or anything else chooses medium. - readonly: no - mutable: yes - widget: combo - default: best From 018b819e9761b947f22145c757d29c66c856265f Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 8 Feb 2021 22:06:10 -0600 Subject: [PATCH 024/122] Remove deprecated gtk2 module --- CMakeLists.txt | 6 --- docs/install.txt | 1 - src/modules/CMakeLists.txt | 4 -- src/modules/gtk2/CMakeLists.txt | 20 ------- src/modules/gtk2/Makefile | 41 -------------- src/modules/gtk2/configure | 46 ---------------- src/modules/gtk2/consumer_gtk2.c | 62 --------------------- src/modules/gtk2/consumer_gtk2_preview.yml | 13 ----- src/modules/gtk2/deprecated | 0 src/modules/gtk2/factory.c | 63 ---------------------- src/modules/qt/producer_qimage.c | 3 -- src/modules/qt/qimage_wrapper.cpp | 3 -- src/modules/qt/qimage_wrapper.h | 3 -- 13 files changed, 265 deletions(-) delete mode 100644 src/modules/gtk2/CMakeLists.txt delete mode 100644 src/modules/gtk2/Makefile delete mode 100755 src/modules/gtk2/configure delete mode 100644 src/modules/gtk2/consumer_gtk2.c delete mode 100644 src/modules/gtk2/consumer_gtk2_preview.yml delete mode 100644 src/modules/gtk2/deprecated delete mode 100644 src/modules/gtk2/factory.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e21b9b02..d6bd45134 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,6 @@ option(MOD_DECKLINK "Enable decklink module" ON) option(MOD_FEEDS "Enable feeds module" ON) option(MOD_FREI0R "Enable frei0r module" ON) option(MOD_GDK "Enable gdk module" ON) -option(MOD_GTK2 "Enable gtk2 module" ON) option(MOD_JACKRACK "Enable jackrack module" ON) option(MOD_KDENLIVE "Enable kdenlive module" ON) option(MOD_LUMAS "Enable lumas module" ON) @@ -145,11 +144,6 @@ if(MOD_GDK) pkg_check_modules(pangoft2 IMPORTED_TARGET pangoft2) endif() -if(MOD_GTK2) - find_package(GTK2 COMPONENTS gtk) - pkg_check_modules(harfbuzz IMPORTED_TARGET harfbuzz) -endif() - if(MOD_JACKRACK) pkg_check_modules(jack IMPORTED_TARGET jack) pkg_check_modules(glib IMPORTED_TARGET glib-2.0) diff --git a/docs/install.txt b/docs/install.txt index 532ff59eb..2bff57f6b 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -74,7 +74,6 @@ Last Revision: 2013-09-07 | *Module* | *Description* | | avformat | [[http://www.ffmpeg.org][FFmpeg]] v4.0 or later | - | gtk2 | [[http://www.gtk.org][GTK2]] and associated dependencies | | jackrack | [[http://jackaudio.org][JACK]], [[http://www.xmlsoft.org/][libxml2]], and ladspa.h | | opengl | [[http://git.sesse.net/movit][Movit]] | | qt | [[http://www.qt-project.org][Qt]] 4.4 or later | diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 45e57803a..cd3f58d5a 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -20,10 +20,6 @@ if(MOD_GDK AND TARGET PkgConfig::GdkPixbuf) add_subdirectory(gdk) endif() -if(MOD_GTK2) - add_subdirectory(gtk2) -endif() - if(MOD_JACKRACK AND TARGET PkgConfig::jack) add_subdirectory(jackrack) endif() diff --git a/src/modules/gtk2/CMakeLists.txt b/src/modules/gtk2/CMakeLists.txt deleted file mode 100644 index 190e5f62c..000000000 --- a/src/modules/gtk2/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -add_library(mltgtk2 MODULE factory.c) -target_link_libraries(mltgtk2 PRIVATE mlt m Threads::Threads) - -if(TARGET GTK2::gtk AND TARGET PkgConfig::fontconfig AND TARGET PkgConfig::harfbuzz) - target_sources(mltgtk2 PRIVATE consumer_gtk2.c) - target_link_libraries(mltgtk2 PRIVATE - GTK2::gtk - GTK2::gdk_pixbuf - GTK2::pango - PkgConfig::fontconfig - PkgConfig::harfbuzz - ) - target_compile_definitions(mltgtk2 PRIVATE USE_GTK2) - install(FILES consumer_gtk2_preview.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/gtk2) -endif() - -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltgtk2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) - -install(TARGETS mltgtk2 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/gtk2/Makefile b/src/modules/gtk2/Makefile deleted file mode 100644 index 3b9dba025..000000000 --- a/src/modules/gtk2/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -include ../../../config.mak -include config.mak - -CFLAGS := -I../.. $(CFLAGS) - -LDFLAGS := -L../../framework -lmlt -lpthread -lm $(LDFLAGS) - -TARGET = ../libmltgtk2$(LIBSUF) - -OBJS = factory.o - -ifdef USE_GTK2 -OBJS += consumer_gtk2.o -CFLAGS += $(shell pkg-config $(PKGCONFIG_PREFIX) --cflags gtk+-2.0) -LDFLAGS += $(shell pkg-config $(PKGCONFIG_PREFIX) --libs gtk+-2.0) -endif - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) $(ASM_OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(ASM_OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(ASM_OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" - install -d "$(DESTDIR)$(mltdatadir)/gtk2" - install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/gtk2" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/gtk2/configure b/src/modules/gtk2/configure deleted file mode 100755 index 7637abfc3..000000000 --- a/src/modules/gtk2/configure +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh - -if [ "$help" = "1" ] -then - cat << EOF -GTK+ options: - - --gtk2-prefix=path - Override the gtk+-2.0 prefix for pkg-config - -EOF - -else - pkgconfig_prefix= - for i in "$@" - do - case $i in - --gtk2-prefix=* ) pkgconfig_prefix="${i#--gtk2-prefix=}" ;; - esac - done - [ "$pkgconfig_prefix" != "" ] && pkgconfig_prefix="--define-variable=prefix=\"$pkgconfig_prefix\"" - - pkg-config $pkgconfig_prefix gtk+-2.0 2> /dev/null - disable_gtk2=$? - - if [ "$disable_gtk2" != "0" ] - then - echo "- GTK2 components not found: disabling" - touch ../disable-gtk2 - exit 0 - fi - - echo > config.mak - - if [ "$disable_gtk2" = "0" ] - then - echo "CFLAGS += -DUSE_GTK2" >> config.mak - echo "USE_GTK2=1" >> config.mak - else - echo "- gtk2 not found: gtk2 preview disabled" - fi - - [ "$pkgconfig_prefix" != "" ] && echo "PKGCONFIG_PREFIX=$pkgconfig_prefix" >> config.mak - - exit 0 -fi - diff --git a/src/modules/gtk2/consumer_gtk2.c b/src/modules/gtk2/consumer_gtk2.c deleted file mode 100644 index 2dbe9cbad..000000000 --- a/src/modules/gtk2/consumer_gtk2.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * consumer_gtk2.c -- A consumer for GTK2 apps - * Copyright (C) 2003-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#ifdef _WIN32 -#include -#else -#include -#endif -#include - -mlt_consumer consumer_gtk2_preview_init( mlt_profile profile, GtkWidget *widget ) -{ - // Create an sdl preview consumer - mlt_consumer consumer = NULL; - - // This is a nasty little hack which is required by SDL - if ( widget != NULL ) - { -#ifdef _WIN32 - HWND xwin = GDK_WINDOW_HWND( widget->window ); -#else - Window xwin = GDK_WINDOW_XWINDOW( widget->window ); -#endif - char windowhack[ 32 ]; - sprintf( windowhack, "%ld", (long) xwin ); - setenv( "SDL_WINDOWID", windowhack, 1 ); - } - - // Create an sdl preview consumer - consumer = mlt_factory_consumer( profile, "sdl_preview", NULL ); - - // Now assign the lock/unlock callbacks - if ( consumer != NULL ) - { - mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer ); - mlt_properties_set_int( properties, "app_locked", 1 ); - mlt_properties_set_data( properties, "app_lock", gdk_threads_enter, 0, NULL, NULL ); - mlt_properties_set_data( properties, "app_unlock", gdk_threads_leave, 0, NULL, NULL ); - } - - return consumer; -} diff --git a/src/modules/gtk2/consumer_gtk2_preview.yml b/src/modules/gtk2/consumer_gtk2_preview.yml deleted file mode 100644 index efd78a8e0..000000000 --- a/src/modules/gtk2/consumer_gtk2_preview.yml +++ /dev/null @@ -1,13 +0,0 @@ -schema_version: 0.1 -type: consumer -identifier: gtk_preview -title: GTK+ (*deprecated*) -description: A wrapper for sdl_preview that makes it easy to embed in GTK+ applications. -version: 1 -copyright: Meltytech, LLC -creator: Charles Yates -license: LGPLv2.1 -language: en -tags: - - Audio - - Video diff --git a/src/modules/gtk2/deprecated b/src/modules/gtk2/deprecated deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/modules/gtk2/factory.c b/src/modules/gtk2/factory.c deleted file mode 100644 index 85857ddf7..000000000 --- a/src/modules/gtk2/factory.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2003-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -#ifdef USE_GTK2 -extern mlt_consumer consumer_gtk2_preview_init( mlt_profile profile, void *widget ); -#endif - -static void initialise( ) -{ - static int init = 0; - if ( init == 0 ) - { - init = 1; - g_type_init( ); - } -} - -void *create_service( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - initialise( ); - -#ifdef USE_GTK2 - if ( !strcmp( id, "gtk2_preview" ) ) - return consumer_gtk2_preview_init( profile, arg ); -#endif - - return NULL; -} - -static mlt_properties metadata( mlt_service_type type, const char *id, void *data ) -{ - char file[ PATH_MAX ]; - snprintf( file, PATH_MAX, "%s/gtk2/%s", mlt_environment( "MLT_DATA" ), (char*) data ); - return mlt_properties_parse_yaml( file ); -} - -MLT_REPOSITORY -{ - MLT_REGISTER( mlt_service_consumer_type, "gtk2_preview", create_service ); - - MLT_REGISTER_METADATA( mlt_service_consumer_type, "gtk2_preview", metadata, "consumer_gtk2_preview.yml" ); -} diff --git a/src/modules/qt/producer_qimage.c b/src/modules/qt/producer_qimage.c index 45693ad8d..fe5077467 100644 --- a/src/modules/qt/producer_qimage.c +++ b/src/modules/qt/producer_qimage.c @@ -1,9 +1,6 @@ /* * producer_image.c -- a QT/QImage based producer for MLT * - * NB: This module is designed to be functionally equivalent to the - * gtk2 image loading module so it can be used as replacement. - * * 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 diff --git a/src/modules/qt/qimage_wrapper.cpp b/src/modules/qt/qimage_wrapper.cpp index e022314f3..8cf5838c1 100644 --- a/src/modules/qt/qimage_wrapper.cpp +++ b/src/modules/qt/qimage_wrapper.cpp @@ -1,9 +1,6 @@ /* * qimage_wrapper.cpp -- a QT/QImage based producer for MLT * - * NB: This module is designed to be functionally equivalent to the - * gtk2 image loading module so it can be used as replacement. - * * 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 diff --git a/src/modules/qt/qimage_wrapper.h b/src/modules/qt/qimage_wrapper.h index dbc6dfe58..cfb0860e1 100644 --- a/src/modules/qt/qimage_wrapper.h +++ b/src/modules/qt/qimage_wrapper.h @@ -1,9 +1,6 @@ /* * qimage_wrapper.h -- a QT/QImage based producer for MLT * - * NB: This module is designed to be functionally equivalent to the - * gtk2 image loading module so it can be used as replacement. - * * 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 From da65d049d814bbd2eca5e2ff19fac7abe1a492cf Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 8 Feb 2021 22:11:54 -0600 Subject: [PATCH 025/122] Remove deprecated kino module --- docs/install.txt | 1 - src/framework/mlt_repository.c | 5 - src/modules/kino/Makefile | 49 - src/modules/kino/avi.cc | 1713 ------------------------------ src/modules/kino/avi.h | 330 ------ src/modules/kino/configure | 39 - src/modules/kino/deprecated | 0 src/modules/kino/endian_types.h | 280 ----- src/modules/kino/error.cc | 103 -- src/modules/kino/error.h | 51 - src/modules/kino/factory.c | 28 - src/modules/kino/filehandler.cc | 941 ---------------- src/modules/kino/filehandler.h | 217 ---- src/modules/kino/gpl | 0 src/modules/kino/kino_wrapper.cc | 108 -- src/modules/kino/kino_wrapper.h | 44 - src/modules/kino/producer_kino.c | 144 --- src/modules/kino/riff.cc | 659 ------------ src/modules/kino/riff.h | 143 --- 19 files changed, 4855 deletions(-) delete mode 100644 src/modules/kino/Makefile delete mode 100644 src/modules/kino/avi.cc delete mode 100644 src/modules/kino/avi.h delete mode 100755 src/modules/kino/configure delete mode 100644 src/modules/kino/deprecated delete mode 100644 src/modules/kino/endian_types.h delete mode 100644 src/modules/kino/error.cc delete mode 100644 src/modules/kino/error.h delete mode 100644 src/modules/kino/factory.c delete mode 100644 src/modules/kino/filehandler.cc delete mode 100644 src/modules/kino/filehandler.h delete mode 100644 src/modules/kino/gpl delete mode 100644 src/modules/kino/kino_wrapper.cc delete mode 100644 src/modules/kino/kino_wrapper.h delete mode 100644 src/modules/kino/producer_kino.c delete mode 100644 src/modules/kino/riff.cc delete mode 100644 src/modules/kino/riff.h diff --git a/docs/install.txt b/docs/install.txt index 2bff57f6b..71873d442 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -30,7 +30,6 @@ Last Revision: 2013-09-07 * gdk - GDK pango and pixbuf dependent services * jackrack - adapter for LADSPA audio plugins and JACK server * kdenlive - services contributed by Kdenlive project - * kino - DV/AVI demuxer from Kino project (*) * linsys - DVEO SDI card consumer (*) * lumas - wipe file generator for core's luma transition * motion_est - motion estimation-based filters (*) diff --git a/src/framework/mlt_repository.c b/src/framework/mlt_repository.c index a999ead64..ce73086d6 100644 --- a/src/framework/mlt_repository.c +++ b/src/framework/mlt_repository.c @@ -104,11 +104,6 @@ mlt_repository mlt_repository_init( const char *directory ) int flags = RTLD_NOW; const char *object_name = mlt_properties_get_value( dir, i); - // Very temporary hack to allow the quicktime plugins to work - // TODO: extend repository to allow this to be used on a case by case basis - if ( strstr( object_name, "libmltkino" ) ) - flags |= RTLD_GLOBAL; - // Open the shared object void *object = dlopen( object_name, flags ); if ( object != NULL ) diff --git a/src/modules/kino/Makefile b/src/modules/kino/Makefile deleted file mode 100644 index 8452dd99c..000000000 --- a/src/modules/kino/Makefile +++ /dev/null @@ -1,49 +0,0 @@ -include ../../../config.mak -include config.mak - -CFLAGS := -I../../ $(CFLAGS) -CXXFLAGS := $(CFLAGS) -Wno-deprecated $(CXXFLAGS) - -LDFLAGS := -L../../framework -lmlt -lpthread $(LDFLAGS) - -TARGET = ../libmltkino.so - -OBJS = factory.o producer_kino.o -CPPOBJS = kino_wrapper.o avi.o error.o filehandler.o riff.o - -LDFLAGS += -lstdc++ - -ifdef HAVE_LIBQUICKTIME -CFLAGS += `pkg-config --cflags libquicktime` -CXXFLAGS += `pkg-config --cflags libquicktime` -LDFLAGS += `pkg-config --libs libquicktime` -endif - -ifdef HAVE_LIBDV -CFLAGS += `pkg-config --cflags libdv` -LDFLAGS += `pkg-config --libs libdv` -endif - - -SRCS := $(OBJS:.o=.c) $(CPPOBJS:.o=.cc) - -all: $(TARGET) - -$(TARGET): $(OBJS) $(CPPOBJS) - $(CXX) -shared -o $@ $(OBJS) $(CPPOBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend config.h config.mak - -clean: - rm -f $(OBJS) $(TARGET) $(CPPOBJS) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/kino/avi.cc b/src/modules/kino/avi.cc deleted file mode 100644 index 799fb449f..000000000 --- a/src/modules/kino/avi.cc +++ /dev/null @@ -1,1713 +0,0 @@ -/* -* avi.cc library for AVI file format i/o -* Copyright (C) 2000 - 2002 Arne Schirmacher -* -* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -// C++ includes - -#include -#include -#include - -using std::cout; -using std::hex; -using std::dec; -using std::setw; -using std::setfill; -using std::endl; - -// C includes - -#include -#include -#include -#include -#include - -// local includes - -#include "error.h" -#include "riff.h" -#include "avi.h" - -#define PADDING_SIZE (512) -#define PADDING_1GB (0x40000000) -#define IX00_INDEX_SIZE (4028) - -#define AVIF_HASINDEX 0x00000010 -#define AVIF_MUSTUSEINDEX 0x00000020 -#define AVIF_TRUSTCKTYPE 0x00000800 -#define AVIF_ISINTERLEAVED 0x00000100 -#define AVIF_WASCAPTUREFILE 0x00010000 -#define AVIF_COPYRIGHTED 0x00020000 - - -//static char g_zeroes[ PADDING_SIZE ]; - -/** The constructor - - \todo mainHdr not initialized - \todo add checking for NULL pointers - -*/ - -AVIFile::AVIFile() : RIFFFile(), - idx1( NULL ), file_list( -1 ), riff_list( -1 ), - hdrl_list( -1 ), avih_chunk( -1 ), movi_list( -1 ), junk_chunk( -1 ), idx1_chunk( -1 ), - index_type( -1 ), current_ix00( -1 ), odml_list( -1 ), dmlh_chunk( -1 ), isUpdateIdx1( true ) -{ - // cerr << "0x" << hex << (long)this << dec << " AVIFile::AVIFile() : RIFFFile(), ..." << endl; - - for ( int i = 0; i < 2; ++i ) - { - indx[ i ] = new AVISuperIndex; - memset( indx[ i ], 0, sizeof( AVISuperIndex ) ); - ix[ i ] = new AVIStdIndex; - memset( ix[ i ], 0, sizeof( AVIStdIndex ) ); - indx_chunk[ i ] = -1; - ix_chunk[ i ] = -1; - strl_list[ i ] = -1; - strh_chunk[ i ] = -1; - strf_chunk[ i ] = -1; - } - idx1 = new AVISimpleIndex; - memset( idx1, 0, sizeof( AVISimpleIndex ) ); - memset( dmlh, 0, sizeof( dmlh ) ); - memset( &mainHdr, 0, sizeof( mainHdr ) ); - memset( &streamHdr, 0, sizeof( streamHdr ) ); -} - - -/** The copy constructor - - \todo add checking for NULL pointers - -*/ - -AVIFile::AVIFile( const AVIFile& avi ) : RIFFFile( avi ) -{ - // cerr << "0x" << hex << (long)this << dec << " 0x" << hex << (long)&avi << dec << " AVIFile::AVIFile(const AVIFile& avi) : RIFFFile(avi)" << endl; - - mainHdr = avi.mainHdr; - idx1 = new AVISimpleIndex; - *idx1 = *avi.idx1; - file_list = avi.file_list; - riff_list = avi.riff_list; - hdrl_list = avi.hdrl_list; - avih_chunk = avi.avih_chunk; - movi_list = avi.movi_list; - junk_chunk = avi.junk_chunk; - idx1_chunk = avi.idx1_chunk; - - for ( int i = 0; i < 2; ++i ) - { - indx[ i ] = new AVISuperIndex; - *indx[ i ] = *avi.indx[ i ]; - ix[ i ] = new AVIStdIndex; - *ix[ i ] = *avi.ix[ i ]; - indx_chunk[ i ] = avi.indx_chunk[ i ]; - ix_chunk[ i ] = avi.ix_chunk[ i ]; - strl_list[ i ] = avi.strl_list[ i ]; - strh_chunk[ i ] = avi.strh_chunk[ i ]; - strf_chunk[ i ] = avi.strf_chunk[ i ]; - } - - index_type = avi.index_type; - current_ix00 = avi.current_ix00; - - for ( int i = 0; i < 62; ++i ) - dmlh[ i ] = avi.dmlh[ i ]; - - isUpdateIdx1 = avi.isUpdateIdx1; - - odml_list = 0; - dmlh_chunk = 0; - memset( &streamHdr, 0, sizeof( streamHdr ) ); -} - - -/** The assignment operator - -*/ - -AVIFile& AVIFile::operator=( const AVIFile& avi ) -{ - // cerr << "0x" << hex << (long)this << dec << " 0x" << hex << (long)&avi << dec << " AVIFile& AVIFile::operator=(const AVIFile& avi)" << endl; - - if ( this != &avi ) - { - RIFFFile::operator=( avi ); - mainHdr = avi.mainHdr; - *idx1 = *avi.idx1; - file_list = avi.file_list; - riff_list = avi.riff_list; - hdrl_list = avi.hdrl_list; - avih_chunk = avi.avih_chunk; - movi_list = avi.movi_list; - junk_chunk = avi.junk_chunk; - idx1_chunk = avi.idx1_chunk; - - for ( int i = 0; i < 2; ++i ) - { - *indx[ i ] = *avi.indx[ i ]; - *ix[ i ] = *avi.ix[ i ]; - indx_chunk[ i ] = avi.indx_chunk[ i ]; - ix_chunk[ i ] = avi.ix_chunk[ i ]; - strl_list[ i ] = avi.strl_list[ i ]; - strh_chunk[ i ] = avi.strh_chunk[ i ]; - strf_chunk[ i ] = avi.strf_chunk[ i ]; - } - - index_type = avi.index_type; - current_ix00 = avi.current_ix00; - - for ( int i = 0; i < 62; ++i ) - dmlh[ i ] = avi.dmlh[ i ]; - - isUpdateIdx1 = avi.isUpdateIdx1; - } - return *this; -} - - -/** The destructor - -*/ - -AVIFile::~AVIFile() -{ - // cerr << "0x" << hex << (long)this << dec << " AVIFile::~AVIFile()" << endl; - - for ( int i = 0; i < 2; ++i ) - { - delete ix[ i ]; - delete indx[ i ]; - } - delete idx1; -} - -/** Initialize the AVI structure to its initial state, either for PAL or NTSC format - - Initialize the AVIFile attributes: mainHdr, indx, ix00, idx1 - - \todo consolidate AVIFile::Init, AVI1File::Init, AVI2File::Init. They are somewhat redundant. - \param format pass AVI_PAL or AVI_NTSC - \param sampleFrequency the sample frequency of the audio content - \param indexType pass AVI_SMALL_INDEX or AVI_LARGE_INDEX - -*/ - -void AVIFile::Init( int format, int sampleFrequency, int indexType ) -{ - int i, j; - - assert( ( format == AVI_PAL ) || ( format == AVI_NTSC ) ); - - index_type = indexType; - - switch ( format ) - { - case AVI_PAL: - mainHdr.dwMicroSecPerFrame = 40000; - mainHdr.dwSuggestedBufferSize = 144008; - break; - - case AVI_NTSC: - mainHdr.dwMicroSecPerFrame = 33366; - mainHdr.dwSuggestedBufferSize = 120008; - break; - - default: /* no default allowed */ - assert( 0 ); - break; - } - - /* Initialize the 'avih' chunk */ - - mainHdr.dwMaxBytesPerSec = 3600000 + sampleFrequency * 4; - mainHdr.dwPaddingGranularity = PADDING_SIZE; - mainHdr.dwFlags = AVIF_TRUSTCKTYPE; - if ( indexType & AVI_SMALL_INDEX ) - mainHdr.dwFlags |= AVIF_HASINDEX; - mainHdr.dwTotalFrames = 0; - mainHdr.dwInitialFrames = 0; - mainHdr.dwStreams = 1; - mainHdr.dwWidth = 0; - mainHdr.dwHeight = 0; - mainHdr.dwReserved[ 0 ] = 0; - mainHdr.dwReserved[ 1 ] = 0; - mainHdr.dwReserved[ 2 ] = 0; - mainHdr.dwReserved[ 3 ] = 0; - - /* Initialize the 'idx1' chunk */ - - for ( int i = 0; i < 8000; ++i ) - { - idx1->aIndex[ i ].dwChunkId = 0; - idx1->aIndex[ i ].dwFlags = 0; - idx1->aIndex[ i ].dwOffset = 0; - idx1->aIndex[ i ].dwSize = 0; - } - idx1->nEntriesInUse = 0; - - /* Initialize the 'indx' chunk */ - - for ( i = 0; i < 2; ++i ) - { - indx[ i ] ->wLongsPerEntry = 4; - indx[ i ] ->bIndexSubType = 0; - indx[ i ] ->bIndexType = KINO_AVI_INDEX_OF_INDEXES; - indx[ i ] ->nEntriesInUse = 0; - indx[ i ] ->dwReserved[ 0 ] = 0; - indx[ i ] ->dwReserved[ 1 ] = 0; - indx[ i ] ->dwReserved[ 2 ] = 0; - for ( j = 0; j < 2014; ++j ) - { - indx[ i ] ->aIndex[ j ].qwOffset = 0; - indx[ i ] ->aIndex[ j ].dwSize = 0; - indx[ i ] ->aIndex[ j ].dwDuration = 0; - } - } - - /* The ix00 and ix01 chunk will be added dynamically in avi_write_frame - as needed */ - - /* Initialize the 'dmlh' chunk. I have no clue what this means - though */ - - for ( i = 0; i < 62; ++i ) - dmlh[ i ] = 0; - //dmlh[0] = -1; /* frame count + 1? */ - -} - - -/** Find position and size of a given frame in the file - - Depending on which index is available, search one of them to - find position and frame size - - \todo the size parameter is redundant. All frames have the same size, which is also in the mainHdr. - \todo all index related operations should be isolated - \param offset the file offset to the start of the frame - \param size the size of the frame - \param frameNum the number of the frame we wish to find - \return 0 if the frame could be found, -1 otherwise -*/ - -int AVIFile::GetDVFrameInfo( off_t &offset, int &size, int frameNum ) -{ - switch ( index_type ) - { - case AVI_LARGE_INDEX: - - /* find relevant index in indx0 */ - - int i; - - for ( i = 0; frameNum >= indx[ 0 ] ->aIndex[ i ].dwDuration; frameNum -= indx[ 0 ] ->aIndex[ i ].dwDuration, ++i ) - ; - - if ( i != current_ix00 ) - { - fail_if( lseek( fd, indx[ 0 ] ->aIndex[ i ].qwOffset + RIFF_HEADERSIZE, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, ix[ 0 ], indx[ 0 ] ->aIndex[ i ].dwSize - RIFF_HEADERSIZE ) ); - current_ix00 = i; - } - - if ( frameNum < ix[ 0 ] ->nEntriesInUse ) - { - offset = ix[ 0 ] ->qwBaseOffset + ix[ 0 ] ->aIndex[ frameNum ].dwOffset; - size = ix[ 0 ] ->aIndex[ frameNum ].dwSize; - return 0; - } - else - return -1; - break; - - case AVI_SMALL_INDEX: - int index = -1; - int frameNumIndex = 0; - for ( int i = 0; i < idx1->nEntriesInUse; ++i ) - { - FOURCC chunkID1 = make_fourcc( "00dc" ); - FOURCC chunkID2 = make_fourcc( "00db" ); - if ( idx1->aIndex[ i ].dwChunkId == chunkID1 || - idx1->aIndex[ i ].dwChunkId == chunkID2 ) - { - if ( frameNumIndex == frameNum ) - { - index = i; - break; - } - ++frameNumIndex; - } - } - if ( index != -1 ) - { - // compatibility check for broken dvgrab dv2 format - if ( idx1->aIndex[ 0 ].dwOffset > GetDirectoryEntry( movi_list ).offset ) - { - offset = idx1->aIndex[ index ].dwOffset + RIFF_HEADERSIZE; - } - else - { - // new, correct dv2 format - offset = idx1->aIndex[ index ].dwOffset + RIFF_HEADERSIZE + GetDirectoryEntry( movi_list ).offset; - } - size = idx1->aIndex[ index ].dwSize; - return 0; - } - else - return -1; - break; - } - return -1; -} - -/** Find position and size of a given frame in the file - - Depending on which index is available, search one of them to - find position and frame size - - \todo the size parameter is redundant. All frames have the same size, which is also in the mainHdr. - \todo all index related operations should be isolated - \param offset the file offset to the start of the frame - \param size the size of the frame - \param frameNum the number of the frame we wish to find - \param chunkID the ID of the type of chunk we want - \return 0 if the frame could be found, -1 otherwise -*/ - -int AVIFile::GetFrameInfo( off_t &offset, int &size, int frameNum, FOURCC chunkID ) -{ - if ( index_type & AVI_LARGE_INDEX ) - { - int i; - - for ( i = 0; frameNum >= indx[ 0 ] ->aIndex[ i ].dwDuration; frameNum -= indx[ 0 ] ->aIndex[ i ].dwDuration, ++i ) - ; - - if ( i != current_ix00 ) - { - fail_if( lseek( fd, indx[ 0 ] ->aIndex[ i ].qwOffset + RIFF_HEADERSIZE, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, ix[ 0 ], indx[ 0 ] ->aIndex[ i ].dwSize - RIFF_HEADERSIZE ) ); - current_ix00 = i; - } - - if ( frameNum < ix[ 0 ] ->nEntriesInUse ) - { - if ( ( FOURCC ) ix[ 0 ] ->dwChunkId == chunkID ) - { - offset = ix[ 0 ] ->qwBaseOffset + ix[ 0 ] ->aIndex[ frameNum ].dwOffset; - size = ix[ 0 ] ->aIndex[ frameNum ].dwSize; - return 0; - } - } - } - if ( index_type & AVI_SMALL_INDEX ) - { - int index = -1; - int frameNumIndex = 0; - for ( int i = 0; i < idx1->nEntriesInUse; ++i ) - { - if ( idx1->aIndex[ i ].dwChunkId == chunkID ) - { - if ( frameNumIndex == frameNum ) - { - index = i; - break; - } - ++frameNumIndex; - } - } - if ( index != -1 ) - { - // compatibility check for broken dvgrab dv2 format - if ( idx1->aIndex[ 0 ].dwOffset > GetDirectoryEntry( movi_list ).offset ) - { - offset = idx1->aIndex[ index ].dwOffset + RIFF_HEADERSIZE; - } - else - { - // new, correct dv2 format - offset = idx1->aIndex[ index ].dwOffset + RIFF_HEADERSIZE + GetDirectoryEntry( movi_list ).offset; - } - size = idx1->aIndex[ index ].dwSize; - return 0; - } - } - return -1; -} - -/** Read in a frame - - \todo we actually don't need the frame here, we could use just a void pointer - \param frame a reference to the frame object that will receive the frame data - \param frameNum the frame number to read - \return 0 if the frame could be read, -1 otherwise -*/ - -int AVIFile::GetDVFrame( uint8_t *data, int frameNum ) -{ - off_t offset; - int size; - - if ( GetDVFrameInfo( offset, size, frameNum ) != 0 || size < 0 ) - return -1; - pthread_mutex_lock( &file_mutex ); - fail_if( lseek( fd, offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, data, size ) ); - pthread_mutex_unlock( &file_mutex ); - - return 0; -} - -/** Read in a frame - - \param data a pointer to the audio buffer - \param frameNum the frame number to read - \param chunkID the ID of the type of chunk we want - \return the size the of the frame data, 0 if could not be read -*/ - -int AVIFile::getFrame( void *data, int frameNum, FOURCC chunkID ) -{ - off_t offset; - int size; - - if ( GetFrameInfo( offset, size, frameNum, chunkID ) != 0 ) - return 0; - fail_if( lseek( fd, offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, data, size ) ); - - return size; -} - -int AVIFile::GetTotalFrames() const -{ - return mainHdr.dwTotalFrames; -} - - -/** prints out a directory entry in text form - - Every subclass of RIFFFile is supposed to override this function - and to implement it for the entry types it knows about. For all - other entry types it should call its parent::PrintDirectoryData. - - \todo use 64 bit routines - \param entry the entry to print -*/ - -void AVIFile::PrintDirectoryEntryData( const RIFFDirEntry &entry ) const -{ - static FOURCC lastStreamType = make_fourcc( " " ); - - if ( entry.type == make_fourcc( "avih" ) ) - { - - int i; - MainAVIHeader main_avi_header; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &main_avi_header, sizeof( MainAVIHeader ) ) ); - - cout << " dwMicroSecPerFrame: " << ( int ) main_avi_header.dwMicroSecPerFrame << endl - << " dwMaxBytesPerSec: " << ( int ) main_avi_header.dwMaxBytesPerSec << endl - << " dwPaddingGranularity: " << ( int ) main_avi_header.dwPaddingGranularity << endl - << " dwFlags: " << ( int ) main_avi_header.dwFlags << endl - << " dwTotalFrames: " << ( int ) main_avi_header.dwTotalFrames << endl - << " dwInitialFrames: " << ( int ) main_avi_header.dwInitialFrames << endl - << " dwStreams: " << ( int ) main_avi_header.dwStreams << endl - << " dwSuggestedBufferSize: " << ( int ) main_avi_header.dwSuggestedBufferSize << endl - << " dwWidth: " << ( int ) main_avi_header.dwWidth << endl - << " dwHeight: " << ( int ) main_avi_header.dwHeight << endl; - for ( i = 0; i < 4; ++i ) - cout << " dwReserved[" << i << "]: " << ( int ) main_avi_header.dwReserved[ i ] << endl; - - } - else if ( entry.type == make_fourcc( "strh" ) ) - { - - AVIStreamHeader avi_stream_header; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &avi_stream_header, sizeof( AVIStreamHeader ) ) ); - - lastStreamType = avi_stream_header.fccType; - - cout << " fccType: '" - << ((char *)&avi_stream_header.fccType)[0] - << ((char *)&avi_stream_header.fccType)[1] - << ((char *)&avi_stream_header.fccType)[2] - << ((char *)&avi_stream_header.fccType)[3] - << '\'' << endl - << " fccHandler: '" - << ((char *)&avi_stream_header.fccHandler)[0] - << ((char *)&avi_stream_header.fccHandler)[1] - << ((char *)&avi_stream_header.fccHandler)[2] - << ((char *)&avi_stream_header.fccHandler)[3] - << '\'' << endl - << " dwFlags: " << ( int ) avi_stream_header.dwFlags << endl - << " wPriority: " << ( int ) avi_stream_header.wPriority << endl - << " wLanguage: " << ( int ) avi_stream_header.wLanguage << endl - << " dwInitialFrames: " << ( int ) avi_stream_header.dwInitialFrames << endl - << " dwScale: " << ( int ) avi_stream_header.dwScale << endl - << " dwRate: " << ( int ) avi_stream_header.dwRate << endl - << " dwLength: " << ( int ) avi_stream_header.dwLength << endl - << " dwQuality: " << ( int ) avi_stream_header.dwQuality << endl - << " dwSampleSize: " << ( int ) avi_stream_header.dwSampleSize << endl; - - } - else if ( entry.type == make_fourcc( "indx" ) ) - { - - int i; - AVISuperIndex avi_super_index; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &avi_super_index, sizeof( AVISuperIndex ) ) ); - - cout << " wLongsPerEntry: " << ( int ) avi_super_index.wLongsPerEntry - << endl - << " bIndexSubType: " << ( int ) avi_super_index.bIndexSubType << endl - << " bIndexType: " << ( int ) avi_super_index.bIndexType << endl - << " nEntriesInUse: " << ( int ) avi_super_index.nEntriesInUse << endl - << " dwChunkId: '" - << ((char *)&avi_super_index.dwChunkId)[0] - << ((char *)&avi_super_index.dwChunkId)[1] - << ((char *)&avi_super_index.dwChunkId)[2] - << ((char *)&avi_super_index.dwChunkId)[3] - << '\'' << endl - << " dwReserved[0]: " << ( int ) avi_super_index.dwReserved[ 0 ] << endl - << " dwReserved[1]: " << ( int ) avi_super_index.dwReserved[ 1 ] << endl - << " dwReserved[2]: " << ( int ) avi_super_index.dwReserved[ 2 ] << endl; - for ( i = 0; i < avi_super_index.nEntriesInUse; ++i ) - { - cout << ' ' << setw( 4 ) << setfill( ' ' ) << i - << ": qwOffset : 0x" << setw( 12 ) << setfill( '0' ) << hex << avi_super_index.aIndex[ i ].qwOffset << endl - << " dwSize : 0x" << setw( 8 ) << avi_super_index.aIndex[ i ].dwSize << endl - << " dwDuration : " << dec << avi_super_index.aIndex[ i ].dwDuration << endl; - } - } - else if ( entry.type == make_fourcc( "strf" ) ) - { - if ( lastStreamType == make_fourcc( "auds" ) ) - { - WAVEFORMATEX waveformatex; - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &waveformatex, sizeof( WAVEFORMATEX ) ) ); - cout << " waveformatex.wFormatTag : " << waveformatex.wFormatTag << endl; - cout << " waveformatex.nChannels : " << waveformatex.nChannels << endl; - cout << " waveformatex.nSamplesPerSec : " << waveformatex.nSamplesPerSec << endl; - cout << " waveformatex.nAvgBytesPerSec: " << waveformatex.nAvgBytesPerSec << endl; - cout << " waveformatex.nBlockAlign : " << waveformatex.nBlockAlign << endl; - cout << " waveformatex.wBitsPerSample : " << waveformatex.wBitsPerSample << endl; - cout << " waveformatex.cbSize : " << waveformatex.cbSize << endl; - } - else if ( lastStreamType == make_fourcc( "vids" ) ) - { - BITMAPINFOHEADER bitmapinfo; - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &bitmapinfo, sizeof( BITMAPINFOHEADER ) ) ); - cout << " bitmapinfo.biSize : " << bitmapinfo.biSize << endl; - cout << " bitmapinfo.biWidth : " << bitmapinfo.biWidth << endl; - cout << " bitmapinfo.biHeight : " << bitmapinfo.biHeight << endl; - cout << " bitmapinfo.biPlanes : " << bitmapinfo.biPlanes << endl; - cout << " bitmapinfo.biBitCount : " << bitmapinfo.biBitCount << endl; - cout << " bitmapinfo.biCompression : " << bitmapinfo.biCompression << endl; - cout << " bitmapinfo.biSizeImage : " << bitmapinfo.biSizeImage << endl; - cout << " bitmapinfo.biXPelsPerMeter: " << bitmapinfo.biXPelsPerMeter << endl; - cout << " bitmapinfo.biYPelsPerMeter: " << bitmapinfo.biYPelsPerMeter << endl; - cout << " bitmapinfo.biClrUsed : " << bitmapinfo.biClrUsed << endl; - cout << " bitmapinfo.biClrImportant : " << bitmapinfo.biClrImportant << endl; - } - else if ( lastStreamType == make_fourcc( "iavs" ) ) - { - DVINFO dvinfo; - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &dvinfo, sizeof( DVINFO ) ) ); - cout << " dvinfo.dwDVAAuxSrc : 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVAAuxSrc << endl; - cout << " dvinfo.dwDVAAuxCtl : 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVAAuxCtl << endl; - cout << " dvinfo.dwDVAAuxSrc1: 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVAAuxSrc1 << endl; - cout << " dvinfo.dwDVAAuxCtl1: 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVAAuxCtl1 << endl; - cout << " dvinfo.dwDVVAuxSrc : 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVVAuxSrc << endl; - cout << " dvinfo.dwDVVAuxCtl : 0x" << setw( 8 ) << setfill( '0' ) << hex << dvinfo.dwDVVAuxCtl << endl; - } - } - - /* This is the Standard Index. It is an array of offsets and - sizes relative to some start offset. */ - - else if ( ( entry.type == make_fourcc( "ix00" ) ) || ( entry.type == make_fourcc( "ix01" ) ) ) - { - - int i; - AVIStdIndex avi_std_index; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, &avi_std_index, sizeof( AVIStdIndex ) ) ); - - cout << " wLongsPerEntry: " << ( int ) avi_std_index.wLongsPerEntry - << endl - << " bIndexSubType: " << ( int ) avi_std_index.bIndexSubType << endl - << " bIndexType: " << ( int ) avi_std_index.bIndexType << endl - << " nEntriesInUse: " << ( int ) avi_std_index.nEntriesInUse << endl - << " dwChunkId: '" - << ((char *)&avi_std_index.dwChunkId)[0] - << ((char *)&avi_std_index.dwChunkId)[1] - << ((char *)&avi_std_index.dwChunkId)[2] - << ((char *)&avi_std_index.dwChunkId)[3] - << '\'' << endl - << " qwBaseOffset: 0x" << setw( 12 ) << hex << avi_std_index.qwBaseOffset << endl - << " dwReserved: " << dec << ( int ) avi_std_index.dwReserved << endl; - for ( i = 0; i < avi_std_index.nEntriesInUse; ++i ) - { - cout << ' ' << setw( 4 ) << setfill( ' ' ) << i - << ": dwOffset : 0x" << setw( 8 ) << setfill( '0' ) << hex << avi_std_index.aIndex[ i ].dwOffset - << " (0x" << setw( 12 ) << avi_std_index.qwBaseOffset + avi_std_index.aIndex[ i ].dwOffset << ')' << endl - << " dwSize : 0x" << setw( 8 ) << avi_std_index.aIndex[ i ].dwSize << dec << endl; - } - - } - else if ( entry.type == make_fourcc( "idx1" ) ) - { - - int i; - int numEntries = entry.length / sizeof( int ) / 4; - DWORD *idx1 = new DWORD[ numEntries * 4 ]; - // FOURCC movi_list = FindDirectoryEntry(make_fourcc("movi")); - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, idx1, entry.length ) ); - - for ( i = 0; i < numEntries; ++i ) - { - - cout << ' ' << setw( 4 ) << setfill( ' ' ) << i << setfill( '0' ) << ": dwChunkId : '" - << ((char *)&idx1[ i * 4 + 0 ])[0] - << ((char *)&idx1[ i * 4 + 0 ])[1] - << ((char *)&idx1[ i * 4 + 0 ])[2] - << ((char *)&idx1[ i * 4 + 0 ])[3] - << '\'' << endl - << " dwType : 0x" << setw( 8 ) << hex << idx1[ i * 4 + 1 ] << endl - << " dwOffset : 0x" << setw( 8 ) << idx1[ i * 4 + 2 ] << endl - // << " (0x" << setw(8) << idx1[i * 4 + 2] + GetDirectoryEntry(movi_list).offset << ')' << endl - << " dwSize : 0x" << setw( 8 ) << idx1[ i * 4 + 3 ] << dec << endl; - } - - delete[] idx1; - } - else if ( entry.type == make_fourcc( "dmlh" ) ) - { - int i; - int numEntries = entry.length / sizeof( int ); - DWORD *dmlh = new DWORD[ numEntries ]; - - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, dmlh, entry.length ) ); - - for ( i = 0; i < numEntries; ++i ) - { - cout << ' ' << setw( 4 ) << setfill( ' ' ) << i << setfill( '0' ) << ": " - << " dwTotalFrames: 0x" << setw( 8 ) << hex << dmlh[ i ] - << " (" << dec << dmlh[ i ] << ")" << endl; - } - delete[] dmlh; - } -} - - -/** If this is not a movi list, read its contents - -*/ - -void AVIFile::ParseList( int parent ) -{ - FOURCC type; - FOURCC name; - DWORD length; - int list; - off_t pos; - off_t listEnd; - - /* Read in the chunk header (type and length). */ - fail_neg( read( fd, &type, sizeof( type ) ) ); - fail_neg( read( fd, &length, sizeof( length ) ) ); - if ( length & 1 ) - length++; - - /* The contents of the list starts here. Obtain its offset. The list - name (4 bytes) is already part of the contents). */ - - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - fail_neg( read( fd, &name, sizeof( name ) ) ); - - /* if we encounter a movi list, do not read it. It takes too much time - and we don't need it anyway. */ - - if ( name != make_fourcc( "movi" ) ) - { - // if (1) { - - /* Add an entry for this list. */ - list = AddDirectoryEntry( type, name, sizeof( name ), parent ); - - /* Read in any chunks contained in this list. This list is the - parent for all chunks it contains. */ - - listEnd = pos + length; - while ( pos < listEnd ) - { - ParseChunk( list ); - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - } - } - else - { - /* Add an entry for this list. */ - - movi_list = AddDirectoryEntry( type, name, length, parent ); - - pos = lseek( fd, length - 4, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - } -} - - -void AVIFile::ParseRIFF() -{ - RIFFFile::ParseRIFF(); - - avih_chunk = FindDirectoryEntry( make_fourcc( "avih" ) ); - if ( avih_chunk != -1 ) - ReadChunk( avih_chunk, ( void* ) & mainHdr, sizeof( MainAVIHeader ) ); -} - - -void AVIFile::ReadIndex() -{ - indx_chunk[ 0 ] = FindDirectoryEntry( make_fourcc( "indx" ) ); - if ( indx_chunk[ 0 ] != -1 ) - { - ReadChunk( indx_chunk[ 0 ], ( void* ) indx[ 0 ], sizeof( AVISuperIndex ) ); - index_type = AVI_LARGE_INDEX; - - /* recalc number of frames from each index */ - mainHdr.dwTotalFrames = 0; - for ( int i = 0; - i < indx[ 0 ] ->nEntriesInUse; - mainHdr.dwTotalFrames += indx[ 0 ] ->aIndex[ i++ ].dwDuration ) - ; - return ; - } - idx1_chunk = FindDirectoryEntry( make_fourcc( "idx1" ) ); - if ( idx1_chunk != -1 ) - { - ReadChunk( idx1_chunk, ( void* ) idx1, sizeof( AVISuperIndex ) ); - idx1->nEntriesInUse = GetDirectoryEntry( idx1_chunk ).length / 16; - index_type = AVI_SMALL_INDEX; - - /* recalc number of frames from the simple index */ - int frameNumIndex = 0; - FOURCC chunkID1 = make_fourcc( "00dc" ); - FOURCC chunkID2 = make_fourcc( "00db" ); - for ( int i = 0; i < idx1->nEntriesInUse; ++i ) - { - if ( idx1->aIndex[ i ].dwChunkId == chunkID1 || - idx1->aIndex[ i ].dwChunkId == chunkID2 ) - { - ++frameNumIndex; - } - } - mainHdr.dwTotalFrames = frameNumIndex; - return ; - } -} - - -void AVIFile::FlushIndx( int stream ) -{ - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - int i; - - /* Write out the previous index. When this function is - entered for the first time, there is no index to - write. Note: this may be an expensive operation - because of a time consuming seek to the former file - position. */ - - if ( ix_chunk[ stream ] != -1 ) - WriteChunk( ix_chunk[ stream ], ix[ stream ] ); - - /* make a new ix chunk. */ - - if ( stream == 0 ) - type = make_fourcc( "ix00" ); - else - type = make_fourcc( "ix01" ); - ix_chunk[ stream ] = AddDirectoryEntry( type, 0, sizeof( AVIStdIndex ), movi_list ); - GetDirectoryEntry( ix_chunk[ stream ], type, name, length, offset, parent ); - - /* fill out all required fields. The offsets in the - array are relative to qwBaseOffset, so fill in the - offset to the next free location in the file - there. */ - - ix[ stream ] ->wLongsPerEntry = 2; - ix[ stream ] ->bIndexSubType = 0; - ix[ stream ] ->bIndexType = KINO_AVI_INDEX_OF_CHUNKS; - ix[ stream ] ->nEntriesInUse = 0; - ix[ stream ] ->dwChunkId = indx[ stream ] ->dwChunkId; - ix[ stream ] ->qwBaseOffset = offset + length; - ix[ stream ] ->dwReserved = 0; - - for ( i = 0; i < IX00_INDEX_SIZE; ++i ) - { - ix[ stream ] ->aIndex[ i ].dwOffset = 0; - ix[ stream ] ->aIndex[ i ].dwSize = 0; - } - - /* add a reference to this new index in our super - index. */ - - i = indx[ stream ] ->nEntriesInUse++; - indx[ stream ] ->aIndex[ i ].qwOffset = offset - RIFF_HEADERSIZE; - indx[ stream ] ->aIndex[ i ].dwSize = length + RIFF_HEADERSIZE; - indx[ stream ] ->aIndex[ i ].dwDuration = 0; -} - - -void AVIFile::UpdateIndx( int stream, int chunk, int duration ) -{ - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - int i; - - /* update the appropriate entry in the super index. It reflects - the number of frames in the referenced index. */ - - i = indx[ stream ] ->nEntriesInUse - 1; - indx[ stream ] ->aIndex[ i ].dwDuration += duration; - - /* update the standard index. Calculate the file position of - the new frame. */ - - GetDirectoryEntry( chunk, type, name, length, offset, parent ); - - indx[ stream ] ->dwChunkId = type; - i = ix[ stream ] ->nEntriesInUse++; - ix[ stream ] ->aIndex[ i ].dwOffset = offset - ix[ stream ] ->qwBaseOffset; - ix[ stream ] ->aIndex[ i ].dwSize = length; -} - - -void AVIFile::UpdateIdx1( int chunk, int flags ) -{ - if ( idx1->nEntriesInUse < 20000 ) - { - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - GetDirectoryEntry( chunk, type, name, length, offset, parent ); - - idx1->aIndex[ idx1->nEntriesInUse ].dwChunkId = type; - idx1->aIndex[ idx1->nEntriesInUse ].dwFlags = flags; - idx1->aIndex[ idx1->nEntriesInUse ].dwOffset = offset - GetDirectoryEntry( movi_list ).offset - RIFF_HEADERSIZE; - idx1->aIndex[ idx1->nEntriesInUse ].dwSize = length; - idx1->nEntriesInUse++; - } -} - -bool AVIFile::verifyStreamFormat( FOURCC type ) -{ - int i, j = 0; - AVIStreamHeader avi_stream_header; - BITMAPINFOHEADER bih; - FOURCC strh = make_fourcc( "strh" ); - FOURCC strf = make_fourcc( "strf" ); - - while ( ( i = FindDirectoryEntry( strh, j++ ) ) != -1 ) - { - ReadChunk( i, ( void* ) & avi_stream_header, sizeof( AVIStreamHeader ) ); - if ( avi_stream_header.fccHandler == type ) - return true; - } - j = 0; - while ( ( i = FindDirectoryEntry( strf, j++ ) ) != -1 ) - { - ReadChunk( i, ( void* ) & bih, sizeof( BITMAPINFOHEADER ) ); - if ( ( FOURCC ) bih.biCompression == type ) - return true; - } - - return false; -} - -bool AVIFile::verifyStream( FOURCC type ) -{ - int i, j = 0; - AVIStreamHeader avi_stream_header; - FOURCC strh = make_fourcc( "strh" ); - - while ( ( i = FindDirectoryEntry( strh, j++ ) ) != -1 ) - { - ReadChunk( i, ( void* ) & avi_stream_header, sizeof( AVIStreamHeader ) ); - if ( avi_stream_header.fccType == type ) - return true; - } - return false; -} - -bool AVIFile::isOpenDML( void ) -{ - int i, j = 0; - FOURCC dmlh = make_fourcc( "dmlh" ); - - while ( ( i = FindDirectoryEntry( dmlh, j++ ) ) != -1 ) - { - return true; - } - return false; -} - -AVI1File::AVI1File() : AVIFile() -{ - memset( &dvinfo, 0, sizeof( dvinfo ) ); -} - - -AVI1File::~AVI1File() -{} - - -/* Initialize the AVI structure to its initial state, either for PAL - or NTSC format */ - -void AVI1File::Init( int format, int sampleFrequency, int indexType ) -{ - int num_blocks; - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - assert( ( format == AVI_PAL ) || ( format == AVI_NTSC ) ); - - AVIFile::Init( format, sampleFrequency, indexType ); - - switch ( format ) - { - case AVI_PAL: - mainHdr.dwWidth = 720; - mainHdr.dwHeight = 576; - - streamHdr[ 0 ].dwScale = 1; - streamHdr[ 0 ].dwRate = 25; - streamHdr[ 0 ].dwSuggestedBufferSize = 144008; - - /* initialize the 'strf' chunk */ - - /* Meaning of the DV stream format chunk per Microsoft - dwDVAAuxSrc - Specifies the Audio Auxiliary Data Source Pack for the first audio block - (first 5 DV DIF sequences for 525-60 systems or 6 DV DIF sequences for 625-50 systems) of - a frame. A DIF sequence is a data block that contains 150 DIF blocks. A DIF block consists - of 80 bytes. The Audio Auxiliary Data Source Pack is defined in section D.7.1 of Part 2, - Annex D, "The Pack Header Table and Contents of Packs" of the Specification of - Consumer-use Digital VCRs. - dwDVAAuxCtl - Specifies the Audio Auxiliary Data Source Control Pack for the first audio block of a - frame. The Audio Auxiliary Data Control Pack is defined in section D.7.2 of Part 2, - Annex D, "The Pack Header Table and Contents of Packs" of the Specification of - Consumer-use Digital VCRs. - dwDVAAuxSrc1 - Specifies the Audio Auxiliary Data Source Pack for the second audio block - (second 5 DV DIF sequences for 525-60 systems or 6 DV DIF sequences for 625-50 systems) of a frame. - dwDVAAuxCtl1 - Specifies the Audio Auxiliary Data Source Control Pack for the second audio block of a frame. - dwDVVAuxSrc - Specifies the Video Auxiliary Data Source Pack as defined in section D.8.1 of Part 2, - Annex D, "The Pack Header Table and Contents of Packs" of the Specification of - Consumer-use Digital VCRs. - dwDVVAuxCtl - Specifies the Video Auxiliary Data Source Control Pack as defined in section D.8.2 of Part 2, - Annex D, "The Pack Header Table and Contents of Packs" of the Specification of - Consumer-use Digital VCRs. - dwDVReserved[2] - Reserved. Set this array to zero. - */ - - dvinfo.dwDVAAuxSrc = 0xd1e030d0; - dvinfo.dwDVAAuxCtl = 0xffa0cf3f; - dvinfo.dwDVAAuxSrc1 = 0xd1e03fd0; - dvinfo.dwDVAAuxCtl1 = 0xffa0cf3f; - dvinfo.dwDVVAuxSrc = 0xff20ffff; - dvinfo.dwDVVAuxCtl = 0xfffdc83f; - dvinfo.dwDVReserved[ 0 ] = 0; - dvinfo.dwDVReserved[ 1 ] = 0; - break; - - case AVI_NTSC: - mainHdr.dwWidth = 720; - mainHdr.dwHeight = 480; - - streamHdr[ 0 ].dwScale = 1001; - streamHdr[ 0 ].dwRate = 30000; - streamHdr[ 0 ].dwSuggestedBufferSize = 120008; - - /* initialize the 'strf' chunk */ - dvinfo.dwDVAAuxSrc = 0xc0c000c0; - dvinfo.dwDVAAuxCtl = 0xffa0cf3f; - dvinfo.dwDVAAuxSrc1 = 0xc0c001c0; - dvinfo.dwDVAAuxCtl1 = 0xffa0cf3f; - dvinfo.dwDVVAuxSrc = 0xff80ffff; - dvinfo.dwDVVAuxCtl = 0xfffcc83f; - dvinfo.dwDVReserved[ 0 ] = 0; - dvinfo.dwDVReserved[ 1 ] = 0; - break; - - default: /* no default allowed */ - assert( 0 ); - break; - } - - indx[ 0 ] ->dwChunkId = make_fourcc( "00__" ); - - /* Initialize the 'strh' chunk */ - - streamHdr[ 0 ].fccType = make_fourcc( "iavs" ); - streamHdr[ 0 ].fccHandler = make_fourcc( "dvsd" ); - streamHdr[ 0 ].dwFlags = 0; - streamHdr[ 0 ].wPriority = 0; - streamHdr[ 0 ].wLanguage = 0; - streamHdr[ 0 ].dwInitialFrames = 0; - streamHdr[ 0 ].dwStart = 0; - streamHdr[ 0 ].dwLength = 0; - streamHdr[ 0 ].dwQuality = 0; - streamHdr[ 0 ].dwSampleSize = 0; - streamHdr[ 0 ].rcFrame.top = 0; - streamHdr[ 0 ].rcFrame.bottom = 0; - streamHdr[ 0 ].rcFrame.left = 0; - streamHdr[ 0 ].rcFrame.right = 0; - - /* This is a simple directory structure setup. For details see the - "OpenDML AVI File Format Extensions" document. - - An AVI file contains basically two types of objects, a - "chunk" and a "list" object. The list object contains any - number of chunks. Since a list is also a chunk, it is - possible to create a hierarchical "list of lists" - structure. - - Every AVI file starts with a "RIFF" object, which is a list - of several other required objects. The actual DV data is - contained in a "movi" list, each frame is in its own chunk. - - Old AVI files (pre OpenDML V. 1.02) contain only one RIFF - chunk of less than 1 GByte size per file. The current - format which allow for almost arbitrary sizes can contain - several RIFF chunks of less than 1 GByte size. Old software - however would only deal with the first RIFF chunk. - - Note that the first entry (FILE) isn�t actually part - of the AVI file. I use this (pseudo-) directory entry to - keep track of the RIFF chunks and their positions in the - AVI file. - */ - - /* Create the container directory entry */ - - file_list = AddDirectoryEntry( make_fourcc( "FILE" ), make_fourcc( "FILE" ), 0, RIFF_NO_PARENT ); - - /* Create a basic directory structure. Only chunks defined from here on will be written to the AVI file. */ - - riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVI " ), RIFF_LISTSIZE, file_list ); - hdrl_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "hdrl" ), RIFF_LISTSIZE, riff_list ); - avih_chunk = AddDirectoryEntry( make_fourcc( "avih" ), 0, sizeof( MainAVIHeader ), hdrl_list ); - strl_list[ 0 ] = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "strl" ), RIFF_LISTSIZE, hdrl_list ); - strh_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strh" ), 0, sizeof( AVIStreamHeader ), strl_list[ 0 ] ); - strf_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strf" ), 0, sizeof( dvinfo ), strl_list[ 0 ] ); - if ( index_type & AVI_LARGE_INDEX ) - indx_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "indx" ), 0, sizeof( AVISuperIndex ), strl_list[ 0 ] ); - - odml_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "odml" ), RIFF_LISTSIZE, hdrl_list ); - dmlh_chunk = AddDirectoryEntry( make_fourcc( "dmlh" ), 0, 0x00f8, odml_list ); - - /* align movi list to block */ - GetDirectoryEntry( hdrl_list, type, name, length, offset, parent ); - num_blocks = length / PADDING_SIZE + 1; - length = num_blocks * PADDING_SIZE - length - 5 * RIFF_HEADERSIZE; // why 5? - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list ); - - movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list ); - - /* The ix00 chunk will be added dynamically to the movi_list in avi_write_frame - as needed */ - - ix_chunk[ 0 ] = -1; -} - - -/* Write a DV video frame. This is somewhat complex... */ - -#if 0 -bool AVI1File::WriteFrame( const Frame &frame ) -{ - int frame_chunk; - int junk_chunk; - int num_blocks; - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - /* exit if no large index and 1GB reached */ - if ( !( index_type & AVI_LARGE_INDEX ) && isUpdateIdx1 == false ) - return false; - - /* Check if we need a new ix00 Standard Index. It has a - capacity of IX00_INDEX_SIZE frames. Whenever we exceed that - number, we need a new index. The new ix00 chunk is also - part of the movi list. */ - - if ( ( index_type & AVI_LARGE_INDEX ) && ( ( ( streamHdr[ 0 ].dwLength - 0 ) % IX00_INDEX_SIZE ) == 0 ) ) - FlushIndx( 0 ); - - /* Write the DV frame data. - - Make a new 00__ chunk for the new frame, write out the - frame. */ - - frame_chunk = AddDirectoryEntry( make_fourcc( "00__" ), 0, frame.GetFrameSize(), movi_list ); - if ( ( index_type & AVI_LARGE_INDEX ) && ( streamHdr[ 0 ].dwLength % IX00_INDEX_SIZE ) == 0 ) - { - GetDirectoryEntry( frame_chunk, type, name, length, offset, parent ); - ix[ 0 ] ->qwBaseOffset = offset - RIFF_HEADERSIZE; - } - WriteChunk( frame_chunk, frame.data ); - // num_blocks = (frame.GetFrameSize() + RIFF_HEADERSIZE) / PADDING_SIZE + 1; - // length = num_blocks * PADDING_SIZE - frame.GetFrameSize() - 2 * RIFF_HEADERSIZE; - // junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, length, movi_list); - // WriteChunk(junk_chunk, g_zeroes); - - if ( index_type & AVI_LARGE_INDEX ) - UpdateIndx( 0, frame_chunk, 1 ); - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - UpdateIdx1( frame_chunk, 0x10 ); - - /* update some variables with the new frame count. */ - - if ( isUpdateIdx1 ) - ++mainHdr.dwTotalFrames; - ++streamHdr[ 0 ].dwLength; - ++dmlh[ 0 ]; - - /* Find out if the current riff list is close to 1 GByte in - size. If so, start a new (extended) RIFF. The only allowed - item in the new RIFF chunk is a movi list (with video - frames and indexes as usual). */ - - GetDirectoryEntry( riff_list, type, name, length, offset, parent ); - if ( length > 0x3f000000 ) - { - /* write idx1 only once and before end of first GB */ - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - { - int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list ); - WriteChunk( idx1_chunk, ( void* ) idx1 ); - } - isUpdateIdx1 = false; - - if ( index_type & AVI_LARGE_INDEX ) - { - /* pad out to 1GB */ - //GetDirectoryEntry(riff_list, type, name, length, offset, parent); - //junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, PADDING_1GB - length - 5 * RIFF_HEADERSIZE, riff_list); - //WriteChunk(junk_chunk, g_zeroes); - - /* padding for alignment */ - GetDirectoryEntry( riff_list, type, name, length, offset, parent ); - num_blocks = ( length + 4 * RIFF_HEADERSIZE ) / PADDING_SIZE + 1; - length = ( num_blocks * PADDING_SIZE ) - length - 4 * RIFF_HEADERSIZE - 2 * RIFF_LISTSIZE; - if ( length > 0 ) - { - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list ); - WriteChunk( junk_chunk, g_zeroes ); - } - - riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVIX" ), RIFF_LISTSIZE, file_list ); - movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list ); - } - } - return true; -} -#endif - -void AVI1File::WriteRIFF() -{ - - WriteChunk( avih_chunk, ( void* ) & mainHdr ); - WriteChunk( strh_chunk[ 0 ], ( void* ) & streamHdr[ 0 ] ); - WriteChunk( strf_chunk[ 0 ], ( void* ) & dvinfo ); - WriteChunk( dmlh_chunk, ( void* ) & dmlh ); - - if ( index_type & AVI_LARGE_INDEX ) - { - WriteChunk( indx_chunk[ 0 ], ( void* ) indx[ 0 ] ); - WriteChunk( ix_chunk[ 0 ], ( void* ) ix[ 0 ] ); - } - - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - { - int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list ); - WriteChunk( idx1_chunk, ( void* ) idx1 ); - } - - RIFFFile::WriteRIFF(); -} - - -AVI2File::AVI2File() : AVIFile() -{} - - -AVI2File::~AVI2File() -{} - - -/* Initialize the AVI structure to its initial state, either for PAL - or NTSC format */ - -void AVI2File::Init( int format, int sampleFrequency, int indexType ) -{ - int num_blocks; - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - assert( ( format == AVI_PAL ) || ( format == AVI_NTSC ) ); - - AVIFile::Init( format, sampleFrequency, indexType ); - - switch ( format ) - { - - case AVI_PAL: - mainHdr.dwStreams = 2; - mainHdr.dwWidth = 720; - mainHdr.dwHeight = 576; - - /* Initialize the 'strh' chunk */ - - streamHdr[ 0 ].fccType = make_fourcc( "vids" ); - streamHdr[ 0 ].fccHandler = make_fourcc( "dvsd" ); - streamHdr[ 0 ].dwFlags = 0; - streamHdr[ 0 ].wPriority = 0; - streamHdr[ 0 ].wLanguage = 0; - streamHdr[ 0 ].dwInitialFrames = 0; - streamHdr[ 0 ].dwScale = 1; - streamHdr[ 0 ].dwRate = 25; - streamHdr[ 0 ].dwStart = 0; - streamHdr[ 0 ].dwLength = 0; - streamHdr[ 0 ].dwSuggestedBufferSize = 144008; - streamHdr[ 0 ].dwQuality = -1; - streamHdr[ 0 ].dwSampleSize = 0; - streamHdr[ 0 ].rcFrame.top = 0; - streamHdr[ 0 ].rcFrame.bottom = 0; - streamHdr[ 0 ].rcFrame.left = 0; - streamHdr[ 0 ].rcFrame.right = 0; - - bitmapinfo.biSize = sizeof( bitmapinfo ); - bitmapinfo.biWidth = 720; - bitmapinfo.biHeight = 576; - bitmapinfo.biPlanes = 1; - bitmapinfo.biBitCount = 24; - bitmapinfo.biCompression = make_fourcc( "dvsd" ); - bitmapinfo.biSizeImage = 144000; - bitmapinfo.biXPelsPerMeter = 0; - bitmapinfo.biYPelsPerMeter = 0; - bitmapinfo.biClrUsed = 0; - bitmapinfo.biClrImportant = 0; - - streamHdr[ 1 ].fccType = make_fourcc( "auds" ); - streamHdr[ 1 ].fccHandler = 0; - streamHdr[ 1 ].dwFlags = 0; - streamHdr[ 1 ].wPriority = 0; - streamHdr[ 1 ].wLanguage = 0; - streamHdr[ 1 ].dwInitialFrames = 0; - streamHdr[ 1 ].dwScale = 2 * 2; - streamHdr[ 1 ].dwRate = sampleFrequency * 2 * 2; - streamHdr[ 1 ].dwStart = 0; - streamHdr[ 1 ].dwLength = 0; - streamHdr[ 1 ].dwSuggestedBufferSize = 8192; - streamHdr[ 1 ].dwQuality = -1; - streamHdr[ 1 ].dwSampleSize = 2 * 2; - streamHdr[ 1 ].rcFrame.top = 0; - streamHdr[ 1 ].rcFrame.bottom = 0; - streamHdr[ 1 ].rcFrame.left = 0; - streamHdr[ 1 ].rcFrame.right = 0; - - break; - - case AVI_NTSC: - mainHdr.dwTotalFrames = 0; - mainHdr.dwStreams = 2; - mainHdr.dwWidth = 720; - mainHdr.dwHeight = 480; - - /* Initialize the 'strh' chunk */ - - streamHdr[ 0 ].fccType = make_fourcc( "vids" ); - streamHdr[ 0 ].fccHandler = make_fourcc( "dvsd" ); - streamHdr[ 0 ].dwFlags = 0; - streamHdr[ 0 ].wPriority = 0; - streamHdr[ 0 ].wLanguage = 0; - streamHdr[ 0 ].dwInitialFrames = 0; - streamHdr[ 0 ].dwScale = 1001; - streamHdr[ 0 ].dwRate = 30000; - streamHdr[ 0 ].dwStart = 0; - streamHdr[ 0 ].dwLength = 0; - streamHdr[ 0 ].dwSuggestedBufferSize = 120008; - streamHdr[ 0 ].dwQuality = -1; - streamHdr[ 0 ].dwSampleSize = 0; - streamHdr[ 0 ].rcFrame.top = 0; - streamHdr[ 0 ].rcFrame.bottom = 0; - streamHdr[ 0 ].rcFrame.left = 0; - streamHdr[ 0 ].rcFrame.right = 0; - - bitmapinfo.biSize = sizeof( bitmapinfo ); - bitmapinfo.biWidth = 720; - bitmapinfo.biHeight = 480; - bitmapinfo.biPlanes = 1; - bitmapinfo.biBitCount = 24; - bitmapinfo.biCompression = make_fourcc( "dvsd" ); - bitmapinfo.biSizeImage = 120000; - bitmapinfo.biXPelsPerMeter = 0; - bitmapinfo.biYPelsPerMeter = 0; - bitmapinfo.biClrUsed = 0; - bitmapinfo.biClrImportant = 0; - - streamHdr[ 1 ].fccType = make_fourcc( "auds" ); - streamHdr[ 1 ].fccHandler = 0; - streamHdr[ 1 ].dwFlags = 0; - streamHdr[ 1 ].wPriority = 0; - streamHdr[ 1 ].wLanguage = 0; - streamHdr[ 1 ].dwInitialFrames = 1; - streamHdr[ 1 ].dwScale = 2 * 2; - streamHdr[ 1 ].dwRate = sampleFrequency * 2 * 2; - streamHdr[ 1 ].dwStart = 0; - streamHdr[ 1 ].dwLength = 0; - streamHdr[ 1 ].dwSuggestedBufferSize = 8192; - streamHdr[ 1 ].dwQuality = 0; - streamHdr[ 1 ].dwSampleSize = 2 * 2; - streamHdr[ 1 ].rcFrame.top = 0; - streamHdr[ 1 ].rcFrame.bottom = 0; - streamHdr[ 1 ].rcFrame.left = 0; - streamHdr[ 1 ].rcFrame.right = 0; - - break; - } - waveformatex.wFormatTag = 1; - waveformatex.nChannels = 2; - waveformatex.nSamplesPerSec = sampleFrequency; - waveformatex.nAvgBytesPerSec = sampleFrequency * 2 * 2; - waveformatex.nBlockAlign = 4; - waveformatex.wBitsPerSample = 16; - waveformatex.cbSize = 0; - - file_list = AddDirectoryEntry( make_fourcc( "FILE" ), make_fourcc( "FILE" ), 0, RIFF_NO_PARENT ); - - /* Create a basic directory structure. Only chunks defined from here on will be written to the AVI file. */ - - riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVI " ), RIFF_LISTSIZE, file_list ); - hdrl_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "hdrl" ), RIFF_LISTSIZE, riff_list ); - avih_chunk = AddDirectoryEntry( make_fourcc( "avih" ), 0, sizeof( MainAVIHeader ), hdrl_list ); - - strl_list[ 0 ] = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "strl" ), RIFF_LISTSIZE, hdrl_list ); - strh_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strh" ), 0, sizeof( AVIStreamHeader ), strl_list[ 0 ] ); - strf_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "strf" ), 0, sizeof( BITMAPINFOHEADER ), strl_list[ 0 ] ); - if ( index_type & AVI_LARGE_INDEX ) - { - indx_chunk[ 0 ] = AddDirectoryEntry( make_fourcc( "indx" ), 0, sizeof( AVISuperIndex ), strl_list[ 0 ] ); - ix_chunk[ 0 ] = -1; - indx[ 0 ] ->dwChunkId = make_fourcc( "00dc" ); - } - - strl_list[ 1 ] = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "strl" ), RIFF_LISTSIZE, hdrl_list ); - strh_chunk[ 1 ] = AddDirectoryEntry( make_fourcc( "strh" ), 0, sizeof( AVIStreamHeader ), strl_list[ 1 ] ); - strf_chunk[ 1 ] = AddDirectoryEntry( make_fourcc( "strf" ), 0, sizeof( WAVEFORMATEX ) - 2, strl_list[ 1 ] ); - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, 2, strl_list[ 1 ] ); - if ( index_type & AVI_LARGE_INDEX ) - { - indx_chunk[ 1 ] = AddDirectoryEntry( make_fourcc( "indx" ), 0, sizeof( AVISuperIndex ), strl_list[ 1 ] ); - ix_chunk[ 1 ] = -1; - indx[ 1 ] ->dwChunkId = make_fourcc( "01wb" ); - - odml_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "odml" ), RIFF_LISTSIZE, hdrl_list ); - dmlh_chunk = AddDirectoryEntry( make_fourcc( "dmlh" ), 0, 0x00f8, odml_list ); - } - - /* align movi list to block */ - GetDirectoryEntry( hdrl_list, type, name, length, offset, parent ); - num_blocks = length / PADDING_SIZE + 1; - length = num_blocks * PADDING_SIZE - length - 5 * RIFF_HEADERSIZE; // why 5 headers? - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list ); - - movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list ); - - idx1->aIndex[ idx1->nEntriesInUse ].dwChunkId = make_fourcc( "7Fxx" ); - idx1->aIndex[ idx1->nEntriesInUse ].dwFlags = 0; - idx1->aIndex[ idx1->nEntriesInUse ].dwOffset = 0; - idx1->aIndex[ idx1->nEntriesInUse ].dwSize = 0; - idx1->nEntriesInUse++; -} - - -void AVI2File::WriteRIFF() -{ - WriteChunk( avih_chunk, ( void* ) & mainHdr ); - WriteChunk( strh_chunk[ 0 ], ( void* ) & streamHdr[ 0 ] ); - WriteChunk( strf_chunk[ 0 ], ( void* ) & bitmapinfo ); - if ( index_type & AVI_LARGE_INDEX ) - { - WriteChunk( dmlh_chunk, ( void* ) & dmlh ); - WriteChunk( indx_chunk[ 0 ], ( void* ) indx[ 0 ] ); - WriteChunk( ix_chunk[ 0 ], ( void* ) ix[ 0 ] ); - } - WriteChunk( strh_chunk[ 1 ], ( void* ) & streamHdr[ 1 ] ); - WriteChunk( strf_chunk[ 1 ], ( void* ) & waveformatex ); - if ( index_type & AVI_LARGE_INDEX ) - { - WriteChunk( indx_chunk[ 1 ], ( void* ) indx[ 1 ] ); - WriteChunk( ix_chunk[ 1 ], ( void* ) ix[ 1 ] ); - } - - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - { - int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list ); - WriteChunk( idx1_chunk, ( void* ) idx1 ); - } - RIFFFile::WriteRIFF(); -} - - -/** Write a DV video frame - - \param frame the frame to write -*/ - -#if 0 -bool AVI2File::WriteFrame( const Frame &frame ) -{ - int audio_chunk; - int frame_chunk; - int junk_chunk; - char soundbuf[ 20000 ]; - int audio_size; - int num_blocks; - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - - /* exit if no large index and 1GB reached */ - if ( !( index_type & AVI_LARGE_INDEX ) && isUpdateIdx1 == false ) - return false; - - /* Check if we need a new ix00 Standard Index. It has a - capacity of IX00_INDEX_SIZE frames. Whenever we exceed that - number, we need a new index. The new ix00 chunk is also - part of the movi list. */ - - if ( ( index_type & AVI_LARGE_INDEX ) && ( ( ( streamHdr[ 0 ].dwLength - 0 ) % IX00_INDEX_SIZE ) == 0 ) ) - { - FlushIndx( 0 ); - FlushIndx( 1 ); - } - - /* Write audio data if we have it */ - - audio_size = frame.ExtractAudio( soundbuf ); - if ( audio_size > 0 ) - { - audio_chunk = AddDirectoryEntry( make_fourcc( "01wb" ), 0, audio_size, movi_list ); - if ( ( index_type & AVI_LARGE_INDEX ) && ( streamHdr[ 0 ].dwLength % IX00_INDEX_SIZE ) == 0 ) - { - GetDirectoryEntry( audio_chunk, type, name, length, offset, parent ); - ix[ 1 ] ->qwBaseOffset = offset - RIFF_HEADERSIZE; - } - WriteChunk( audio_chunk, soundbuf ); - // num_blocks = (audio_size + RIFF_HEADERSIZE) / PADDING_SIZE + 1; - // length = num_blocks * PADDING_SIZE - audio_size - 2 * RIFF_HEADERSIZE; - // junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, length, movi_list); - // WriteChunk(junk_chunk, g_zeroes); - if ( index_type & AVI_LARGE_INDEX ) - UpdateIndx( 1, audio_chunk, audio_size / waveformatex.nChannels / 2 ); - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - UpdateIdx1( audio_chunk, 0x00 ); - streamHdr[ 1 ].dwLength += audio_size / waveformatex.nChannels / 2; - - } - - /* Write video data */ - - frame_chunk = AddDirectoryEntry( make_fourcc( "00dc" ), 0, frame.GetFrameSize(), movi_list ); - if ( ( index_type & AVI_LARGE_INDEX ) && ( streamHdr[ 0 ].dwLength % IX00_INDEX_SIZE ) == 0 ) - { - GetDirectoryEntry( frame_chunk, type, name, length, offset, parent ); - ix[ 0 ] ->qwBaseOffset = offset - RIFF_HEADERSIZE; - } - WriteChunk( frame_chunk, frame.data ); - // num_blocks = (frame.GetFrameSize() + RIFF_HEADERSIZE) / PADDING_SIZE + 1; - // length = num_blocks * PADDING_SIZE - frame.GetFrameSize() - 2 * RIFF_HEADERSIZE; - // junk_chunk = AddDirectoryEntry(make_fourcc("JUNK"), 0, length, movi_list); - // WriteChunk(junk_chunk, g_zeroes); - if ( index_type & AVI_LARGE_INDEX ) - UpdateIndx( 0, frame_chunk, 1 ); - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - UpdateIdx1( frame_chunk, 0x10 ); - - /* update some variables with the new frame count. */ - - if ( isUpdateIdx1 ) - ++mainHdr.dwTotalFrames; - ++streamHdr[ 0 ].dwLength; - ++dmlh[ 0 ]; - - /* Find out if the current riff list is close to 1 GByte in - size. If so, start a new (extended) RIFF. The only allowed - item in the new RIFF chunk is a movi list (with video - frames and indexes as usual). */ - - GetDirectoryEntry( riff_list, type, name, length, offset, parent ); - if ( length > 0x3f000000 ) - { - - /* write idx1 only once and before end of first GB */ - if ( ( index_type & AVI_SMALL_INDEX ) && isUpdateIdx1 ) - { - int idx1_chunk = AddDirectoryEntry( make_fourcc( "idx1" ), 0, idx1->nEntriesInUse * 16, riff_list ); - WriteChunk( idx1_chunk, ( void* ) idx1 ); - } - isUpdateIdx1 = false; - - if ( index_type & AVI_LARGE_INDEX ) - { - /* padding for alignment */ - GetDirectoryEntry( riff_list, type, name, length, offset, parent ); - num_blocks = ( length + 4 * RIFF_HEADERSIZE ) / PADDING_SIZE + 1; - length = ( num_blocks * PADDING_SIZE ) - length - 4 * RIFF_HEADERSIZE - 2 * RIFF_LISTSIZE; - if ( length > 0 ) - { - junk_chunk = AddDirectoryEntry( make_fourcc( "JUNK" ), 0, length, riff_list ); - WriteChunk( junk_chunk, g_zeroes ); - } - - riff_list = AddDirectoryEntry( make_fourcc( "RIFF" ), make_fourcc( "AVIX" ), RIFF_LISTSIZE, file_list ); - movi_list = AddDirectoryEntry( make_fourcc( "LIST" ), make_fourcc( "movi" ), RIFF_LISTSIZE, riff_list ); - } - } - return true; -} -#endif - -void AVI1File::setDVINFO( DVINFO &info ) -{ - // do not do this until debugged audio against DirectShow - return ; - - dvinfo.dwDVAAuxSrc = info.dwDVAAuxSrc; - dvinfo.dwDVAAuxCtl = info.dwDVAAuxCtl; - dvinfo.dwDVAAuxSrc1 = info.dwDVAAuxSrc1; - dvinfo.dwDVAAuxCtl1 = info.dwDVAAuxCtl1; - dvinfo.dwDVVAuxSrc = info.dwDVVAuxSrc; - dvinfo.dwDVVAuxCtl = info.dwDVVAuxCtl; -} - - -void AVI2File::setDVINFO( DVINFO &info ) -{} - -void AVIFile::setFccHandler( FOURCC type, FOURCC handler ) -{ - for ( int i = 0; i < mainHdr.dwStreams; i++ ) - { - if ( streamHdr[ i ].fccType == type ) - { - int k, j = 0; - FOURCC strf = make_fourcc( "strf" ); - BITMAPINFOHEADER bih; - - streamHdr[ i ].fccHandler = handler; - - while ( ( k = FindDirectoryEntry( strf, j++ ) ) != -1 ) - { - ReadChunk( k, ( void* ) & bih, sizeof( BITMAPINFOHEADER ) ); - bih.biCompression = handler; - } - } - } -} - -bool AVIFile::getStreamFormat( void* data, FOURCC type ) -{ - int i, j = 0; - FOURCC strh = make_fourcc( "strh" ); - FOURCC strf = make_fourcc( "strf" ); - AVIStreamHeader avi_stream_header; - bool result = false; - - while ( ( result == false ) && ( i = FindDirectoryEntry( strh, j++ ) ) != -1 ) - { - ReadChunk( i, ( void* ) & avi_stream_header, sizeof( AVIStreamHeader ) ); - if ( avi_stream_header.fccType == type ) - { - FOURCC chunkID; - int size; - - pthread_mutex_lock( &file_mutex ); - fail_neg( read( fd, &chunkID, sizeof( FOURCC ) ) ); - if ( chunkID == strf ) - { - fail_neg( read( fd, &size, sizeof( int ) ) ); - fail_neg( read( fd, data, size ) ); - result = true; - } - pthread_mutex_unlock( &file_mutex ); - } - } - return result; -} diff --git a/src/modules/kino/avi.h b/src/modules/kino/avi.h deleted file mode 100644 index 6c20923bc..000000000 --- a/src/modules/kino/avi.h +++ /dev/null @@ -1,330 +0,0 @@ -/* -* avi.h library for AVI file format i/o -* Copyright (C) 2000 - 2002 Arne Schirmacher -* -* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -/** Common AVI declarations - - Some of this comes from the public domain AVI specification, which - explains the microsoft-style definitions. - - \file avi.h -*/ - -#ifndef _AVI_H -#define _AVI_H 1 - -#include -#include "riff.h" - -#define PACKED(x) __attribute__((packed)) x - -#define AVI_SMALL_INDEX (0x01) -#define AVI_LARGE_INDEX (0x02) -#define KINO_AVI_INDEX_OF_INDEXES (0x00) -#define KINO_AVI_INDEX_OF_CHUNKS (0x01) -#define AVI_INDEX_2FIELD (0x01) - -enum { AVI_PAL, AVI_NTSC, AVI_AUDIO_48KHZ, AVI_AUDIO_44KHZ, AVI_AUDIO_32KHZ }; - -/** Declarations of the main AVI file header - - The contents of this struct goes into the 'avih' chunk. */ - -typedef struct -{ - /// frame display rate (or 0L) - DWORD dwMicroSecPerFrame; - - /// max. transfer rate - DWORD dwMaxBytesPerSec; - - /// pad to multiples of this size, normally 2K - DWORD dwPaddingGranularity; - - /// the ever-present flags - DWORD dwFlags; - - /// # frames in file - DWORD dwTotalFrames; - DWORD dwInitialFrames; - DWORD dwStreams; - DWORD dwSuggestedBufferSize; - - DWORD dwWidth; - DWORD dwHeight; - - DWORD dwReserved[ 4 ]; -} -PACKED(MainAVIHeader); - -typedef struct -{ - WORD top, bottom, left, right; -} -PACKED(RECT); - -/** Declaration of a stream header - - The contents of this struct goes into the 'strh' header. */ - -typedef struct -{ - FOURCC fccType; - FOURCC fccHandler; - DWORD dwFlags; /* Contains AVITF_* flags */ - WORD wPriority; - WORD wLanguage; - DWORD dwInitialFrames; - DWORD dwScale; - DWORD dwRate; /* dwRate / dwScale == samples/second */ - DWORD dwStart; - DWORD dwLength; /* In units above... */ - DWORD dwSuggestedBufferSize; - DWORD dwQuality; - DWORD dwSampleSize; - RECT rcFrame; -} -PACKED(AVIStreamHeader); - -typedef struct -{ - DWORD dwDVAAuxSrc; - DWORD dwDVAAuxCtl; - DWORD dwDVAAuxSrc1; - DWORD dwDVAAuxCtl1; - DWORD dwDVVAuxSrc; - DWORD dwDVVAuxCtl; - DWORD dwDVReserved[ 2 ]; -} -PACKED(DVINFO); - -typedef struct -{ - DWORD biSize; - LONG biWidth; - LONG biHeight; - WORD biPlanes; - WORD biBitCount; - DWORD biCompression; - DWORD biSizeImage; - LONG biXPelsPerMeter; - LONG biYPelsPerMeter; - DWORD biClrUsed; - DWORD biClrImportant; - char dummy[ 1040 ]; -} -PACKED(BITMAPINFOHEADER); - -typedef struct -{ - WORD wFormatTag; - WORD nChannels; - DWORD nSamplesPerSec; - DWORD nAvgBytesPerSec; - WORD nBlockAlign; - WORD wBitsPerSample; - WORD cbSize; - WORD dummy; -} -PACKED(WAVEFORMATEX); - -typedef struct -{ - WORD wLongsPerEntry; - BYTE bIndexSubType; - BYTE bIndexType; - DWORD nEntriesInUse; - FOURCC dwChunkId; - DWORD dwReserved[ 3 ]; - struct avisuperindex_entry - { - QUADWORD qwOffset; - DWORD dwSize; - DWORD dwDuration; - } - aIndex[ 3198 ]; -} -PACKED(AVISuperIndex); - -typedef struct -{ - WORD wLongsPerEntry; - BYTE bIndexSubType; - BYTE bIndexType; - DWORD nEntriesInUse; - FOURCC dwChunkId; - QUADWORD qwBaseOffset; - DWORD dwReserved; - struct avifieldindex_entry - { - DWORD dwOffset; - DWORD dwSize; - } - aIndex[ 17895 ]; -} -PACKED(AVIStdIndex); - -typedef struct -{ - struct avisimpleindex_entry - { - FOURCC dwChunkId; - DWORD dwFlags; - DWORD dwOffset; - DWORD dwSize; - } - aIndex[ 20000 ]; - DWORD nEntriesInUse; -} -PACKED(AVISimpleIndex); - -typedef struct -{ - DWORD dirEntryType; - DWORD dirEntryName; - DWORD dirEntryLength; - size_t dirEntryOffset; - int dirEntryWrittenFlag; - int dirEntryParentList; -} -AviDirEntry; - - -/** base class for all AVI type files - - It contains methods and members which are the same in all AVI type files regardless of the particular compression, number - of streams etc. - - The AVIFile class also contains methods for handling several indexes to the video frame content. */ - -class AVIFile : public RIFFFile -{ -public: - AVIFile(); - AVIFile( const AVIFile& ); - virtual ~AVIFile(); - virtual AVIFile& operator=( const AVIFile& ); - - virtual void Init( int format, int sampleFrequency, int indexType ); - virtual int GetDVFrameInfo( off_t &offset, int &size, int frameNum ); - virtual int GetFrameInfo( off_t &offset, int &size, int frameNum, FOURCC chunkID ); - virtual int GetDVFrame( uint8_t *data, int frameNum ); - virtual int getFrame( void *data, int frameNum, FOURCC chunkID ); - virtual int GetTotalFrames() const; - virtual void PrintDirectoryEntryData( const RIFFDirEntry &entry ) const; - //virtual bool WriteFrame( const Frame &frame ) { return false; } - virtual void ParseList( int parent ); - virtual void ParseRIFF( void ); - virtual void ReadIndex( void ); - virtual void WriteRIFF( void ) - { } - virtual void FlushIndx( int stream ); - virtual void UpdateIndx( int stream, int chunk, int duration ); - virtual void UpdateIdx1( int chunk, int flags ); - virtual bool verifyStreamFormat( FOURCC type ); - virtual bool verifyStream( FOURCC type ); - virtual bool isOpenDML( void ); - virtual void setDVINFO( DVINFO& ) - { } - virtual void setFccHandler( FOURCC type, FOURCC handler ); - virtual bool getStreamFormat( void* data, FOURCC type ); - -protected: - MainAVIHeader mainHdr; - AVISimpleIndex *idx1; - int file_list; - int riff_list; - int hdrl_list; - int avih_chunk; - int movi_list; - int junk_chunk; - int idx1_chunk; - - AVIStreamHeader streamHdr[ 2 ]; - AVISuperIndex *indx[ 2 ]; - AVIStdIndex *ix[ 2 ]; - int indx_chunk[ 2 ]; - int ix_chunk[ 2 ]; - int strl_list[ 2 ]; - int strh_chunk[ 2 ]; - int strf_chunk[ 2 ]; - - int index_type; - int current_ix00; - - DWORD dmlh[ 62 ]; - int odml_list; - int dmlh_chunk; - bool isUpdateIdx1; - -}; - - -/** writing Type 1 DV AVIs - -*/ - -class AVI1File : public AVIFile -{ -public: - AVI1File(); - virtual ~AVI1File(); - - virtual void Init( int format, int sampleFrequency, int indexType ); - //virtual bool WriteFrame( const Frame &frame ); - virtual void WriteRIFF( void ); - virtual void setDVINFO( DVINFO& ); - -private: - DVINFO dvinfo; - - AVI1File( const AVI1File& ); - AVI1File& operator=( const AVI1File& ); -}; - - -/** writing Type 2 (separate audio data) DV AVIs - -This file type contains both audio and video tracks. It is therefore more compatible -to certain Windows programs, which expect any AVI having both audio and video tracks. -The video tracks contain the raw DV data (as in type 1) and the extracted audio tracks. - -Note that because the DV data contains audio information anyway, this means duplication -of data and a slight increase of file size. - -*/ - -class AVI2File : public AVIFile -{ -public: - AVI2File(); - virtual ~AVI2File(); - - virtual void Init( int format, int sampleFrequency, int indexType ); - //virtual bool WriteFrame( const Frame &frame ); - virtual void WriteRIFF( void ); - virtual void setDVINFO( DVINFO& ); - -private: - BITMAPINFOHEADER bitmapinfo; - WAVEFORMATEX waveformatex; - - AVI2File( const AVI2File& ); - AVI2File& operator=( const AVI2File& ); -}; -#endif diff --git a/src/modules/kino/configure b/src/modules/kino/configure deleted file mode 100755 index 5949890c1..000000000 --- a/src/modules/kino/configure +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - - if [ "$targetos" = "Darwin" ] || [ "$targetos" = "MinGW" ] - then - echo "- does not build on OS X or Windows: disabling" - touch ../disable-kino - exit 0 - fi - - # Entirely optional... - pkg-config libquicktime 2> /dev/null - lqt_disabled=$? - - pkg-config libdv 2> /dev/null - libdv_disabled=$? - - echo > config.mak - - if [ "$lqt_disabled" = "0" ] - then - echo "CFLAGS += -DHAVE_LIBQUICKTIME" >> config.mak - echo "HAVE_LIBQUICKTIME=1" >> config.mak - else - echo "- libquicktime not found: only enabling dv avi support" - fi - - if [ "$libdv_disabled" = "0" ] - then - echo "CFLAGS += -DHAVE_LIBDV" >> config.mak - echo "HAVE_LIBDV=1" >> config.mak - fi - - [ "$libdv_disabled" != "0" -a "$lqt_disabled" = "0" ] && echo "- libdv not found: mov dv may not have audio" - - exit 0 -fi diff --git a/src/modules/kino/deprecated b/src/modules/kino/deprecated deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/modules/kino/endian_types.h b/src/modules/kino/endian_types.h deleted file mode 100644 index cd2410ada..000000000 --- a/src/modules/kino/endian_types.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * - * Quick hack to handle endianness and word length issues. - * Defines _le, _be, and _ne variants to standard ISO types - * like int32_t, that are stored in little-endian, big-endian, - * and native-endian byteorder in memory, respectively. - * Caveat: int32_le_t and friends cannot be used in vararg - * functions like printf() without an explicit cast. - * - * Copyright (c) 2003-2005 Daniel Kobras - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _ENDIAN_TYPES_H -#define _ENDIAN_TYPES_H - -#include - -/* Needed for BYTE_ORDER and BIG/LITTLE_ENDIAN macros. */ -#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) -#ifndef _BSD_SOURCE -# define _BSD_SOURCE -# include -# undef _BSD_SOURCE -#else -# include -#endif -#else -# include -#endif /* !defined(__FreeBSD__) && !defined(__NetBSD__) */ - -#if !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) -#include -#elif defined(__OpenBSD__) -#define bswap_16(x) swap16(x) -#define bswap_32(x) swap32(x) -#define bswap_64(x) swap64(x) -#else -#define bswap_16(x) bswap16(x) -#define bswap_32(x) bswap32(x) -#define bswap_64(x) bswap64(x) -#endif /* !defined(__FreeBSD__) && !defined(__NetBSD__) */ - -static inline int8_t bswap(const int8_t& x) -{ - return x; -} - -static inline u_int8_t bswap(const u_int8_t& x) -{ - return x; -} - -static inline int16_t bswap(const int16_t& x) -{ - return bswap_16(x); -} - -static inline u_int16_t bswap(const u_int16_t& x) -{ - return bswap_16(x); -} - -static inline int32_t bswap(const int32_t& x) -{ - return bswap_32(x); -} - -static inline u_int32_t bswap(const u_int32_t& x) -{ - return bswap_32(x); -} - -static inline int64_t bswap(const int64_t& x) -{ - return bswap_64(x); -} - -static inline u_int64_t bswap(const u_int64_t& x) -{ - return bswap_64(x); -} - -#define le_to_cpu cpu_to_le -#define be_to_cpu cpu_to_be - -template static inline T cpu_to_le(const T& x) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - return x; -#else - return bswap(x); -#endif -} - -template static inline T cpu_to_be(const T& x) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - return bswap(x); -#else - return x; -#endif -} - -template class le_t { - T m; - T read() const { - return le_to_cpu(m); - }; - void write(const T& n) { - m = cpu_to_le(n); - }; -public: - le_t(void) { - m = 0; - }; - le_t(const T& o) { - write(o); - }; - operator T() const { - return read(); - }; - le_t operator++() { - write(read() + 1); - return *this; - }; - le_t operator++(int) { - write(read() + 1); - return *this; - }; - le_t operator--() { - write(read() - 1); - return *this; - }; - le_t operator--(int) { - write(read() - 1); - return *this; - }; - le_t& operator+=(const T& t) { - write(read() + t); - return *this; - }; - le_t& operator-=(const T& t) { - write(read() - t); - return *this; - }; - le_t& operator&=(const le_t& t) { - m &= t.m; - return *this; - }; - le_t& operator|=(const le_t& t) { - m |= t.m; - return *this; - }; -} __attribute__((packed)); - -/* Just copy-and-pasted from le_t. Too lazy to do it right. */ - -template class be_t { - T m; - T read() const { - return be_to_cpu(m); - }; - void write(const T& n) { - m = cpu_to_be(n); - }; -public: - be_t(void) { - m = 0; - }; - be_t(const T& o) { - write(o); - }; - operator T() const { - return read(); - }; - be_t operator++() { - write(read() + 1); - return *this; - }; - be_t operator++(int) { - write(read() + 1); - return *this; - }; - be_t operator--() { - write(read() - 1); - return *this; - }; - be_t operator--(int) { - write(read() - 1); - return *this; - }; - be_t& operator+=(const T& t) { - write(read() + t); - return *this; - }; - be_t& operator-=(const T& t) { - write(read() - t); - return *this; - }; - be_t& operator&=(const be_t& t) { - m &= t.m; - return *this; - }; - be_t& operator|=(const be_t& t) { - m |= t.m; - return *this; - }; -} __attribute__((packed)); - -/* Define types of native endianness similar to the little and big endian - * versions below. Not really necessary but useful occasionally to emphasize - * endianness of data. - */ - -typedef int8_t int8_ne_t; -typedef int16_t int16_ne_t; -typedef int32_t int32_ne_t; -typedef int64_t int64_ne_t; -typedef u_int8_t u_int8_ne_t; -typedef u_int16_t u_int16_ne_t; -typedef u_int32_t u_int32_ne_t; -typedef u_int64_t u_int64_ne_t; - - -/* The classes work on their native endianness as well, but obviously - * introduce some overhead. Use the faster typedefs to native types - * therefore, unless you're debugging. - */ - -#if BYTE_ORDER == LITTLE_ENDIAN -typedef int8_ne_t int8_le_t; -typedef int16_ne_t int16_le_t; -typedef int32_ne_t int32_le_t; -typedef int64_ne_t int64_le_t; -typedef u_int8_ne_t u_int8_le_t; -typedef u_int16_ne_t u_int16_le_t; -typedef u_int32_ne_t u_int32_le_t; -typedef u_int64_ne_t u_int64_le_t; -typedef int8_t int8_be_t; -typedef be_t int16_be_t; -typedef be_t int32_be_t; -typedef be_t int64_be_t; -typedef u_int8_t u_int8_be_t; -typedef be_t u_int16_be_t; -typedef be_t u_int32_be_t; -typedef be_t u_int64_be_t; -#else -typedef int8_ne_t int8_be_t; -typedef int16_ne_t int16_be_t; -typedef int32_ne_t int32_be_t; -typedef int64_ne_t int64_be_t; -typedef u_int8_ne_t u_int8_be_t; -typedef u_int16_ne_t u_int16_be_t; -typedef u_int32_ne_t u_int32_be_t; -typedef u_int64_ne_t u_int64_be_t; -typedef int8_t int8_le_t; -typedef le_t int16_le_t; -typedef le_t int32_le_t; -typedef le_t int64_le_t; -typedef u_int8_t u_int8_le_t; -typedef le_t u_int16_le_t; -typedef le_t u_int32_le_t; -typedef le_t u_int64_le_t; -#endif - -#endif diff --git a/src/modules/kino/error.cc b/src/modules/kino/error.cc deleted file mode 100644 index 92b93613d..000000000 --- a/src/modules/kino/error.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* -* error.cc Error handling -* Copyright (C) 2000 Arne Schirmacher -* -* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifdef HAVE_CONFIG_H -#include -#endif - -// C++ includes - -#include -#include -#include -#include - -using std::ostringstream; -using std::string; -using std::endl; -using std::ends; -using std::cerr; - -// C includes - -#include -#include - -// local includes - -#include "error.h" - -void real_fail_neg( int eval, const char *eval_str, const char *func, const char *file, int line ) -{ - if ( eval < 0 ) - { - string exc; - ostringstream sb; - - sb << file << ":" << line << ": In function \"" << func << "\": \"" << eval_str << "\" evaluated to " << eval; - if ( errno != 0 ) - sb << endl << file << ":" << line << ": errno: " << errno << " (" << strerror( errno ) << ")"; - sb << ends; - exc = sb.str(); - cerr << exc << endl; - throw exc; - } -} - - -/** error handler for NULL result codes - - Whenever this is called with a NULL argument, it will throw an - exception. Typically used with functions like malloc() and new(). - -*/ - -void real_fail_null( const void *eval, const char *eval_str, const char *func, const char *file, int line ) -{ - if ( eval == NULL ) - { - - string exc; - ostringstream sb; - - sb << file << ":" << line << ": In function \"" << func << "\": " << eval_str << " is NULL" << ends; - exc = sb.str(); - cerr << exc << endl; - throw exc; - } -} - - -void real_fail_if( bool eval, const char *eval_str, const char *func, const char *file, int line ) -{ - if ( eval == true ) - { - - string exc; - ostringstream sb; - - sb << file << ":" << line << ": In function \"" << func << "\": condition \"" << eval_str << "\" is true"; - if ( errno != 0 ) - sb << endl << file << ":" << line << ": errno: " << errno << " (" << strerror( errno ) << ")"; - sb << ends; - exc = sb.str(); - cerr << exc << endl; - throw exc; - } -} diff --git a/src/modules/kino/error.h b/src/modules/kino/error.h deleted file mode 100644 index 30dedb958..000000000 --- a/src/modules/kino/error.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* error.h Error handling -* Copyright (C) 2000 Arne Schirmacher -* -* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef _ERROR_H -#define _ERROR_H 1 - -#ifdef __cplusplus -extern "C" -{ -#endif - - /* - * Should check for gcc/g++ and version > 2.6 I suppose - */ -#ifndef __ASSERT_FUNCTION -# define __ASSERT_FUNCTION __PRETTY_FUNCTION__ -#endif - -#define fail_neg(eval) real_fail_neg (eval, #eval, __ASSERT_FUNCTION, __FILE__, __LINE__) -#define fail_null(eval) real_fail_null (eval, #eval, __ASSERT_FUNCTION, __FILE__, __LINE__) -#define fail_if(eval) real_fail_if (eval, #eval, __ASSERT_FUNCTION, __FILE__, __LINE__) - - void real_fail_neg ( int eval, const char * eval_str, const char * func, const char * file, int line ); - void real_fail_null ( const void * eval, const char * eval_str, const char * func, const char * file, int line ); - void real_fail_if ( bool eval, const char * eval_str, const char * func, const char * file, int line ); - - extern void sigpipe_clear( ); - extern int sigpipe_get( ); - -#ifdef __cplusplus -} -#endif - -#endif - diff --git a/src/modules/kino/factory.c b/src/modules/kino/factory.c deleted file mode 100644 index 1ccdfd898..000000000 --- a/src/modules/kino/factory.c +++ /dev/null @@ -1,28 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2005-2014 Meltytech, LLC - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -extern mlt_producer producer_kino_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -MLT_REPOSITORY -{ - MLT_REGISTER( mlt_service_producer_type, "kino", producer_kino_init ); -} diff --git a/src/modules/kino/filehandler.cc b/src/modules/kino/filehandler.cc deleted file mode 100644 index 864087ffd..000000000 --- a/src/modules/kino/filehandler.cc +++ /dev/null @@ -1,941 +0,0 @@ -/* -* filehandler.cc -- saving DV data into different file formats -* Copyright (C) 2000 Arne Schirmacher -* -* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -extern "C" { -#include -} - -#include -#include -#include -#include - -using std::cerr; -using std::endl; -using std::ostringstream; -using std::setw; -using std::setfill; - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// libdv header files -#ifdef HAVE_LIBDV -#include -#endif - -#include "filehandler.h" -#include "error.h" -#include "riff.h" -#include "avi.h" - -FileTracker *FileTracker::instance = NULL; - -FileTracker::FileTracker( ) : mode( CAPTURE_MOVIE_APPEND ) -{ - cerr << ">> Constructing File Capture tracker" << endl; -} - -FileTracker::~FileTracker( ) -{ - cerr << ">> Destroying File Capture tracker" << endl; -} - -FileTracker &FileTracker::GetInstance( ) -{ - if ( instance == NULL ) - instance = new FileTracker(); - - return *instance; -} - -void FileTracker::SetMode( FileCaptureMode mode ) -{ - this->mode = mode; -} - -FileCaptureMode FileTracker::GetMode( ) -{ - return this->mode; -} - -char *FileTracker::Get( int index ) -{ - return list[ index ]; -} - -void FileTracker::Add( const char *file ) -{ - if ( this->mode != CAPTURE_IGNORE ) - { - cerr << ">>>> Registering " << file << " with the tracker" << endl; - list.push_back( strdup( file ) ); - } -} - -unsigned int FileTracker::Size( ) -{ - return list.size(); -} - -void FileTracker::Clear( ) -{ - while ( Size() > 0 ) - { - free( list[ Size() - 1 ] ); - list.pop_back( ); - } - this->mode = CAPTURE_MOVIE_APPEND; -} - -FileHandler::FileHandler() : done( false ), autoSplit( false ), maxFrameCount( 999999 ), - framesWritten( 0 ), filename( "" ) -{ - /* empty body */ - timeStamp = 0; - everyNthFrame = 0; - framesToSkip = 0; - maxFileSize = 0; -} - - -FileHandler::~FileHandler() -{ - /* empty body */ -} - - -bool FileHandler::GetAutoSplit() const -{ - return autoSplit; -} - - -bool FileHandler::GetTimeStamp() const -{ - return timeStamp; -} - - -string FileHandler::GetBaseName() const -{ - return base; -} - - -string FileHandler::GetExtension() const -{ - return extension; -} - - -int FileHandler::GetMaxFrameCount() const -{ - return maxFrameCount; -} - -off_t FileHandler::GetMaxFileSize() const -{ - return maxFileSize; -} - -string FileHandler::GetFilename() const -{ - return filename; -} - - -void FileHandler::SetAutoSplit( bool flag ) -{ - autoSplit = flag; -} - - -void FileHandler::SetTimeStamp( bool flag ) -{ - timeStamp = flag; -} - - -void FileHandler::SetBaseName( const string& s ) -{ - base = s; -} - - -void FileHandler::SetMaxFrameCount( int count ) -{ - assert( count >= 0 ); - maxFrameCount = count; -} - - -void FileHandler::SetEveryNthFrame( int every ) -{ - assert ( every > 0 ); - - everyNthFrame = every; -} - - -void FileHandler::SetMaxFileSize( off_t size ) -{ - assert ( size >= 0 ); - maxFileSize = size; -} - - -#if 0 -void FileHandler::SetSampleFrame( const Frame& sample ) -{ - /* empty body */ -} -#endif - -bool FileHandler::Done() -{ - return done; -} - -#if 0 -bool FileHandler::WriteFrame( const Frame& frame ) -{ - static TimeCode prevTimeCode; - TimeCode timeCode; - - /* If the user wants autosplit, start a new file if a - new recording is detected. */ - prevTimeCode.sec = -1; - frame.GetTimeCode( timeCode ); - int time_diff = timeCode.sec - prevTimeCode.sec; - bool discontinuity = prevTimeCode.sec != -1 && ( time_diff > 1 || ( time_diff < 0 && time_diff > -59 ) ); - if ( FileIsOpen() && GetAutoSplit() == true && ( frame.IsNewRecording() || discontinuity ) ) - { - Close(); - } - - if ( FileIsOpen() == false ) - { - - string filename; - static int counter = 0; - - if ( GetTimeStamp() == true ) - { - ostringstream sb, sb2; - struct tm date; - string recDate; - - if ( ! frame.GetRecordingDate( date ) ) - { - struct timeval tv; - struct timezone tz; - gettimeofday( &tv, &tz ); - localtime_r( static_cast< const time_t * >( &tv.tv_sec ), &date ); - } - sb << setfill( '0' ) - << setw( 4 ) << date.tm_year + 1900 << '.' - << setw( 2 ) << date.tm_mon + 1 << '.' - << setw( 2 ) << date.tm_mday << '_' - << setw( 2 ) << date.tm_hour << '-' - << setw( 2 ) << date.tm_min << '-' - << setw( 2 ) << date.tm_sec; - recDate = sb.str(); - sb2 << GetBaseName() << recDate << GetExtension(); - filename = sb2.str(); - cerr << ">>> Trying " << filename << endl; - } - else - { - struct stat stats; - do - { - ostringstream sb; - sb << GetBaseName() << setfill( '0' ) << setw( 3 ) << ++ counter << GetExtension(); - filename = sb.str(); - cerr << ">>> Trying " << filename << endl; - } - while ( stat( filename.c_str(), &stats ) == 0 ); - } - - SetSampleFrame( frame ); - if ( Create( filename ) == false ) - { - cerr << ">>> Error creating file!" << endl; - return false; - } - framesWritten = 0; - framesToSkip = 0; - } - - /* write frame */ - - if ( framesToSkip == 0 ) - { - if ( 0 > Write( frame ) ) - { - cerr << ">>> Error writing frame!" << endl; - return false; - } - framesToSkip = everyNthFrame; - ++framesWritten; - } - framesToSkip--; - - /* If the frame count is exceeded, close the current file. - If the autosplit flag is set, a new file will be created in the next iteration. - If the flag is not set, we are done. */ - - if ( ( GetMaxFrameCount() > 0 ) && - ( framesWritten >= GetMaxFrameCount() ) ) - { - Close(); - done = !GetAutoSplit(); - } - - /* If the file size could be exceeded by another frame, close the current file. - If the autosplit flag is set, a new file will be created on the next iteration. - If the flag is not set, we are done. */ - /* not exact, but should be good enough to prevent going over. */ - if ( FileIsOpen() ) - { - AudioInfo info; - frame.GetAudioInfo( info ); - if ( ( GetFileSize() > 0 ) && ( GetMaxFileSize() > 0 ) && - ( GetFileSize() + frame.GetFrameSize() + info.samples * 4 + 12 ) - >= GetMaxFileSize() ) - { // 12 = sizeof chunk metadata - Close(); - done = !GetAutoSplit(); - } - } - prevTimeCode.sec = timeCode.sec; - return true; -} -#endif - -RawHandler::RawHandler() : fd( -1 ) -{ - extension = ".dv"; - numBlocks = 0; -} - - -RawHandler::~RawHandler() -{ - Close(); -} - - -bool RawHandler::FileIsOpen() -{ - return fd != -1; -} - - -bool RawHandler::Create( const string& filename ) -{ - fd = open( filename.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_NONBLOCK, 0644 ); - if ( fd != -1 ) - { - FileTracker::GetInstance().Add( filename.c_str() ); - this->filename = filename; - } - return ( fd != -1 ); -} - - -#if 0 -int RawHandler::Write( const Frame& frame ) -{ - int result = write( fd, frame.data, frame.GetFrameSize() ); - return result; -} -#endif - -int RawHandler::Close() -{ - if ( fd != -1 ) - { - close( fd ); - fd = -1; - } - return 0; -} - - -off_t RawHandler::GetFileSize() -{ - struct stat file_status; - fstat( fd, &file_status ); - return file_status.st_size; -} - -int RawHandler::GetTotalFrames() -{ - return GetFileSize() / ( 480 * numBlocks ); -} - - -bool RawHandler::Open( const char *s ) -{ - unsigned char data[ 4 ]; - assert( fd == -1 ); - fd = open( s, O_RDONLY | O_NONBLOCK ); - if ( fd < 0 ) - return false; - if ( read( fd, data, 4 ) < 0 ) - return false; - if ( lseek( fd, 0, SEEK_SET ) < 0 ) - return false; - numBlocks = ( ( data[ 3 ] & 0x80 ) == 0 ) ? 250 : 300; - filename = s; - return true; - -} - -int RawHandler::GetFrame( uint8_t *data, int frameNum ) -{ - assert( fd != -1 ); - int size = 480 * numBlocks; - if ( frameNum < 0 ) - return -1; - off_t offset = ( ( off_t ) frameNum * ( off_t ) size ); - fail_if( lseek( fd, offset, SEEK_SET ) == ( off_t ) - 1 ); - if ( read( fd, data, size ) > 0 ) - return 0; - else - return -1; -} - - -/***************************************************************************/ - - -AVIHandler::AVIHandler( int format ) : avi( NULL ), aviFormat( format ), isOpenDML( false ), - fccHandler( make_fourcc( "dvsd" ) ), channels( 2 ), isFullyInitialized( false ), - audioBuffer( NULL ) -{ - extension = ".avi"; - for ( int c = 0; c < 4; c++ ) - audioChannels[ c ] = NULL; - memset( &dvinfo, 0, sizeof( dvinfo ) ); -} - - -AVIHandler::~AVIHandler() -{ - delete audioBuffer; - audioBuffer = NULL; - - for ( int c = 0; c < 4; c++ ) - { - delete audioChannels[ c ]; - audioChannels[ c ] = NULL; - } - - delete avi; -} - -#if 0 -void AVIHandler::SetSampleFrame( const Frame& sample ) -{ - Pack pack; - sample.GetAudioInfo( audioInfo ); - sample.GetVideoInfo( videoInfo ); - - sample.GetAAUXPack( 0x50, pack ); - dvinfo.dwDVAAuxSrc = *( DWORD* ) ( pack.data + 1 ); - sample.GetAAUXPack( 0x51, pack ); - dvinfo.dwDVAAuxCtl = *( DWORD* ) ( pack.data + 1 ); - - sample.GetAAUXPack( 0x52, pack ); - dvinfo.dwDVAAuxSrc1 = *( DWORD* ) ( pack.data + 1 ); - sample.GetAAUXPack( 0x53, pack ); - dvinfo.dwDVAAuxCtl1 = *( DWORD* ) ( pack.data + 1 ); - - sample.GetVAUXPack( 0x60, pack ); - dvinfo.dwDVVAuxSrc = *( DWORD* ) ( pack.data + 1 ); - sample.GetVAUXPack( 0x61, pack ); - dvinfo.dwDVVAuxCtl = *( DWORD* ) ( pack.data + 1 ); - -#ifdef WITH_LIBDV - - if ( sample.decoder->std == e_dv_std_smpte_314m ) - fccHandler = make_fourcc( "dv25" ); -#endif -} -#endif - -bool AVIHandler::FileIsOpen() -{ - return avi != NULL; -} - - -bool AVIHandler::Create( const string& filename ) -{ - assert( avi == NULL ); - - switch ( aviFormat ) - { - - case AVI_DV1_FORMAT: - fail_null( avi = new AVI1File ); - if ( !avi || avi->Create( filename.c_str() ) == false ) - return false; - //avi->Init( videoInfo.isPAL ? AVI_PAL : AVI_NTSC, audioInfo.frequency, AVI_LARGE_INDEX ); - break; - - case AVI_DV2_FORMAT: - fail_null( avi = new AVI2File ); - if ( !avi || avi->Create( filename.c_str() ) == false ) - return false; - //if ( GetOpenDML() ) - //avi->Init( videoInfo.isPAL ? AVI_PAL : AVI_NTSC, audioInfo.frequency, - //( AVI_SMALL_INDEX | AVI_LARGE_INDEX ) ); - //else - //avi->Init( videoInfo.isPAL ? AVI_PAL : AVI_NTSC, audioInfo.frequency, - //( AVI_SMALL_INDEX ) ); - break; - - default: - assert( aviFormat == AVI_DV1_FORMAT || aviFormat == AVI_DV2_FORMAT ); - } - - avi->setDVINFO( dvinfo ); - avi->setFccHandler( make_fourcc( "iavs" ), fccHandler ); - avi->setFccHandler( make_fourcc( "vids" ), fccHandler ); - this->filename = filename; - FileTracker::GetInstance().Add( filename.c_str() ); - return ( avi != NULL ); -} - -#if 0 -int AVIHandler::Write( const Frame& frame ) -{ - assert( avi != NULL ); - try - { - return avi->WriteFrame( frame ) ? 0 : -1; - } - catch (...) - { - return -1; - } -} -#endif - -int AVIHandler::Close() -{ - if ( avi != NULL ) - { - avi->WriteRIFF(); - delete avi; - avi = NULL; - } - if ( audioBuffer != NULL ) - { - delete audioBuffer; - audioBuffer = NULL; - } - for ( int c = 0; c < 4; c++ ) - { - if ( audioChannels[ c ] != NULL ) - { - delete audioChannels[ c ]; - audioChannels[ c ] = NULL; - } - } - isFullyInitialized = false; - return 0; -} - -off_t AVIHandler::GetFileSize() -{ - return avi->GetFileSize(); -} - -int AVIHandler::GetTotalFrames() -{ - return avi->GetTotalFrames(); -} - - -bool AVIHandler::Open( const char *s ) -{ - assert( avi == NULL ); - fail_null( avi = new AVI1File ); - if ( avi->Open( s ) ) - { - avi->ParseRIFF(); - if ( ! ( - avi->verifyStreamFormat( make_fourcc( "dvsd" ) ) || - avi->verifyStreamFormat( make_fourcc( "DVSD" ) ) || - avi->verifyStreamFormat( make_fourcc( "dvcs" ) ) || - avi->verifyStreamFormat( make_fourcc( "DVCS" ) ) || - avi->verifyStreamFormat( make_fourcc( "dvcp" ) ) || - avi->verifyStreamFormat( make_fourcc( "DVCP" ) ) || - avi->verifyStreamFormat( make_fourcc( "CDVC" ) ) || - avi->verifyStreamFormat( make_fourcc( "cdvc" ) ) || - avi->verifyStreamFormat( make_fourcc( "DV25" ) ) || - avi->verifyStreamFormat( make_fourcc( "dv25" ) ) ) ) - return false; - avi->ReadIndex(); - if ( avi->verifyStream( make_fourcc( "auds" ) ) ) - aviFormat = AVI_DV2_FORMAT; - else - aviFormat = AVI_DV1_FORMAT; - isOpenDML = avi->isOpenDML(); - filename = s; - return true; - } - else - return false; - -} - -int AVIHandler::GetFrame( uint8_t *data, int frameNum ) -{ - int result = avi->GetDVFrame( data, frameNum ); -#if 0 - if ( result == 0 ) - { - /* get the audio from the audio stream, if available */ - if ( aviFormat == AVI_DV2_FORMAT ) - { - WAVEFORMATEX wav; - - if ( ! isFullyInitialized && - avi->getStreamFormat( ( void* ) &wav, make_fourcc( "auds" ) ) ) - { - if ( channels > 0 && channels < 5 ) - { - // Allocate interleaved audio buffer - audioBuffer = new int16_t[ 2 * DV_AUDIO_MAX_SAMPLES * channels ]; - - // Allocate non-interleaved audio buffers - for ( int c = 0; c < channels; c++ ) - audioChannels[ c ] = new int16_t[ 2 * DV_AUDIO_MAX_SAMPLES ]; - - // Get the audio parameters from AVI for subsequent calls to method - audioInfo.channels = wav.nChannels; - audioInfo.frequency = wav.nSamplesPerSec; - - // Skip initialization on subsequent calls to method - isFullyInitialized = true; - cerr << ">>> using audio from separate AVI audio stream" << endl; - } - } - - // Get the frame from AVI - int n = avi->getFrame( audioBuffer, frameNum, make_fourcc( "01wb" ) ); - if ( n > 0 ) - { - // Temporary pointer to audio scratch buffer - int16_t * s = audioBuffer; - - // Determine samples in this frame - audioInfo.samples = n / audioInfo.channels / sizeof( int16_t ); - - // Convert interleaved audio into non-interleaved - for ( int n = 0; n < audioInfo.samples; ++n ) - for ( int i = 0; i < audioInfo.channels; i++ ) - audioChannels[ i ][ n ] = *s++; - - // Write interleaved audio into frame - frame.EncodeAudio( audioInfo, audioChannels ); - } - } - - // Parse important metadata in DV bitstream - frame.ExtractHeader(); - } -#endif - return result; -} - - -void AVIHandler::SetOpenDML( bool flag ) -{ - isOpenDML = flag; -} - - -bool AVIHandler::GetOpenDML() const -{ - return isOpenDML; -} - - -/***************************************************************************/ - -#ifdef HAVE_LIBQUICKTIME - -#ifndef HAVE_LIBDV -#define DV_AUDIO_MAX_SAMPLES 1944 -#endif - -// Missing fourcc's in libquicktime (allows compilation) -#ifndef QUICKTIME_DV_AVID -#define QUICKTIME_DV_AVID "AVdv" -#endif - -#ifndef QUICKTIME_DV_AVID_A -#define QUICKTIME_DV_AVID_A "dvcp" -#endif - -#ifndef QUICKTIME_DVCPRO -#define QUICKTIME_DVCPRO "dvpp" -#endif - -QtHandler::QtHandler() : fd( NULL ) -{ - extension = ".mov"; - Init(); -} - - -QtHandler::~QtHandler() -{ - Close(); -} - -void QtHandler::Init() -{ - if ( fd != NULL ) - Close(); - - fd = NULL; - samplingRate = 0; - samplesPerBuffer = 0; - channels = 2; - audioBuffer = NULL; - audioChannelBuffer = NULL; - isFullyInitialized = false; -} - - -bool QtHandler::FileIsOpen() -{ - return fd != NULL; -} - - -bool QtHandler::Create( const string& filename ) -{ - Init(); - - if ( open( filename.c_str(), O_CREAT | O_TRUNC | O_RDWR | O_NONBLOCK, 0644 ) != -1 ) - { - fd = quicktime_open( const_cast( filename.c_str() ), 0, 1 ); - if ( fd != NULL ) - FileTracker::GetInstance().Add( filename.c_str() ); - } - else - return false; - this->filename = filename; - return true; -} - -void QtHandler::AllocateAudioBuffers() -{ - if ( channels > 0 && channels < 5 ) - { - audioBufferSize = DV_AUDIO_MAX_SAMPLES * 2; - audioBuffer = new int16_t[ audioBufferSize * channels ]; - - audioChannelBuffer = new short int * [ channels ]; - for ( int c = 0; c < channels; c++ ) - audioChannelBuffer[ c ] = new short int[ audioBufferSize ]; - isFullyInitialized = true; - } -} - -inline void QtHandler::DeinterlaceStereo16( void* pInput, int iBytes, - void* pLOutput, void* pROutput ) -{ - short int * piSampleInput = ( short int* ) pInput; - short int* piSampleLOutput = ( short int* ) pLOutput; - short int* piSampleROutput = ( short int* ) pROutput; - - while ( ( char* ) piSampleInput < ( ( char* ) pInput + iBytes ) ) - { - *piSampleLOutput++ = *piSampleInput++; - *piSampleROutput++ = *piSampleInput++; - } -} - -#if 0 -int QtHandler::Write( const Frame& frame ) -{ - if ( ! isFullyInitialized ) - { - AudioInfo audio; - - if ( frame.GetAudioInfo( audio ) ) - { - channels = 2; - quicktime_set_audio( fd, channels, audio.frequency, 16, QUICKTIME_TWOS ); - } - else - { - channels = 0; - } - - quicktime_set_video( fd, 1, 720, frame.IsPAL() ? 576 : 480, - frame.GetFrameRate(), QUICKTIME_DV ); - AllocateAudioBuffers(); - } - - int result = quicktime_write_frame( fd, const_cast( frame.data ), - frame.GetFrameSize(), 0 ); - - if ( channels > 0 ) - { - AudioInfo audio; - if ( frame.GetAudioInfo( audio ) && ( unsigned int ) audio.samples < audioBufferSize ) - { - long bytesRead = frame.ExtractAudio( audioBuffer ); - - DeinterlaceStereo16( audioBuffer, bytesRead, - audioChannelBuffer[ 0 ], - audioChannelBuffer[ 1 ] ); - - quicktime_encode_audio( fd, audioChannelBuffer, NULL, audio.samples ); - } - } - return result; -} -#endif - -int QtHandler::Close() -{ - if ( fd != NULL ) - { - quicktime_close( fd ); - fd = NULL; - } - if ( audioBuffer != NULL ) - { - delete audioBuffer; - audioBuffer = NULL; - } - if ( audioChannelBuffer != NULL ) - { - for ( int c = 0; c < channels; c++ ) - delete audioChannelBuffer[ c ]; - delete audioChannelBuffer; - audioChannelBuffer = NULL; - } - return 0; -} - - -off_t QtHandler::GetFileSize() -{ - struct stat file_status; - stat( filename.c_str(), &file_status ); - return file_status.st_size; -} - - -int QtHandler::GetTotalFrames() -{ - return ( int ) quicktime_video_length( fd, 0 ); -} - - -bool QtHandler::Open( const char *s ) -{ - Init(); - - fd = quicktime_open( s, 1, 0 ); - if ( fd == NULL ) - { - fprintf( stderr, "Error opening: %s\n", s ); - return false; - } - - if ( quicktime_has_video( fd ) <= 0 ) - { - fprintf( stderr, "There must be at least one video track in the input file (%s).\n", - s ); - Close(); - return false; - } - char * fcc = quicktime_video_compressor( fd, 0 ); - if ( strncmp( fcc, QUICKTIME_DV, 4 ) != 0 && - strncmp( fcc, QUICKTIME_DV_AVID, 4 ) != 0 && - strncmp( fcc, QUICKTIME_DV_AVID_A, 4 ) != 0 && - strncmp( fcc, QUICKTIME_DVCPRO, 4 ) != 0 ) - { - Close(); - return false; - } - if ( quicktime_has_audio( fd ) ) - channels = quicktime_track_channels( fd, 0 ); - filename = s; - return true; -} - -int QtHandler::GetFrame( uint8_t *data, int frameNum ) -{ - assert( fd != NULL ); - - quicktime_set_video_position( fd, frameNum, 0 ); - quicktime_read_frame( fd, data, 0 ); - -#ifdef HAVE_LIBDV - if ( quicktime_has_audio( fd ) ) - { - if ( ! isFullyInitialized ) - AllocateAudioBuffers(); - - // Fetch the frequency of the audio track and calc number of samples needed - int frequency = quicktime_sample_rate( fd, 0 ); - float fps = ( data[ 3 ] & 0x80 ) ? 25.0f : 29.97f; - int samples = mlt_sample_calculator( fps, frequency, frameNum ); - int64_t seek = mlt_sample_calculator_to_now( fps, frequency, frameNum ); - - // Obtain a dv encoder and initialise it with minimal info - dv_encoder_t *encoder = dv_encoder_new( 0, 0, 0 ); - encoder->isPAL = ( data[ 3 ] & 0x80 ); - encoder->samples_this_frame = samples; - - // Seek to the calculated position and decode - quicktime_set_audio_position( fd, seek, 0 ); - lqt_decode_audio( fd, audioChannelBuffer, NULL, (long) samples ); - - // Encode the audio on the frame and done - dv_encode_full_audio( encoder, audioChannelBuffer, channels, frequency, data ); - dv_encoder_free( encoder ); - } -#endif - - return 0; -} -#endif diff --git a/src/modules/kino/filehandler.h b/src/modules/kino/filehandler.h deleted file mode 100644 index fdab94183..000000000 --- a/src/modules/kino/filehandler.h +++ /dev/null @@ -1,217 +0,0 @@ -/* -* filehandler.h -* Copyright (C) 2000 Arne Schirmacher -* -* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -#ifndef _FILEHANDLER_H -#define _FILEHANDLER_H - -// enum { PAL_FORMAT, NTSC_FORMAT, AVI_DV1_FORMAT, AVI_DV2_FORMAT, QT_FORMAT, RAW_FORMAT, TEST_FORMAT, UNDEFINED }; - -#include -using std::vector; - -#include -using std::string; - -#include "riff.h" -#include "avi.h" -#include -#include - -enum { AVI, PLAYLIST, RAW_DV, QT, UNKNOWN_FORMAT }; -enum { PAL_FORMAT, NTSC_FORMAT, AVI_DV1_FORMAT, AVI_DV2_FORMAT, QT_FORMAT, RAW_FORMAT, TEST_FORMAT, UNDEFINED }; -enum { DISPLAY_XX, DISPLAY_GDKRGB, DISPLAY_GDKRGB32, DISPLAY_XV, DISPLAY_SDL }; - -enum { NORM_UNSPECIFIED=0, NORM_PAL=1, NORM_NTSC=2 }; -enum { AUDIO_32KHZ=0, AUDIO_44KHZ=1, AUDIO_48KHZ=2 }; -enum { ASPECT_43=0, ASPECT_169=1 }; - -enum FileCaptureMode { - CAPTURE_IGNORE, - CAPTURE_FRAME_APPEND, - CAPTURE_FRAME_INSERT, - CAPTURE_MOVIE_APPEND -}; - -class FileTracker -{ -protected: - FileTracker(); - ~FileTracker(); -public: - static FileTracker &GetInstance( ); - void SetMode( FileCaptureMode ); - FileCaptureMode GetMode( ); - unsigned int Size(); - char *Get( int ); - void Add( const char * ); - void Clear( ); -private: - static FileTracker *instance; - vector list; - FileCaptureMode mode; -}; - -class FileHandler -{ -public: - - FileHandler(); - virtual ~FileHandler(); - - virtual bool GetAutoSplit() const; - virtual bool GetTimeStamp() const; - virtual string GetBaseName() const; - virtual string GetExtension() const; - virtual int GetMaxFrameCount() const; - virtual off_t GetMaxFileSize() const; - virtual off_t GetFileSize() = 0; - virtual int GetTotalFrames() = 0; - virtual string GetFilename() const; - - virtual void SetAutoSplit( bool ); - virtual void SetTimeStamp( bool ); - virtual void SetBaseName( const string& base ); - virtual void SetMaxFrameCount( int ); - virtual void SetEveryNthFrame( int ); - virtual void SetMaxFileSize( off_t ); - //virtual void SetSampleFrame( const Frame& sample ); - - //virtual bool WriteFrame( const Frame& frame ); - virtual bool FileIsOpen() = 0; - virtual bool Create( const string& filename ) = 0; - //virtual int Write( const Frame& frame ) = 0; - virtual int Close() = 0; - virtual bool Done( void ); - - virtual bool Open( const char *s ) = 0; - virtual int GetFrame( uint8_t *data, int frameNum ) = 0; - int GetFramesWritten() const - { - return framesWritten; - } - -protected: - bool done; - bool autoSplit; - bool timeStamp; - int maxFrameCount; - int framesWritten; - int everyNthFrame; - int framesToSkip; - off_t maxFileSize; - string base; - string extension; - string filename; -}; - - -class RawHandler: public FileHandler -{ -public: - int fd; - - RawHandler(); - ~RawHandler(); - - bool FileIsOpen(); - bool Create( const string& filename ); - //int Write( const Frame& frame ); - int Close(); - off_t GetFileSize(); - int GetTotalFrames(); - bool Open( const char *s ); - int GetFrame( uint8_t *data, int frameNum ); -private: - int numBlocks; -}; - - -class AVIHandler: public FileHandler -{ -public: - AVIHandler( int format = AVI_DV1_FORMAT ); - ~AVIHandler(); - - //void SetSampleFrame( const Frame& sample ); - bool FileIsOpen(); - bool Create( const string& filename ); - //int Write( const Frame& frame ); - int Close(); - off_t GetFileSize(); - int GetTotalFrames(); - bool Open( const char *s ); - int GetFrame( uint8_t *data, int frameNum ); - bool GetOpenDML() const; - void SetOpenDML( bool ); - int GetFormat() const - { - return aviFormat; - } - -protected: - AVIFile *avi; - int aviFormat; - //AudioInfo audioInfo; - //VideoInfo videoInfo; - bool isOpenDML; - DVINFO dvinfo; - FOURCC fccHandler; - int channels; - bool isFullyInitialized; - int16_t *audioBuffer; - int16_t *audioChannels[ 4 ]; -}; - - -#ifdef HAVE_LIBQUICKTIME -#include - -class QtHandler: public FileHandler -{ -public: - QtHandler(); - ~QtHandler(); - - bool FileIsOpen(); - bool Create( const string& filename ); - //int Write( const Frame& frame ); - int Close(); - off_t GetFileSize(); - int GetTotalFrames(); - bool Open( const char *s ); - int GetFrame( uint8_t *data, int frameNum ); - void AllocateAudioBuffers(); - -private: - quicktime_t *fd; - long samplingRate; - int samplesPerBuffer; - int channels; - bool isFullyInitialized; - unsigned int audioBufferSize; - int16_t *audioBuffer; - short int** audioChannelBuffer; - - void Init(); - inline void DeinterlaceStereo16( void* pInput, int iBytes, void* pLOutput, void* pROutput ); - -}; -#endif - -#endif diff --git a/src/modules/kino/gpl b/src/modules/kino/gpl deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/modules/kino/kino_wrapper.cc b/src/modules/kino/kino_wrapper.cc deleted file mode 100644 index fca7106b5..000000000 --- a/src/modules/kino/kino_wrapper.cc +++ /dev/null @@ -1,108 +0,0 @@ -/* - * kino_wrapper.cc -- c wrapper for kino file handler - * Copyright (C) 2005-2014 Meltytech, LLC - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include "kino_wrapper.h" -#include "filehandler.h" - -extern "C" -{ - -#include - -struct kino_wrapper_s -{ - FileHandler *handler; - int is_pal; -}; - -kino_wrapper kino_wrapper_init( ) -{ - kino_wrapper self = ( kino_wrapper )malloc( sizeof( kino_wrapper_s ) ); - if ( self != NULL ) - self->handler = NULL; - return self; -} - -int kino_wrapper_open( kino_wrapper self, char *src ) -{ - if ( self != NULL ) - { - // Rough file determination based on file type - if ( strncasecmp( strrchr( src, '.' ), ".avi", 4 ) == 0 ) - self->handler = new AVIHandler( ); - else if ( strncasecmp( strrchr( src, '.' ), ".dv", 3 ) == 0 || strncasecmp( strrchr( src, '.' ), ".dif", 4 ) == 0 ) - self->handler = new RawHandler( ); - #ifdef HAVE_LIBQUICKTIME - else if ( strncasecmp( strrchr( src, '.' ), ".mov", 4 ) == 0 ) - self->handler = new QtHandler( ); - #endif - - // Open the file if we have a handler - if ( self->handler != NULL ) - if ( !self->handler->Open( src ) ) - self = NULL; - - // Check the first frame to see if it's PAL or NTSC - if ( self != NULL && self->handler != NULL ) - { - uint8_t *data = ( uint8_t * )mlt_pool_alloc( 144000 ); - if ( self->handler->GetFrame( data, 0 ) == 0 ) - self->is_pal = data[3] & 0x80; - else - self = NULL; - mlt_pool_release( data ); - } - } - - return kino_wrapper_is_open( self ); -} - -int kino_wrapper_get_frame_count( kino_wrapper self ) -{ - return self != NULL && self->handler != NULL ? self->handler->GetTotalFrames( ) : 0; -} - -int kino_wrapper_is_open( kino_wrapper self ) -{ - return self != NULL && self->handler != NULL ? self->handler->FileIsOpen( ) : 0; -} - -int kino_wrapper_is_pal( kino_wrapper self ) -{ - return self != NULL ? self->is_pal : 0; -} - -int kino_wrapper_get_frame( kino_wrapper self, uint8_t *data, int index ) -{ - return self != NULL && self->handler != NULL ? !self->handler->GetFrame( data, index ) : 0; -} - -void kino_wrapper_close( kino_wrapper self ) -{ - if ( self ) - delete self->handler; - free( self ); -} - -} - - diff --git a/src/modules/kino/kino_wrapper.h b/src/modules/kino/kino_wrapper.h deleted file mode 100644 index f96ebddc1..000000000 --- a/src/modules/kino/kino_wrapper.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * kino_wrapper.h -- c wrapper for kino file handler - * Copyright (C) 2005-2014 Meltytech, LLC - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef MLT_PRODUCER_KINO_WRAPPER_H_ -#define MLT_PRODUCER_KINO_WRAPPER_H_ - -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -typedef struct kino_wrapper_s *kino_wrapper; - -extern kino_wrapper kino_wrapper_init( ); -extern int kino_wrapper_open( kino_wrapper, char * ); -extern int kino_wrapper_is_open( kino_wrapper ); -extern int kino_wrapper_is_pal( kino_wrapper ); -extern int kino_wrapper_get_frame_count( kino_wrapper ); -extern int kino_wrapper_get_frame( kino_wrapper, uint8_t *, int ); -extern void kino_wrapper_close( kino_wrapper ); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/modules/kino/producer_kino.c b/src/modules/kino/producer_kino.c deleted file mode 100644 index 21696ce71..000000000 --- a/src/modules/kino/producer_kino.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * producer_kino.c -- a DV file format parser - * Copyright (C) 2005-2014 Meltytech, LLC - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include "kino_wrapper.h" - -/* NB: This is an abstract producer - it provides no codec support whatsoever. */ - -#define FRAME_SIZE_525_60 10 * 150 * 80 -#define FRAME_SIZE_625_50 12 * 150 * 80 - -typedef struct producer_kino_s *producer_kino; - -struct producer_kino_s -{ - struct mlt_producer_s parent; - kino_wrapper wrapper; -}; - -static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int index ); -static void producer_close( mlt_producer parent ); - -mlt_producer producer_kino_init( mlt_profile profile, mlt_service_type type, const char *id, char *filename ) -{ - kino_wrapper wrapper = kino_wrapper_init( ); - - if ( kino_wrapper_open( wrapper, filename ) ) - { - producer_kino this = calloc( 1, sizeof( struct producer_kino_s ) ); - - if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 ) - { - mlt_producer producer = &this->parent; - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - double fps = kino_wrapper_is_pal( wrapper ) ? 25 : 30000.0 / 1001.0; - - // Assign the wrapper - this->wrapper = wrapper; - - // Pass wrapper properties (frame rate, count etc) - mlt_properties_set_position( properties, "length", kino_wrapper_get_frame_count( wrapper ) ); - mlt_properties_set_position( properties, "in", 0 ); - mlt_properties_set_position( properties, "out", kino_wrapper_get_frame_count( wrapper ) - 1 ); - mlt_properties_set_double( properties, "real_fps", fps ); - mlt_properties_set( properties, "resource", filename ); - - // Register transport implementation with the producer - producer->close = ( mlt_destructor )producer_close; - - // Register our get_frame implementation with the producer - producer->get_frame = producer_get_frame; - - // Return the producer - return producer; - } - free( this ); - } - - kino_wrapper_close( wrapper ); - - return NULL; -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - producer_kino this = producer->child; - uint8_t *data = mlt_pool_alloc( FRAME_SIZE_625_50 ); - - // Obtain the current frame number - uint64_t position = mlt_producer_frame( producer ); - - // Create an empty frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - // Seek and fetch - if ( kino_wrapper_get_frame( this->wrapper, data, position ) ) - { - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Determine if we're PAL or NTSC - int is_pal = kino_wrapper_is_pal( this->wrapper ); - - // Pass the dv data - mlt_properties_set_data( properties, "dv_data", data, FRAME_SIZE_625_50, ( mlt_destructor )mlt_pool_release, NULL ); - - // Update other info on the frame - mlt_properties_set_int( properties, "width", 720 ); - mlt_properties_set_int( properties, "height", is_pal ? 576 : 480 ); - mlt_properties_set_int( properties, "top_field_first", is_pal ? 0 : ( data[ 5 ] & 0x07 ) == 0 ? 0 : 1 ); - } - else - { - mlt_pool_release( data ); - } - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - if ( parent != NULL ) - { - // Obtain this - producer_kino this = parent->child; - - // Close the file - if ( this != NULL ) - kino_wrapper_close( this->wrapper ); - - // Close the parent - parent->close = NULL; - mlt_producer_close( parent ); - - // Free the memory - free( this ); - } -} diff --git a/src/modules/kino/riff.cc b/src/modules/kino/riff.cc deleted file mode 100644 index 162cc51bd..000000000 --- a/src/modules/kino/riff.cc +++ /dev/null @@ -1,659 +0,0 @@ -/* -* riff.cc library for RIFF file format i/o -* Copyright (C) 2000 - 2002 Arne Schirmacher -* -* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -// C++ includes - -#include -//#include -#include -#include - -using std::cout; -using std::hex; -using std::dec; -using std::setw; -using std::setfill; -using std::endl; - -// C includes - -#include -#include -#include - -// local includes - -#include "error.h" -#include "riff.h" - - -/** make a 32 bit "string-id" - - \param s a pointer to 4 chars - \return the 32 bit "string id" - \bugs It is not checked whether we really have 4 characters - - Some compilers understand constants like int id = 'ABCD'; but I - could not get it working on the gcc compiler so I had to use this - workaround. We can now use id = make_fourcc("ABCD") instead. */ - -FOURCC make_fourcc( const char *s ) -{ - if ( s[ 0 ] == 0 ) - return 0; - else - return *( ( FOURCC* ) s ); -} - - -RIFFDirEntry::RIFFDirEntry() -{ - type = 0; - name = 0; - length = 0; - offset = 0; - parent = 0; - written = 0; -} - - -RIFFDirEntry::RIFFDirEntry ( FOURCC t, FOURCC n, int l, int o, int p ) : type( t ), name( n ), length( l ), offset( o ), parent( p ), written( 0 ) -{} - - -/** Creates the object without an output file. - -*/ - -RIFFFile::RIFFFile() : fd( -1 ) -{ - pthread_mutex_init( &file_mutex, NULL ); -} - - -/* Copy constructor - - Duplicate the file descriptor -*/ - -RIFFFile::RIFFFile( const RIFFFile& riff ) : fd( -1 ) -{ - if ( riff.fd != -1 ) - { - fd = dup( riff.fd ); - } - directory = riff.directory; -} - - -/** Destroys the object. - - If it has an associated opened file, close it. */ - -RIFFFile::~RIFFFile() -{ - Close(); - pthread_mutex_destroy( &file_mutex ); -} - - -RIFFFile& RIFFFile::operator=( const RIFFFile& riff ) -{ - if ( fd != riff.fd ) - { - Close(); - if ( riff.fd != -1 ) - { - fd = dup( riff.fd ); - } - directory = riff.directory; - } - return *this; -} - - -/** Creates or truncates the file. - - \param s the filename -*/ - -bool RIFFFile::Create( const char *s ) -{ - fd = open( s, O_RDWR | O_NONBLOCK | O_CREAT | O_TRUNC, 00644 ); - - if ( fd == -1 ) - return false; - else - return true; -} - - -/** Opens the file read only. - - \param s the filename -*/ - -bool RIFFFile::Open( const char *s ) -{ - fd = open( s, O_RDONLY | O_NONBLOCK ); - - if ( fd == -1 ) - return false; - else - return true; -} - - -/** Destroys the object. - - If it has an associated opened file, close it. */ - -void RIFFFile::Close() -{ - if ( fd != -1 ) - { - close( fd ); - fd = -1; - } -} - - -/** Adds an entry to the list of containers. - - \param type the type of this entry - \param name the name - \param length the length of the data in the container - \param list the container in which this object is contained. - \return the ID of the newly created entry - - The topmost object is not contained in any other container. Use - the special ID RIFF_NO_PARENT to create the topmost object. */ - -int RIFFFile::AddDirectoryEntry( FOURCC type, FOURCC name, off_t length, int list ) -{ - /* Put all parameters in an RIFFDirEntry object. The offset is - currently unknown. */ - - RIFFDirEntry entry( type, name, length, 0 /* offset */, list ); - - /* If the new chunk is in a list, then get the offset and size - of that list. The offset of this chunk is the end of the list - (parent_offset + parent_length) plus the size of the chunk - header. */ - - if ( list != RIFF_NO_PARENT ) - { - RIFFDirEntry parent = GetDirectoryEntry( list ); - entry.offset = parent.offset + parent.length + RIFF_HEADERSIZE; - } - - /* The list which this new chunk is a member of has now increased in - size. Get that directory entry and bump up its length by the size - of the chunk. Since that list may also be contained in another - list, walk up to the top of the tree. */ - - while ( list != RIFF_NO_PARENT ) - { - RIFFDirEntry parent = GetDirectoryEntry( list ); - parent.length += RIFF_HEADERSIZE + length; - SetDirectoryEntry( list, parent ); - list = parent.parent; - } - - directory.insert( directory.end(), entry ); - - return directory.size() - 1; -} - - -/** Modifies an entry. - - \param i the ID of the entry which is to modify - \param type the type of this entry - \param name the name - \param length the length of the data in the container - \param list the container in which this object is contained. - \note Do not change length, offset, or the parent container. - \note Do not change an empty name ("") to a name and vice versa */ - -void RIFFFile::SetDirectoryEntry( int i, FOURCC type, FOURCC name, off_t length, off_t offset, int list ) -{ - RIFFDirEntry entry( type, name, length, offset, list ); - - assert( i >= 0 && i < ( int ) directory.size() ); - - directory[ i ] = entry; -} - - -/** Modifies an entry. - - The entry.written flag is set to false because the contents has been modified - - \param i the ID of the entry which is to modify - \param entry the new entry - \note Do not change length, offset, or the parent container. - \note Do not change an empty name ("") to a name and vice versa */ - -void RIFFFile::SetDirectoryEntry( int i, RIFFDirEntry &entry ) -{ - assert( i >= 0 && i < ( int ) directory.size() ); - - entry.written = false; - directory[ i ] = entry; -} - - -/** Retrieves an entry. - - Gets the most important member variables. - - \param i the ID of the entry to retrieve - \param type - \param name - \param length - \param offset - \param list */ - -void RIFFFile::GetDirectoryEntry( int i, FOURCC &type, FOURCC &name, off_t &length, off_t &offset, int &list ) const -{ - RIFFDirEntry entry; - - assert( i >= 0 && i < ( int ) directory.size() ); - - entry = directory[ i ]; - type = entry.type; - name = entry.name; - length = entry.length; - offset = entry.offset; - list = entry.parent; -} - - -/** Retrieves an entry. - - Gets the whole RIFFDirEntry object. - - \param i the ID of the entry to retrieve - \return the entry */ - -RIFFDirEntry RIFFFile::GetDirectoryEntry( int i ) const -{ - assert( i >= 0 && i < ( int ) directory.size() ); - - return directory[ i ]; -} - - -/** Calculates the total size of the file - - \return the size the file in bytes -*/ - -off_t RIFFFile::GetFileSize( void ) const -{ - - /* If we have at least one entry, return the length field - of the FILE entry, which is the length of its contents, - which is the actual size of whatever is currently in the - AVI directory structure. - - Note that the first entry does not belong to the AVI - file. - - If we don't have any entry, the file size is zero. */ - - if ( directory.size() > 0 ) - return directory[ 0 ].length; - else - return 0; -} - - -/** prints the attributes of the entry - - \param i the ID of the entry to print -*/ - -void RIFFFile::PrintDirectoryEntry ( int i ) const -{ - RIFFDirEntry entry; - RIFFDirEntry parent; - FOURCC entry_name; - FOURCC list_name; - - /* Get all attributes of the chunk object. If it is contained - in a list, get the name of the list too (otherwise the name of - the list is blank). If the chunk object doesn´t have a name (only - LISTs and RIFFs have a name), the name is blank. */ - - entry = GetDirectoryEntry( i ); - if ( entry.parent != RIFF_NO_PARENT ) - { - parent = GetDirectoryEntry( entry.parent ); - list_name = parent.name; - } - else - { - list_name = make_fourcc( " " ); - } - if ( entry.name != 0 ) - { - entry_name = entry.name; - } - else - { - entry_name = make_fourcc( " " ); - } - - /* Print out the ascii representation of type and name, as well as - length and file offset. */ - - cout << hex << setfill( '0' ) << "type: " - << ((char *)&entry.type)[0] - << ((char *)&entry.type)[1] - << ((char *)&entry.type)[2] - << ((char *)&entry.type)[3] - << " name: " - << ((char *)&entry_name)[0] - << ((char *)&entry_name)[1] - << ((char *)&entry_name)[2] - << ((char *)&entry_name)[3] - << " length: 0x" << setw( 12 ) << entry.length - << " offset: 0x" << setw( 12 ) << entry.offset - << " list: " - << ((char *)&list_name)[0] - << ((char *)&list_name)[1] - << ((char *)&list_name)[2] - << ((char *)&list_name)[3] << dec << endl; - - /* print the content itself */ - - PrintDirectoryEntryData( entry ); -} - - -/** prints the contents of the entry - - Prints a readable representation of the contents of an index. - Override this to print out any objects you store in the RIFF file. - - \param entry the entry to print */ - -void RIFFFile::PrintDirectoryEntryData( const RIFFDirEntry &entry ) const - {} - - -/** prints the contents of the whole directory - - Prints a readable representation of the contents of an index. - Override this to print out any objects you store in the RIFF file. - - \param entry the entry to print */ - -void RIFFFile::PrintDirectory() const -{ - int i; - int count = directory.size(); - - for ( i = 0; i < count; ++i ) - PrintDirectoryEntry( i ); -} - - -/** finds the index - - finds the index of a given directory entry type - - \todo inefficient if the directory has lots of items - \param type the type of the entry to find - \param n the zero-based instance of type to locate - \return the index of the found object in the directory, or -1 if not found */ - -int RIFFFile::FindDirectoryEntry ( FOURCC type, int n ) const -{ - int i, j = 0; - int count = directory.size(); - - for ( i = 0; i < count; ++i ) - if ( directory[ i ].type == type ) - { - if ( j == n ) - return i; - j++; - } - - return -1; -} - - -/** Reads all items that are contained in one list - - Read in one chunk and add it to the directory. If the chunk - happens to be of type LIST, then call ParseList recursively for - it. - - \param parent The id of the item to process -*/ - -void RIFFFile::ParseChunk( int parent ) -{ - FOURCC type; - DWORD length; - int typesize; - - /* Check whether it is a LIST. If so, let ParseList deal with it */ - - fail_if( read( fd, &type, sizeof( type ) ) != sizeof( type )); - if ( type == make_fourcc( "LIST" ) ) - { - typesize = (int) -sizeof( type ); - fail_if( lseek( fd, typesize, SEEK_CUR ) == ( off_t ) - 1 ); - ParseList( parent ); - } - - /* it is a normal chunk, create a new directory entry for it */ - - else - { - fail_neg( read( fd, &length, sizeof( length ) ) ); - if ( length & 1 ) - length++; - AddDirectoryEntry( type, 0, length, parent ); - fail_if( lseek( fd, length, SEEK_CUR ) == ( off_t ) - 1 ); - } -} - - -/** Reads all items that are contained in one list - - \param parent The id of the list to process - -*/ - -void RIFFFile::ParseList( int parent ) -{ - FOURCC type; - FOURCC name; - int list; - DWORD length; - off_t pos; - off_t listEnd; - - /* Read in the chunk header (type and length). */ - fail_neg( read( fd, &type, sizeof( type ) ) ); - fail_neg( read( fd, &length, sizeof( length ) ) ); - - if ( length & 1 ) - length++; - - /* The contents of the list starts here. Obtain its offset. The list - name (4 bytes) is already part of the contents). */ - - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - fail_neg( read( fd, &name, sizeof( name ) ) ); - - /* Add an entry for this list. */ - - list = AddDirectoryEntry( type, name, sizeof( name ), parent ); - - /* Read in any chunks contained in this list. This list is the - parent for all chunks it contains. */ - - listEnd = pos + length; - while ( pos < listEnd ) - { - ParseChunk( list ); - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - } -} - - -/** Reads the directory structure of the whole RIFF file - -*/ - -void RIFFFile::ParseRIFF( void ) -{ - FOURCC type; - DWORD length; - off_t filesize = 0; - off_t pos; - int container = AddDirectoryEntry( make_fourcc( "FILE" ), make_fourcc( "FILE" ), 0, RIFF_NO_PARENT ); - - pos = lseek( fd, 0, SEEK_SET ); - fail_if( pos == -1 ); - - /* calculate file size from RIFF header instead from physical file. */ - - while ( ( read( fd, &type, sizeof( type ) ) > 0 ) && - ( read( fd, &length, sizeof( length ) ) > 0 ) && - ( type == make_fourcc( "RIFF" ) ) ) - { - - filesize += length + RIFF_HEADERSIZE; - - fail_if( lseek( fd, pos, SEEK_SET ) == ( off_t ) - 1 ); - ParseList( container ); - pos = lseek( fd, 0, SEEK_CUR ); - fail_if( pos == ( off_t ) - 1 ); - } -} - - -/** Reads one item including its contents from the RIFF file - - \param chunk_index The index of the item to write - \param data A pointer to the data - -*/ - -void RIFFFile::ReadChunk( int chunk_index, void *data, off_t data_len ) -{ - RIFFDirEntry entry; - - entry = GetDirectoryEntry( chunk_index ); - pthread_mutex_lock( &file_mutex ); - fail_if( lseek( fd, entry.offset, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( read( fd, data, entry.length > data_len ? data_len : entry.length ) ); - pthread_mutex_unlock( &file_mutex ); -} - - -/** Writes one item including its contents to the RIFF file - - \param chunk_index The index of the item to write - \param data A pointer to the data - -*/ - -void RIFFFile::WriteChunk( int chunk_index, const void *data ) -{ - RIFFDirEntry entry; - - entry = GetDirectoryEntry( chunk_index ); - pthread_mutex_lock( &file_mutex ); - fail_if( lseek( fd, entry.offset - RIFF_HEADERSIZE, SEEK_SET ) == ( off_t ) - 1 ); - fail_neg( write( fd, &entry.type, sizeof( entry.type ) ) ); - DWORD length = entry.length; - fail_neg( write( fd, &length, sizeof( length ) ) ); - fail_neg( write( fd, data, entry.length ) ); - pthread_mutex_unlock( &file_mutex ); - - /* Remember that this entry already has been written. */ - - directory[ chunk_index ].written = true; -} - - -/** Writes out the directory structure - - For all items in the directory list that have not been written - yet, it seeks to the file position where that item should be - stored and writes the type and length field. If the item has a - name, it will also write the name field. - - \note It does not write the contents of any item. Use WriteChunk to do that. */ - -void RIFFFile::WriteRIFF( void ) -{ - int i; - RIFFDirEntry entry; - int count = directory.size(); - - /* Start at the second entry (RIFF), since the first entry (FILE) - is needed only for internal purposes and is not written to the - file. */ - - for ( i = 1; i < count; ++i ) - { - - /* Only deal with entries that haven´t been written */ - - entry = GetDirectoryEntry( i ); - if ( entry.written == false ) - { - - /* A chunk entry consist of its type and length, a list - entry has an additional name. Look up the entry, seek - to the start of the header, which is at the offset of - the data start minus the header size and write out the - items. */ - - fail_if( lseek( fd, entry.offset - RIFF_HEADERSIZE, SEEK_SET ) == ( off_t ) - 1 ) ; - fail_neg( write( fd, &entry.type, sizeof( entry.type ) ) ); - DWORD length = entry.length; - fail_neg( write( fd, &length, sizeof( length ) ) ); - - /* If it has a name, it is a list. Write out the extra name - field. */ - - if ( entry.name != 0 ) - { - fail_neg( write( fd, &entry.name, sizeof( entry.name ) ) ); - } - - /* Remember that this entry already has been written. */ - - directory[ i ].written = true; - } - } -} diff --git a/src/modules/kino/riff.h b/src/modules/kino/riff.h deleted file mode 100644 index 810056326..000000000 --- a/src/modules/kino/riff.h +++ /dev/null @@ -1,143 +0,0 @@ -/* -* riff.h library for RIFF file format i/o -* Copyright (C) 2000 - 2002 Arne Schirmacher -* -* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -* Tag: $Name$ -* -* Change log: -* -* $Log$ -* Revision 1.2 2005/07/25 07:21:39 lilo_booter -* + fixes for opendml dv avi -* -* Revision 1.1 2005/04/15 14:28:26 lilo_booter -* Initial version -* -* Revision 1.14 2005/04/01 23:43:10 ddennedy -* apply endian fixes from Daniel Kobras -* -* Revision 1.13 2004/10/11 01:37:11 ddennedy -* mutex safety locks in RIFF and AVI classes, type 2 AVI optimization, mencoder export script -* -* Revision 1.12 2004/01/06 22:53:42 ddennedy -* metadata editing tweaks and bugfixes, new ui elements in preparation for publish functions -* -* Revision 1.11 2003/11/25 23:01:25 ddennedy -* cleanup and a few bugfixes -* -* Revision 1.10 2003/10/21 16:34:34 ddennedy -* GNOME2 port phase 1: initial checkin -* -* Revision 1.8.4.1 2002/11/25 04:48:31 ddennedy -* bugfix to report errors when loading files -* -* Revision 1.8 2002/04/21 06:36:40 ddennedy -* kindler avc and 1394 bus reset support in catpure page, honor max file size -* -* Revision 1.7 2002/04/09 06:53:42 ddennedy -* cleanup, new libdv 0.9.5, large AVI, dnd storyboard -* -* Revision 1.3 2002/03/25 21:34:25 arne -* Support for large (64 bit) files mostly completed -* -* Revision 1.2 2002/03/04 19:22:43 arne -* updated to latest Kino avi code -* -* Revision 1.1.1.1 2002/03/03 19:08:08 arne -* import of version 1.01 -* -*/ - -#ifndef _RIFF_H -#define _RIFF_H 1 - -#include -using std::vector; - -#include - -#include "endian_types.h" - -#define QUADWORD int64_le_t -#define DWORD int32_le_t -#define LONG u_int32_le_t -#define WORD int16_le_t -#define BYTE u_int8_le_t -#define FOURCC u_int32_t // No endian conversion needed. - -#define RIFF_NO_PARENT (-1) -#define RIFF_LISTSIZE (4) -#define RIFF_HEADERSIZE (8) - -#ifdef __cplusplus -extern "C" -{ - FOURCC make_fourcc( const char * s ); -} -#endif - -class RIFFDirEntry -{ -public: - FOURCC type; - FOURCC name; - off_t length; - off_t offset; - int parent; - int written; - - RIFFDirEntry(); - RIFFDirEntry( FOURCC t, FOURCC n, int l, int o, int p ); -}; - - -class RIFFFile -{ -public: - RIFFFile(); - RIFFFile( const RIFFFile& ); - virtual ~RIFFFile(); - RIFFFile& operator=( const RIFFFile& ); - - virtual bool Open( const char *s ); - virtual bool Create( const char *s ); - virtual void Close(); - virtual int AddDirectoryEntry( FOURCC type, FOURCC name, off_t length, int list ); - virtual void SetDirectoryEntry( int i, FOURCC type, FOURCC name, off_t length, off_t offset, int list ); - virtual void SetDirectoryEntry( int i, RIFFDirEntry &entry ); - virtual void GetDirectoryEntry( int i, FOURCC &type, FOURCC &name, off_t &length, off_t &offset, int &list ) const; - virtual RIFFDirEntry GetDirectoryEntry( int i ) const; - virtual off_t GetFileSize( void ) const; - virtual void PrintDirectoryEntry( int i ) const; - virtual void PrintDirectoryEntryData( const RIFFDirEntry &entry ) const; - virtual void PrintDirectory( void ) const; - virtual int FindDirectoryEntry( FOURCC type, int n = 0 ) const; - virtual void ParseChunk( int parent ); - virtual void ParseList( int parent ); - virtual void ParseRIFF( void ); - virtual void ReadChunk( int chunk_index, void *data, off_t data_len ); - virtual void WriteChunk( int chunk_index, const void *data ); - virtual void WriteRIFF( void ); - -protected: - int fd; - pthread_mutex_t file_mutex; - -private: - vector directory; -}; -#endif From 1212accc3c9cc7437b2841b596858365091cdb3d Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 8 Feb 2021 22:16:25 -0600 Subject: [PATCH 026/122] Remove deprecated linsys module --- docs/install.txt | 1 - src/modules/linsys/20-linsys.rules | 6 - src/modules/linsys/Makefile | 41 - src/modules/linsys/configure | 31 - src/modules/linsys/consumer_SDIstream.c | 672 ------- src/modules/linsys/consumer_sdi.yml | 12 - src/modules/linsys/deprecated | 0 src/modules/linsys/factory.c | 22 - src/modules/linsys/gpl | 0 src/modules/linsys/sdi_generator.c | 2411 ----------------------- src/modules/linsys/sdi_generator.h | 319 --- 11 files changed, 3515 deletions(-) delete mode 100644 src/modules/linsys/20-linsys.rules delete mode 100755 src/modules/linsys/Makefile delete mode 100755 src/modules/linsys/configure delete mode 100644 src/modules/linsys/consumer_SDIstream.c delete mode 100644 src/modules/linsys/consumer_sdi.yml delete mode 100644 src/modules/linsys/deprecated delete mode 100644 src/modules/linsys/factory.c delete mode 100644 src/modules/linsys/gpl delete mode 100644 src/modules/linsys/sdi_generator.c delete mode 100644 src/modules/linsys/sdi_generator.h diff --git a/docs/install.txt b/docs/install.txt index 71873d442..fa3562016 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -30,7 +30,6 @@ Last Revision: 2013-09-07 * gdk - GDK pango and pixbuf dependent services * jackrack - adapter for LADSPA audio plugins and JACK server * kdenlive - services contributed by Kdenlive project - * linsys - DVEO SDI card consumer (*) * lumas - wipe file generator for core's luma transition * motion_est - motion estimation-based filters (*) * normalize - audio normalisation functions (*) diff --git a/src/modules/linsys/20-linsys.rules b/src/modules/linsys/20-linsys.rules deleted file mode 100644 index 2f4f06db3..000000000 --- a/src/modules/linsys/20-linsys.rules +++ /dev/null @@ -1,6 +0,0 @@ -# udev rules for linsys cards to give members of the video group permissions -KERNEL=="sdi*[rt]x[0-9]*", MODE="0660", GROUP="video", \ - RUN+="/usr/bin/find /sys/$env{DEVPATH}/ -type f -execdir /bin/chmod 0660 {} + -execdir /bin/chgrp video {} +", OPTIONS="last_rule" -KERNEL=="asi*[rt]x[0-9]*", MODE="0660", GROUP="video", \ - RUN+="/usr/bin/find /sys/$env{DEVPATH}/ -type f -execdir /bin/chmod 0660 {} + -execdir /bin/chgrp video {} +", OPTIONS="last_rule" - diff --git a/src/modules/linsys/Makefile b/src/modules/linsys/Makefile deleted file mode 100755 index 143cb9d6e..000000000 --- a/src/modules/linsys/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt -lpthread - -include ../../../config.mak -include config.mak - -TARGET = ../libmltlinsys$(LIBSUF) - -OBJS = factory.o \ - consumer_SDIstream.o - -ifdef WITH_JPEG -CFLAGS += -DWITH_JPEG -LDFLAGS += -ljpeg -endif - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" - install -d "$(DESTDIR)$(mltdatadir)/linsys" - install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/linsys" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/linsys/configure b/src/modules/linsys/configure deleted file mode 100755 index 735daeed9..000000000 --- a/src/modules/linsys/configure +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -if [ "$help" = "1" ] -then - cat << EOF -Linsys options: - - --linsys-with-jpeg - Enable the option to export JPEGs (disabled by default) - -EOF - -else - if [ "$targetos" = "Darwin" ] || [ "$targetos" = "MinGW" ] - then - echo "- does not build on OS X or Windows: disabling" - touch ../disable-linsys - exit 0 - fi - - touch config.mak - - for i in "$@" - do - case $i in - --linsys-with-jpeg ) echo "WITH_JPEG=1" > config.mak ;; - esac - done - - exit 0 -fi - diff --git a/src/modules/linsys/consumer_SDIstream.c b/src/modules/linsys/consumer_SDIstream.c deleted file mode 100644 index a00e74a30..000000000 --- a/src/modules/linsys/consumer_SDIstream.c +++ /dev/null @@ -1,672 +0,0 @@ -/** - * - * MLT SDI Consumer: - * request video and audio data from MLT and generate an SDI stream - * - * Copyright (C) Broadcasting Center Europe S.A. http://www.bce.lu - * an RTL Group Company http://www.rtlgroup.com - * All rights reserved. - * - * E-mail: support_plasec@bce.lu - * - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - * DESCRIPTION: - * This software act as interface between the MLT Frameworkas as - * MLT Consumer and the Linear Systems Ltd. SMPTE 292M and SMPTE 259M-C boards. - * - * Linear Systems can be contacted at http://www.linsys.ca - * - ********************************************************************************** - * System : INTeL I686 64Bit - * OS : Linux SuSE Kernel 2.6.27.39-0.2-default - * Compiler: gcc 4.3.2 (c++) - ********************************************************************************** - * Project : MLT SDI Consumer for SD and HD - * Started by : Thomas Kurpick, Dipl.Inf. (FH) - ********************************************************************************** - * Supported and tested boards for SD-SDI or HD-SDI Output: - * PCI SDI Master™ (model 107) - * PCIe SDI Master™ (model 159) - * PCIe LP SDI Master™ FD (model 145) - * PCIe LP SDI Master™ Quad/o (model 180) - * PCIe LP HD-SDI Master™ O (model 193) - * - * Note: PCIe LP HD-SDI Master™ O (model 193) is an VidPort model and supports an - * separate video and audio interface. Device file: - * /dev/sdivideotx[] for active video data - * /dev/sdiaudiotx[] for pcm audio data - * - * This mlt consumer use the following device files: - * /dev/sditx[] (SD-PAL) up to 8 x AES (8 x stereo / 16 audio channels) - * /dev/sdivideotx[] (HD) - * /dev/sdiaudiotx[] (HD) up to 4 x AES (4 x stereo / 8 audio channels) - * - * - ********************************************************************************** - * Last modified by: - * Thomas Kurpick 08.Jan.2010 - * and - * Dan Dennedy 10.Feb.2010 - * Ver. 2.0 - * See also Git commit log. - * - ********************************************************************************** - * - * Consumer properties: - * 'dev_video' - * 'dev_audio' - * 'blanking' - * Only to monitor the SDI output a beta version of jpeg-writer is implemented. - * 'jpeg_files' a number for output interval - * 'save_jpegs' path for image - * - * EXAMPLE: - * - * SDI boards with full frame stream (with blanking): - * melt video.dv -consumer sdi:/dev/sditx0 - * melt video.dv -consumer sdi:/dev/sditx0 blanking=true - * melt video.dv -consumer sdi dev_video=/dev/sditx0 blanking=true - * melt video.dv audio_index=all -consumer sdi dev_video=/dev/sditx0 blanking=true - * - * SDI boards without full frame stream (without blanking): - * melt -profile atsc_1080i_50 video.mpeg audio_index=1 -consumer sdi dev_video=/dev/sdivideotx0 dev_audio=/dev/sdiaudiotx0 blanking=false - * melt -profile atsc_1080i_50 video.mpeg audio_index=all -consumer sdi dev_video=/dev/sdivideotx0 dev_audio=/dev/sdiaudiotx0 blanking=false - * melt -profile atsc_1080i_50 video.mpeg audio_index=all -consumer sdi dev_video=/dev/sdivideotx0 dev_audio=/dev/sdiaudiotx0 blanking=false jpeg_files=25 save_jpegs=channel_04.jpg - * - * - * SDI output formats and MLT profiles: - * ##################################################################################################################################################### - * ########## SMPTE 274M 1920 x 1080 Image Sample Structure ############################################################################################ - * ##################################################################################################################################################### - * System No. System nomenclature Form of scanning Frame rate Embedded Audio MLT profile Linsys board support (model) - * 4 1920 x 1080/60/I interlaced 30 HZ 4 x AES (8 channels) atsc_1080i_60 193 - * 5 1920 x 1080/59.94/I interlaced 30000/1001 ~ 29.97 HZ 4 x AES (8 channels) atsc_1080i_5994 193 - * 6 1920 x 1080/50/I interlaced 25 HZ 4 x AES (8 channels) atsc_1080i_50 193 - * 7 1920 x 1080/30/P progressive 30 HZ 4 x AES (8 channels) atsc_1080p_30 193 - * 8 1920 x 1080/29.97/P progressive 30000/1001 ~ 29.97 HZ 4 x AES (8 channels) atsc_1080p_2997 193 - * 9 1920 x 1080/25/P progressive 25 HZ 4 x AES (8 channels) atsc_1080p_25 193 - * 10 1920 x 1080/24/P progressive 24 HZ 4 x AES (8 channels) atsc_1080p_24 193 - * 11 1920 x 1080/23.98/P progressive 24000/1001 ~ 23.98 HZ 4 x AES (8 channels) atsc_1080p_2398 193 - * - * ##################################################################################################################################################### - * ########## SMPTE 296M 1280 × 720 Progressive Image Sample Structure ################################################################################# - * ##################################################################################################################################################### - * System No. System nomenclature Form of scanning Frame rate Embedded Audio MLT profile Linsys board support (model) - * 1 1280 × 720/60 progressive 60 HZ 4 x AES (8 channels) atsc_720p_60 193 - * 2 1280 × 720/59.94 progressive 60000/1001 ~ 59.97 HZ 4 x AES (8 channels) atsc_720p_5994 193 - * 3 1280 × 720/50 progressive 50 HZ 4 x AES (8 channels) atsc_720p_50 193 - * 4 1280 × 720/30 progressive 30 HZ 4 x AES (8 channels) atsc_720p_30 193 - * 5 1280 × 720/29.97 progressive 30000/1001 ~ 29.97 HZ 4 x AES (8 channels) atsc_720p_2997 193 - * 6 1280 × 720/25 progressive 25 HZ 4 x AES (8 channels) atsc_720p_25 193 - * 7 1280 × 720/24 progressive 24 HZ 4 x AES (8 channels) atsc_720p_24 193 - * 8 1280 × 720/23.98 progressive 24000/1001 ~ 23.98 HZ 4 x AES (8 channels) atsc_720p_2398 193 - * - * ##################################################################################################################################################### - * ########## SMPTE 125M 486i 29.97Hz & BT.656 576i 25Hz ############################################################################################### - * ##################################################################################################################################################### - * System No. System nomenclature Form of scanning Frame rate Embedded Audio MLT profile Linsys board support (model) - * SD PAL 720 × 576/50/I interlaced 25 HZ 8 x AES (16 channels) dv_pal 180,145,159,107 - * SD PAL 720 × 576/50/I interlaced 25 HZ 4 x AES (8 channels) dv_pal 193 - * SD NTSC 720 × 486/59.94/I interlaced 30000/1001 ~ 29.97 HZ 8 x AES (16 channels) sdi_486i_5994 TODO:180,145,159,107 - * SD NTSC 720 × 486/59.94/I interlaced 30000/1001 ~ 29.97 HZ 4 x AES (8 channels) sdi_486i_5994 193 - * - **/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WITH_JPEG -// for JPEG output -#include -#endif - -#include "sdi_generator.c" - -// alias for "struct consumer_SDIstream_s *" , now we can write "consumer_SDIstream". Makes it more readable... -typedef struct consumer_SDIstream_s *consumer_SDIstream; - -struct consumer_SDIstream_s { - // Most of these values are set to their defaults by the parent consumer - struct mlt_consumer_s parent; // This is the basic Consumer from which we fetch our data - mlt_image_format pix_fmt; // Must be mlt_image_yuv422 for SDI - - int width; - int height; - - struct audio_format audio_format; - /** - * device file: - * /dev/sditx0 - * /dev/sdivideotx0 - * /dev/sdiaudiotx0 - **/ - char *device_file_video; // Path for SDI output - char *device_file_audio; // Path for exclusive SDI audio output - - /** - * write own HANC (ancillary data) is available for: - * SDI board ASSY 193 HD 'blanking=false' - * SDI board ASSY 180 SD quad 'blanking=true' - * SDI board ASSY 145 SD single 'blanking=true' - * - * 0=false, 1=true - * - **/ - uint8_t blanking; - - // our audio channel pair for this frame - int16_t audio_buffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES]; // The SDI audio channel pairs for this frame - - char *video_fmt_name; // 1080i25, 1080p25, 576i50, 486i2997, ... - -}; - -/** - * Forward references to static functions. - **/ -static int consumer_start(mlt_consumer this); -static int consumer_stop(mlt_consumer this); -static int consumer_is_stopped(mlt_consumer this); -static void consumer_close(mlt_consumer parent); -static void *consumer_thread(void *); - -static void consumer_write_JPEG(char * path, uint8_t **vBuffer, mlt_profile myProfile); -int convertYCBCRtoRGB(int y1, int cb, int cr, int y2, uint8_t * target_rgb); - -/***************************************************************************************************** - ****************************************** SDI Master Consumer ************************************** - *****************************************************************************************************/ - -/** This is what will be called by the factory - * @param profile: profile name for consumer - * @param type: unused - * @param *id: unused - * @param *arg: pointer to output path - **/ -mlt_consumer consumer_SDIstream_init(mlt_profile profile, mlt_service_type type, const char *id, char *arg) { - - // Create the consumer object - consumer_SDIstream this = calloc( 1, sizeof(struct consumer_SDIstream_s) ); - - // If malloc and consumer init ok - if (this != NULL && mlt_consumer_init(&this->parent, this, profile) == 0) { - - // Get the parent consumer object - mlt_consumer parent = &this->parent; - - // We have stuff to clean up, so override the close method - parent->close = consumer_close; - - // Set output path for SDI, default is "/dev/sditx0" - if (arg == NULL) { - this->device_file_video = strdup("/dev/sditx0"); - } else { - this->device_file_video = strdup(arg); - } - - // Set up start/stop/terminated callbacks - parent->start = consumer_start; - parent->stop = consumer_stop; - parent->is_stopped = consumer_is_stopped; - - // Set explicit to zero or other value - int i, j; - for (i = 0; i < MAX_AUDIO_STREAMS; i++) { - for (j = 0; j < MAX_AUDIO_SAMPLES; j++) { - this->audio_buffer[i][j] = j; - } - } - - mlt_events_register( MLT_CONSUMER_PROPERTIES(parent), "consumer-fatal-error", NULL ); - - // Return the consumer produced - return parent; - } - - // malloc or consumer init failed - free(this); - - // Indicate failure - return NULL; -} - -/** - * Start the consumer. - **/ -static int consumer_start(mlt_consumer parent) { - - // Get the properties - mlt_properties properties = mlt_consumer_properties(parent); - - // Get the actual object - consumer_SDIstream this = parent->child; - - // Check that we're not already running - if (!mlt_properties_get_int(properties, "running")) { - // Allocate threads - pthread_t *consumer_pthread = calloc(1, sizeof(pthread_t)); - - // Assign the thread to properties - mlt_properties_set_data(properties, "consumer_pthread", consumer_pthread, sizeof(pthread_t), free, NULL); - - // Set the running state - mlt_properties_set_int(properties, "running", 1); - - // Create the the threads - pthread_create(consumer_pthread, NULL, consumer_thread, this); - } - return 0; -} - -/** - * Stop the consumer - **/ -static int consumer_stop(mlt_consumer parent) { - - // Get the properties - mlt_properties properties = mlt_consumer_properties(parent); - - // Check that we're running - if (mlt_properties_get_int(properties, "running")) { - - // Get the threads - pthread_t *consumer_pthread = mlt_properties_get_data(properties, "consumer_pthread", NULL); - - // Stop the threads - mlt_properties_set_int(properties, "running", 0); - - // Wait for termination - pthread_join(*consumer_pthread, NULL); - - } - return 0; -} - -/** - * Determine if the consumer is stopped - **/ -static int consumer_is_stopped(mlt_consumer this) { - // Get the properties - mlt_properties properties = mlt_consumer_properties(this); - return !mlt_properties_get_int(properties, "running"); -} - -/** - * Threaded wrapper for pipe. - **/ -static void *consumer_thread(void *arg) { - - // Identify the arg - consumer_SDIstream this = arg; - - // Get the consumer - mlt_consumer consumer = &this->parent; - - // Convenience functionality (this is to stop melt/inigo after the end of a playout) - int terminate_on_pause = mlt_properties_get_int(MLT_CONSUMER_PROPERTIES( consumer ), "terminate_on_pause"); - int terminated = 0; // save only status - - int save_jpegs = mlt_properties_get_int(MLT_CONSUMER_PROPERTIES( consumer ), "save_jpegs"); - char * jpeg_folder = mlt_properties_get(MLT_CONSUMER_PROPERTIES( consumer ), "jpeg_file"); - - // If no folder is specified, skip jpeg export - if (jpeg_folder == NULL) { - save_jpegs = 0; - } - - if (save_jpegs > 0) - mlt_log_info(MLT_CONSUMER_SERVICE(consumer), "Saving a JPEG every %i frame.\n", save_jpegs); - - int counter = 0; // each second we save a Jpeg - - // set properties (path) for device files - if (mlt_properties_get(MLT_CONSUMER_PROPERTIES( consumer ), "dev_video") != NULL) { - this->device_file_video = strdup(mlt_properties_get(MLT_CONSUMER_PROPERTIES( consumer ), "dev_video")); - } - if (mlt_properties_get(MLT_CONSUMER_PROPERTIES( consumer ), "dev_audio") != NULL) { - if (this->blanking == 0) { - this->device_file_audio = strdup(mlt_properties_get(MLT_CONSUMER_PROPERTIES( consumer ), "dev_audio")); - } else { - // if we write HANC we do not write further audio data - mlt_log_info(MLT_CONSUMER_SERVICE(consumer), "Audio device file is set but will not be used.\n"); - } - } - - // Set additional device file defaults - struct stat st; - int fd = -1; - if (this->device_file_video) - fd = stat(this->device_file_video, &st); - if (fd == -1) { - free(this->device_file_video); - this->device_file_video = strdup("/dev/sdivideotx0"); - } else { - close(fd); - } - if (this->device_file_audio) { - fd = stat(this->device_file_audio, &st); - if (fd == -1) { - free(this->device_file_audio); - this->device_file_audio = strdup("/dev/sdiaudiotx0"); - } else { - close(fd); - } - } else if (this->device_file_video && - strstr(this->device_file_video, "sdivideotx")) { - this->device_file_audio = strdup("/dev/sdiaudiotx0"); - } - - // set blanking flag; is not nessary we write no own blanking(HANC) for HD board ASSY 193 - if (mlt_properties_get(MLT_CONSUMER_PROPERTIES( consumer ), "blanking")) { - // set value - if (!strcmp( mlt_properties_get(MLT_CONSUMER_PROPERTIES( consumer ), "blanking"), "false")) { - this->blanking = 0; - } else if (!strcmp( mlt_properties_get(MLT_CONSUMER_PROPERTIES( consumer ), "blanking"), "true")) { - this->blanking = 1; - } else { - this->blanking = mlt_properties_get_int(MLT_CONSUMER_PROPERTIES( consumer ), "blanking"); - } - } else if (this->device_file_video && strstr(this->device_file_video, "sdivideotx")) { - this->blanking = 0; - } else { - // set default value without HD board, also with blanking - this->blanking = 1; - } - - // Define a frame pointer - mlt_frame frame; - - // set Datablock number for SDI encoding - int my_dbn = 1; - - double fps = mlt_properties_get_double(MLT_CONSUMER_PROPERTIES(consumer), "fps"); - unsigned int count = 0; - - // Tell the framework how we want our audio and video - int frequency = this->audio_format.sample_rate; - int channels = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES(consumer), "channels" ); - int samples; - - // set number of audio channels, linsys vidport model 193 is limited to 8 channels (4AES frames) - this->audio_format.channels = 8; /* 0,2,4,6,8 */ - this->audio_format.aformat = mlt_audio_s16; /* 16, 24, 32 */ - this->audio_format.sample_rate = 48000; - this->pix_fmt = mlt_image_yuv422; - - if (this->device_file_video && this->device_file_audio && - !sdi_init(this->device_file_video, this->device_file_audio, this->blanking, mlt_service_profile((mlt_service) consumer), &this->audio_format)) { - mlt_log_fatal( MLT_CONSUMER_SERVICE(consumer), "failed to initialize\n" ); - mlt_events_fire( MLT_CONSUMER_PROPERTIES(consumer), "consumer-fatal-error", NULL ); - mlt_consumer_stopped(consumer); - return NULL; - } - - uint8_t *video_buffer = NULL; - int16_t *audio_buffer_tmp; // the upstream audio buffer - - // Loop until told not to - while (!consumer_is_stopped(consumer) && terminated == 0) { // - - // Get a frame from the service - if ((frame = mlt_consumer_rt_frame(consumer)) != NULL) { - - // Check for termination - if (terminate_on_pause && frame != NULL) { - terminated = mlt_properties_get_double(MLT_FRAME_PROPERTIES( frame ), "_speed") == 0.0; - if (terminated == 1) { - mlt_log_verbose(MLT_CONSUMER_SERVICE(consumer), "\nEnd of playout reached, terminating\n"); - consumer_stop(consumer); - } - } - - // True if mlt_consumer_rt_frame(...) successful - if (mlt_properties_get_int(mlt_frame_properties(frame), "rendered") == 1) { - - // Get the video from this frame and save it to our video_buffer - mlt_frame_get_image(frame, &video_buffer, &this->pix_fmt, &this->width, &this->height, 1); - - // Get the audio from this frame and save it to our audio_buffer - samples = mlt_audio_calculate_frame_samples(fps, frequency, count++); - mlt_frame_get_audio(frame, (void**) &audio_buffer_tmp, &this->audio_format.aformat, &frequency, &channels, &samples); - - this->audio_format.sample_rate = frequency; - this->audio_format.samples = samples; - - /* TODO: Audio is currently hard coded to 8 channels because write 8 channels to the sdi board. - The Linys SDI board has to be configured with the same number of channels! - this->audio_format.channels = channels; // take given number of channels - */ - - /* Tell the sdi_generator.c to playout our frame - * 8 AES (8 x stereo channels are possible, max. 16 channels) Linsys SD board model: 107, 159, 145, 180 - * 4 AES (4 x stereo channels are possible, max. 8 channels) Linsys HD board model: 193 - */ - if (video_buffer) { - - // provide mapping of audio channels - int i, j = 0; - int map_channels, map_start; - - for (i = 0; i < MAX_AUDIO_STREAMS && j < channels; i++) { - char key[27]; - int c; - - sprintf(key, "meta.map.audio.%d.channels", i); - map_channels = mlt_properties_get_int(MLT_FRAME_PROPERTIES(frame), key); - sprintf(key, "meta.map.audio.%d.start", i); - map_start = mlt_properties_get_int(MLT_FRAME_PROPERTIES(frame), key); - - if (!map_channels) - map_channels = channels - j; - for (c = 0; c < map_channels && j < channels; c++, j++) { - int16_t *src = audio_buffer_tmp + j; - int16_t *dest = this->audio_buffer[(map_start + c) / 2] + (map_start + c) % 2; - int s = samples + 1; - - while (--s) { - *dest = *src; - dest += 2; - src += channels; - } - } - } - - // generate SDI frame and playout - my_dbn = sdi_playout(video_buffer, this->audio_buffer, &this->audio_format, (channels + 1) / 2, my_dbn); - - // write a JPEG of every X-th frame - if (save_jpegs > 0 && counter >= save_jpegs) { - consumer_write_JPEG(jpeg_folder, &video_buffer, mlt_service_profile((mlt_service) consumer)); - counter = 0; - } else if (save_jpegs > 0) { - counter++; - } - mlt_events_fire(MLT_CONSUMER_PROPERTIES( consumer ), "consumer-frame-show", frame, NULL ); - } else { - mlt_log_warning(MLT_CONSUMER_SERVICE(consumer), "Videobuffer was NULL, skipping playout!\n"); - } - } else { - mlt_log_warning(MLT_CONSUMER_SERVICE(consumer), "WARNING the requested frame is not yet rendered! This will cause image disturbance!\n"); - - if (video_buffer) { - my_dbn = sdi_playout(video_buffer, this->audio_buffer, &this->audio_format, (channels + 1) / 2, my_dbn); - } else { - mlt_log_warning(MLT_CONSUMER_SERVICE(consumer), "Videobuffer was NULL, skipping playout!\n"); - } - } - - if (frame != NULL) - mlt_frame_close(frame); - } - - } - mlt_consumer_stopped(consumer); - return NULL; -} - -/** - * Callback to allow override of the close method. - **/ -static void consumer_close(mlt_consumer parent) { - - // Get the actual object - consumer_SDIstream this = parent->child; - - free(this->device_file_video); - free(this->device_file_audio); - - // Now clean up the rest (the close = NULL is a bit nasty but needed for now) - parent->close = NULL; - mlt_consumer_close(parent); - - // Invoke the close function of the sdi_generator to close opened files used for output - sdimaster_close(); - - // Finally clean up this - free(this); -} - -/** - * Write videobuffer as JPEG to path - * @param path - **/ -static void consumer_write_JPEG(char * filename, uint8_t **vBuffer, mlt_profile myProfile) { - -#ifdef WITH_JPEG - - int bytes_per_pixel = 3; // or 1 for GRACYSCALE images - int color_space = JCS_RGB; // or JCS_GRAYSCALE for grayscale images - - uint8_t * buffer_position = *vBuffer; - uint8_t image_rgb[myProfile->width * myProfile->height * bytes_per_pixel]; - - //convert vBuffer to RGB - int i; - for (i = 0; i < sizeof(image_rgb) / 6; i++) { - int y1 = *(buffer_position++); - int cb = *(buffer_position++); - int y2 = *(buffer_position++); - int cr = *(buffer_position++); - convertYCBCRtoRGB(y1, cb, cr, y2, &image_rgb[i * 6]); - } - - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - - // this is a pointer to one row of image data - JSAMPROW row_pointer[1]; - - FILE *outfile = fopen(filename, "wb"); - - if (!outfile) { - mlt_log_error(NULL, "%s: Error opening output jpeg file %s\n!", __FILE__, filename); - return; - } - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - jpeg_stdio_dest(&cinfo, outfile); - - // Setting the parameters of the output file here - cinfo.image_width = myProfile->width; - cinfo.image_height = myProfile->height; - cinfo.input_components = bytes_per_pixel; - cinfo.in_color_space = (J_COLOR_SPACE) color_space; - - // default compression parameters, we shouldn't be worried about these - jpeg_set_defaults(&cinfo); - - // Now do the compression - jpeg_start_compress(&cinfo, TRUE); - - // like reading a file, this time write one row at a time - while (cinfo.next_scanline < cinfo.image_height) { - row_pointer[0] = &image_rgb[cinfo.next_scanline * cinfo.image_width * cinfo.input_components]; - jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - // similar to read file, clean up after we're done compressing - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - fclose(outfile); -#endif -} - -/** - * converts YCbCr samples to two 32-bit RGB values - * @param y1 cb cr and y2 values - * @param target pointer - * @return 0 upon success - **/ -int convertYCBCRtoRGB(int y1, int cb, int cr, int y2, uint8_t * target_rgb) { - -#ifdef WITH_JPEG - - if(y1 > 235) - y1 = 235; - if(y1 < 16) - y1 = 16; - - if(y2 > 235) - y2 = 235; - if(y2 < 16) - y2 = 16; - - if(cr > 240) - cr = 240; - if(cr < 16) - cr = 16; - - if(cb > 240) - cb = 240; - if(cb < 16) - cb = 16; - - uint8_t r1, g1, b1, r2, g2, b2; - - //pointer to current output buffer position - uint8_t * target_pointer = target_rgb; - - r1 = y1 + 1.402 * (cr - 128); - g1 = y1 - 0.34414 * (cb - 128) - 0.71414 * (cr - 128); - b1 = y1 + 1.772 * (cb - 128); - - r2 = y2 + 1.402 * (cr - 128); - g2 = y2 - 0.34414 * (cb - 128) - 0.71414 *(cr - 128); - b2 = y2 + 1.772 * (cb - 128); - - *target_pointer++ = r1; - *target_pointer++ = g1; - *target_pointer++ = b1; - - *target_pointer++ = r2; - *target_pointer++ = g2; - *target_pointer++ = b2; - - return 0; -#endif - return 1; -} diff --git a/src/modules/linsys/consumer_sdi.yml b/src/modules/linsys/consumer_sdi.yml deleted file mode 100644 index ac26e3cc8..000000000 --- a/src/modules/linsys/consumer_sdi.yml +++ /dev/null @@ -1,12 +0,0 @@ -schema_version: 0.1 -type: consumer -identifier: sdi -title: Linear Systems SDI (*deprecated*) -version: 1 -copyright: Broadcasting Center Europe S.A. -creator: Thomas Kurpick -license: GPLv2 -language: en -tags: - - Audio - - Video diff --git a/src/modules/linsys/deprecated b/src/modules/linsys/deprecated deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/modules/linsys/factory.c b/src/modules/linsys/factory.c deleted file mode 100644 index e34b3a67f..000000000 --- a/src/modules/linsys/factory.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * factory.c for Linsys SDI consumer -*/ - -#include -#include -#include - -extern mlt_consumer consumer_SDIstream_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -static mlt_properties metadata( mlt_service_type type, const char *id, void *data ) -{ - char file[ PATH_MAX ]; - snprintf( file, PATH_MAX, "%s/linsys/%s", mlt_environment( "MLT_DATA" ), (char*) data ); - return mlt_properties_parse_yaml( file ); -} - -MLT_REPOSITORY -{ - MLT_REGISTER( mlt_service_consumer_type, "sdi", consumer_SDIstream_init ); - MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdi", metadata, "consumer_sdi.yml" ); -} diff --git a/src/modules/linsys/gpl b/src/modules/linsys/gpl deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/modules/linsys/sdi_generator.c b/src/modules/linsys/sdi_generator.c deleted file mode 100644 index f48776c5c..000000000 --- a/src/modules/linsys/sdi_generator.c +++ /dev/null @@ -1,2411 +0,0 @@ -/** - * - * MLT SDI Consumer: - * request video and audio data from MLT and generate an SDI stream - * - * Copyright (C) Broadcasting Center Europe S.A. http://www.bce.lu - * an RTL Group Company http://www.rtlgroup.com - * All rights reserved. - * - * E-mail: support_plasec@bce.lu - * - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * - * DESCRIPTION: - * This software act as interface between the MLT Frameworkas as - * MLT Consumer and the Linear Systems Ltd. SMPTE 292M and SMPTE 259M-C boards. - * - * Linear Systems can be contacted at http://www.linsys.ca - * - ********************************************************************************** - * System : INTeL I686 64Bit - * OS : Linux SuSE Kernel 2.6.27.39-0.2-default - * Compiler: gcc 4.3.2 (c++) - ********************************************************************************** - * Project : MLT SDI Consumer for SD and HD - * Started by : Thomas Kurpick, Dipl.Inf. (FH) - ********************************************************************************** - * Supported and tested boards for SD-SDI or HD-SDI Output: - * PCI SDI Master™ (model 107) - * PCIe SDI Master™ (model 159) - * PCIe LP SDI Master™ FD (model 145) - * PCIe LP SDI Master™ Quad/o (model 180) - * PCIe LP HD-SDI Master™ O (model 193) - * - * Note: PCIe LP HD-SDI Master™ O (model 193) is an VidPort model and supports an - * separate video and audio interface. Device file: - * /dev/sdivideotx[] for active video data - * /dev/sdiaudiotx[] for pcm audio data - * - * This mlt consumer use the following device files: - * /dev/sditx[] (SD-PAL) up to 8 x AES (8 x stereo / 16 audio channels) - * /dev/sdivideotx[] (HD) - * /dev/sdiaudiotx[] (HD) up to 4 x AES (4 x stereo / 8 audio channels) - * - * - ********************************************************************************** - * Last modified by: - * Thomas Kurpick 08.Jan.2010 - * Ver. 2.0 - * - ********************************************************************************** - * - * Consumer properties: - * 'dev_video' - * 'dev_audio' - * 'blanking' - * Only to monitor the SDI output a beta version of jpeg-writer is implemented. - * 'jpeg_files' a number for output interval - * 'save_jpegs' path for image - * - * EXAMPLE: - * - * SDI boards with full frame stream (with blanking): - * melt video.dv -consumer sdi:/dev/sditx0 buffer=0; - * melt video.dv -consumer sdi:/dev/sditx0 buffer=0 blanking=true; - * melt video.dv -consumer sdi dev_video=/dev/sditx0 buffer=0 blanking=true; - * melt video.dv audio_index=all -consumer sdi dev_video=/dev/sditx0 buffer=0 blanking=true; - * - * SDI boards without full frame stream (without blanking): - * melt -profile atsc_1080i_50 video.mpeg audio_index=1 -consumer sdi dev_video=/dev/sdivideotx0 dev_sdiaudio=/dev/sdiaudiotx0 blanking=false - * melt -profile atsc_1080i_50 video.mpeg audio_index=all -consumer sdi dev_video=/dev/sdivideotx0 dev_sdiaudio=/dev/sdiaudiotx0 blanking=false - * melt -profile atsc_1080i_50 video.mpeg audio_index=all -consumer sdi dev_video=/dev/sdivideotx0 dev_sdiaudio=/dev/sdiaudiotx0 blanking=false jpeg_files=25 save_jpegs=channel_04.jpg - * - * - * SDI output formats and MLT profiles: - * ##################################################################################################################################################### - * ########## SMPTE 274M 1920 x 1080 Image Sample Structure ############################################################################################ - * ##################################################################################################################################################### - * System No. System nomenclature Form of scanning Frame rate Embedded Audio MLT profile Linsys board support (model) - * 4 1920 x 1080/60/I interlaced 30 HZ 4 x AES (8 channels) atsc_1080i_60 193 - * 5 1920 x 1080/59.94/I interlaced 30000/1001 ~ 29.97 HZ 4 x AES (8 channels) atsc_1080i_5994 193 - * 6 1920 x 1080/50/I interlaced 25 HZ 4 x AES (8 channels) atsc_1080i_50 193 - * 7 1920 x 1080/30/P progressive 30 HZ 4 x AES (8 channels) atsc_1080p_30 193 - * 8 1920 x 1080/29.97/P progressive 30000/1001 ~ 29.97 HZ 4 x AES (8 channels) atsc_1080p_2997 193 - * 9 1920 x 1080/25/P progressive 25 HZ 4 x AES (8 channels) atsc_1080p_25 193 - * 10 1920 x 1080/24/P progressive 24 HZ 4 x AES (8 channels) atsc_1080p_24 193 - * 11 1920 x 1080/23.98/P progressive 24000/1001 ~ 23.98 HZ 4 x AES (8 channels) atsc_1080p_2398 193 - * - * ##################################################################################################################################################### - * ########## SMPTE 296M 1280 × 720 Progressive Image Sample Structure ################################################################################# - * ##################################################################################################################################################### - * System No. System nomenclature Form of scanning Frame rate Embedded Audio MLT profile Linsys board support (model) - * 1 1280 × 720/60 progressive 60 HZ 4 x AES (8 channels) atsc_720p_60 193 - * 2 1280 × 720/59.94 progressive 60000/1001 ~ 59.97 HZ 4 x AES (8 channels) atsc_720p_5994 193 - * 3 1280 × 720/50 progressive 50 HZ 4 x AES (8 channels) atsc_720p_50 193 - * 4 1280 × 720/30 progressive 30 HZ 4 x AES (8 channels) atsc_720p_30 193 - * 5 1280 × 720/29.97 progressive 30000/1001 ~ 29.97 HZ 4 x AES (8 channels) atsc_720p_2997 193 - * 6 1280 × 720/25 progressive 25 HZ 4 x AES (8 channels) atsc_720p_25 193 - * 7 1280 × 720/24 progressive 24 HZ 4 x AES (8 channels) atsc_720p_24 193 - * 8 1280 × 720/23.98 progressive 24000/1001 ~ 23.98 HZ 4 x AES (8 channels) atsc_720p_2398 193 - * - * ##################################################################################################################################################### - * ########## SMPTE 125M 486i 29.97Hz & BT.656 576i 25Hz ############################################################################################### - * ##################################################################################################################################################### - * System No. System nomenclature Form of scanning Frame rate Embedded Audio MLT profile Linsys board support (model) - * SD PAL 720 × 576/50/I interlaced 25 HZ 8 x AES (16 channels) dv_pal 180,145,159,107 - * SD PAL 720 × 576/50/I interlaced 25 HZ 4 x AES (8 channels) dv_pal 193 - * SD NTSC 720 × 486/59.94/I interlaced 30000/1001 ~ 29.97 HZ 8 x AES (16 channels) sdi_486i_5994 TODO:180,145,159,107 - * SD NTSC 720 × 486/59.94/I interlaced 30000/1001 ~ 29.97 HZ 4 x AES (8 channels) sdi_486i_5994 193 - * - **/ - -#include "sdi_generator.h" - -/*!/brief initialization of the file handlers for the playout - * @param *device_video: file or SDITX device or SDIVIDEOTX device - * @param *device_audio: file or SDIAUDIOTX device - * @param blanking: true or false (if false the consumer write only active video data without any VANH or HANC) - */ -static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, mlt_profile myProfile, - const struct audio_format * audio_format) { - - // set device file - device_file_video = device_video; - device_file_audio = device_audio; - - // set flag for using of blanking with ancillary data - info.blanking = blanking; - - // set pack method for SDI word conversion - pack = pack8; - //pack = pack10; - //pack = pack_v210; - - // check format - if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 0) { - info.fmt = &FMT_1080i60; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080I_60HZ; - } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den - == 1001 && myProfile->progressive == 0) { - info.fmt = &FMT_1080i5994; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080I_59_94HZ; - } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 25 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 0) { - info.fmt = &FMT_1080i50; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080I_50HZ; - } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 1) { - info.fmt = &FMT_1080p30; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_30HZ; - } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den - == 1001 && myProfile->progressive == 1) { - info.fmt = &FMT_1080p2997; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_29_97HZ; - } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 25 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 1) { - info.fmt = &FMT_1080p25; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_25HZ; - } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 24 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 1) { - info.fmt = &FMT_1080p24; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_24HZ; - } else if (myProfile->width == 1920 && myProfile->height == 1080 && myProfile->frame_rate_num == 24000 && myProfile->frame_rate_den - == 1001 && myProfile->progressive == 1) { - info.fmt = &FMT_1080p2398; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_274M_1080P_23_98HZ; - } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 60 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 1) { - info.fmt = &FMT_720p60; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_60HZ; - } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 60000 && myProfile->frame_rate_den - == 1001 && myProfile->progressive == 1) { - info.fmt = &FMT_720p5994; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_59_94HZ; - } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 50 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 1) { - info.fmt = &FMT_720p50; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_50HZ; - } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 30 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 1) { - info.fmt = &FMT_720p30; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_30HZ; - } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den - == 1001 && myProfile->progressive == 1) { - info.fmt = &FMT_720p2997; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_29_97HZ; - } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 25 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 1) { - info.fmt = &FMT_720p25; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_25HZ; - } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 24 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 1) { - info.fmt = &FMT_720p24; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_24HZ; - } else if (myProfile->width == 1280 && myProfile->height == 720 && myProfile->frame_rate_num == 24000 && myProfile->frame_rate_den - == 1001 && myProfile->progressive == 1) { - info.fmt = &FMT_720p2398; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_296M_720P_23_98HZ; - } else if (myProfile->width == 720 && myProfile->height == 576 && myProfile->frame_rate_num == 25 && myProfile->frame_rate_den == 1 - && myProfile->progressive == 0) { - info.fmt = &FMT_576i50; - sdi_frame_mode = SDIVIDEO_CTL_BT_601_576I_50HZ; - } else if (myProfile->width == 720 && myProfile->height == 486 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den - == 1001 && myProfile->progressive == 0) { - info.fmt = &FMT_486i5994; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_125M_486I_59_94HZ; - } else if (myProfile->width == 720 && myProfile->height == 480 && myProfile->frame_rate_num == 30000 && myProfile->frame_rate_den - == 1001 && myProfile->progressive == 0) { - info.fmt = &FMT_480i5994; - sdi_frame_mode = SDIVIDEO_CTL_SMPTE_125M_486I_59_94HZ; - } else { - printf("Consumer got unknown format: %s", myProfile->description); - info.fmt = &FMT_576i50; - sdi_frame_mode = SDIVIDEO_CTL_BT_601_576I_50HZ; - } - - printf("Consumer use format: %s\nProfile: %i %i %i %i %i\n", myProfile->description, myProfile->width, myProfile->height, - myProfile->frame_rate_num, myProfile->frame_rate_den, myProfile->progressive); - - // Check if the format supports own blanking (note: model 193 supports currently only active video at the video device file) - if (info.blanking && info.fmt != &FMT_576i50) { - printf("SDI consumer doesn't support blanking(HANC) for the configured SD board and SDI format. Try argument: blanking=false\n"); - return 0; - } - - // if we write our own HANC we need an AES channel status bit array - if (info.blanking) { - - // small description - // http://www.sencore.com/newsletter/Nov05/DigAudioChannelStatusBits.htm - // or - // http://www.sencore.com/uploads/files/DigAudioChannelStatusBits.pdf - - // create empty AESChannelStatusBitArray - int i = 0; - for (i = 0; i < sizeof(AESChannelStatusBitArray) / sizeof(AESChannelStatusBitArray[0]); i++) - AESChannelStatusBitArray[i] = 0; - - /** - * Professional Format - Channel Status Bits - **/ - ////// Byte 0 ////// - AESChannelStatusBitArray[0] = 1; // professional format - - AESChannelStatusBitArray[1] = 0; // PCM Format - - AESChannelStatusBitArray[2] = 1; // Emphasis: [100] No Emphasis - AESChannelStatusBitArray[3] = 0; // ^ - AESChannelStatusBitArray[4] = 0; // ^ - - AESChannelStatusBitArray[5] = 0; // locked - - AESChannelStatusBitArray[6] = 0; // sample frequency Fs: [01]48kHz, [10]44kHz, [11]32kHz - AESChannelStatusBitArray[7] = 1; // ^ - ////// Byte 1 ////// - AESChannelStatusBitArray[8] = 0; // channel mode: [0000] not indicated, [0001]2channels, [0010]1channel mono, ... - AESChannelStatusBitArray[9] = 0; // ^ - AESChannelStatusBitArray[10] = 0; // ^ - AESChannelStatusBitArray[11] = 1; // ^ - ////// Byte 2 ////// - AESChannelStatusBitArray[19] = 0; // Encoded sample word length [100]20bits, - AESChannelStatusBitArray[20] = 0; // - AESChannelStatusBitArray[21] = 0; // - ////// Byte 3 ////// - AESChannelStatusBitArray[24] = 0; // - AESChannelStatusBitArray[25] = 0; // - AESChannelStatusBitArray[26] = 0; // - AESChannelStatusBitArray[27] = 0; // - AESChannelStatusBitArray[28] = 0; // - AESChannelStatusBitArray[29] = 0; // - AESChannelStatusBitArray[30] = 0; // - AESChannelStatusBitArray[31] = 0; // Multi Channel Mode - ////// Byte 4-21 ////// - //AESChannelStatusBitArray[32-179]= 0; - ////// Byte 22 ////// - AESChannelStatusBitArray[180] = 0; // Reliability Flags - AESChannelStatusBitArray[181] = 1; // ^ - AESChannelStatusBitArray[182] = 1; // ^ - AESChannelStatusBitArray[183] = 1; // ^ - ////// Byte 23 ////// - AESChannelStatusBitArray[184] = 0; // Cyclic Redundancy Check - AESChannelStatusBitArray[185] = 1; // ^ - AESChannelStatusBitArray[186] = 0; // ^ - AESChannelStatusBitArray[187] = 0; // ^ - AESChannelStatusBitArray[188] = 1; // ^ - AESChannelStatusBitArray[189] = 0; // ^ - AESChannelStatusBitArray[190] = 1; // ^ - AESChannelStatusBitArray[191] = 1; // ^ - } - - // set buffer for one line of active video samples - line_buffer = (uint16_t*) calloc(info.fmt->samples_per_line, sizeof(uint16_t)); - - // calculate and set buffer for the complete SDI frame - if (info.fmt != &FMT_576i50 && info.fmt != &FMT_486i5994) { - if (info.blanking) { - if (pack == pack_v210) { - samples = (info.fmt->samples_per_line / 96 * 48) + ((info.fmt->samples_per_line % 96) ? 48 : 0); - sdi_frame_size = samples * info.fmt->lines_per_frame * 8 / 3; - } else { - sdi_frame_size = info.fmt->samples_per_line * info.fmt->lines_per_frame; - } - } else { - if (pack == pack_v210) { - samples = (info.fmt->active_samples_per_line / 96 * 48) + ((info.fmt->active_samples_per_line % 96) ? 48 : 0); - sdi_frame_size = samples * info.fmt->active_lines_per_frame * 8 / 3; - } else { - sdi_frame_size = info.fmt->active_samples_per_line * info.fmt->active_lines_per_frame; - } - } - } else { - if (info.blanking) { - if (pack == pack_v210) { - sdi_frame_size = info.fmt->samples_per_line * 4 / 3 * info.fmt->lines_per_frame; - } else if (pack == pack8) { - sdi_frame_size = info.fmt->samples_per_line * info.fmt->lines_per_frame; - } else { - sdi_frame_size = info.fmt->samples_per_line * 10 / 8 * info.fmt->lines_per_frame; - } - } else { - if (pack == pack_v210) { - sdi_frame_size = info.fmt->active_samples_per_line * 4 / 3 * info.fmt->active_lines_per_frame; - } else if (pack == pack8) { - sdi_frame_size = info.fmt->active_samples_per_line * info.fmt->active_lines_per_frame; - } else { - sdi_frame_size = info.fmt->active_samples_per_line * 10 / 8 * info.fmt->active_lines_per_frame; - } - } - } - - // (*10/8 because we store (TOTAL_SAMPLES*TOTAL_LINES) words with 10 bit in this 8 bit array) ) - if (info.fmt == &FMT_576i50 && info.blanking) { - sdi_frame_size = info.fmt->samples_per_line * 10 / 8 * info.fmt->lines_per_frame; - } - - if (info.blanking) { - printf("SDI frame size: %"PRIu64"\n", sdi_frame_size); - } else { - printf("Frame size for active video: %"PRIu64"\n", sdi_frame_size); - } - - /** - * Setup HD-SDI Master device (vidport): - * - * if device_file_video available then - * if vidport available - * 1. setup - * end - * 1. open device file handler - * - * if device_file_audio available then - * 1. setup - * 2. open device file handler - * end - * end - **/ - if (device_file_video != NULL) { - - // If we use a Linsys HD board with active video (without blanking) setup the board for the used mode - if (strstr(device_file_video, "sdivideotx") != NULL && !info.blanking) { - - char * value; - - // Buffer size - value = itoa(sdi_frame_size); - setSDIVideoProperties(SETTING_BUFFER_SIZE_VIDEO, value, device_video); - free(value); - - // Frame Mode - value = itoa(sdi_frame_mode); - setSDIVideoProperties(SETTING_FRAME_MODE, value, device_video); - free(value); - - // Data Mode - if (pack == pack8) - setSDIVideoProperties(SETTING_DATA_MODE, "0", device_video); - else if (pack == pack_v210) - setSDIVideoProperties(SETTING_DATA_MODE, "1", device_video); - } - - // open file handle for SDI(video) output - if ((fh_sdi_video = open(device_file_video, O_WRONLY)) == -1) { - perror(NULL); - printf("\ncould not open video output destination: %s\n", device_file_video); - return 0; - } - printf("SDI consumer uses video device file: %s\n", device_file_video); - - // Check if we have to use a separate device file for audio - if (device_file_audio != NULL) { - - // set settings for audio device file - if (strstr(device_file_audio, "sdiaudiotx") != NULL && !info.blanking) { - - char * value; - - /** - * prepare sample size - * MLT supports: 16bit, 32bit - * LINSYS SDI boards supports: 16bit, 24bit, 32bit - * we set 16bit as default - **/ - uint8_t sample_size = audio_format->aformat == mlt_audio_s32 ? 32 : 16; - - // Buffer size - // audio buffer per frame (Bytes) = sample rate / frame rate * ( sample size / 1Byte ) x channels - value = itoa( - (uint64_t) audio_format->sample_rate / ( (uint64_t) myProfile->frame_rate_num / (uint64_t) myProfile->frame_rate_den) * (uint64_t) sample_size / 8 - * (uint64_t) audio_format->channels); - setSDIAudioProperties(SETTING_BUFFER_SIZE_AUDIO, value, device_audio); - free(value); - - // channels - value = itoa(audio_format->channels); - setSDIAudioProperties(SETTING_CHANNELS, value, device_audio); - free(value); - - // sample rate - value = itoa(audio_format->sample_rate); - setSDIAudioProperties(SETTING_SAMPEL_RATE, value, device_audio); - free(value); - - // sample size - value = itoa(sample_size); - setSDIAudioProperties(SETTING_SAMPLE_SIZE, value, device_audio); - free(value); - } - - // open file handle for audio output - if ((fh_sdi_audio = open(device_file_audio, O_WRONLY)) == -1) { - perror(NULL); - printf("\nCould not open audio output destination: %s\n", device_file_audio); - return 0; - } - printf("SDI consumer uses audio device file: %s\n", device_file_audio); - } - - } - - // set buffer for the complete SDI frame - data = (uint8_t*) calloc(sdi_frame_size, sizeof(uint8_t)); - - return 1; -} - -/** - * Writes video and audio to specified files in SDI format - * @param *vBuffer: Pointer to a video Buffer - * @param aBuffer[][] - * @param *audio_format: mlt audio_format - * @param audio_streams: number of audio streams which have content in aBuffer (available 0-8) - * @return current DBN (data block number of SDI frame) - **/ -static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES], const struct audio_format * audio_format, - int audio_streams, int my_DBN) { - - // Pointer to the start of data. This is used to fill data line by line - uint8_t *p = data; - - //******************************************************************************************* - //**************** Build the SDI frame line by line **************************************** - //******************************************************************************************* - - /* - * if SDI FMT_576i50 for card ASSY 145 or ASSY 159, with access to whole SDI frame buffer - * and device_file_audio must be NULL - * than we write own audio data, - * else - * than HD for card ASSY 193 - */ - //if (info.fmt == &FMT_576i50 && device_file_audio == NULL && !strcmp(device_file_video, "/dev/sdivideotx0")) { - if (info.fmt == &FMT_576i50 && info.blanking) { - - //counter for the lines - int i = 0; - int16_t AudioGroupCounter = 0; - - /*#####################################################*/ - /*######## FIELD 1 #######################*/ - /*#####################################################*/ - - info.xyz = &FIELD_1_VERT_BLANKING; - - // line 1-22 VERTICAL_BLANKING:23 lines SAV 0x2ac EAV 0x2d8 - for (i = 1; i <= 5; i++) { - create_SD_SDI_Line(line_buffer, &info, FIELD_1, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - } - for (i = 6; i <= 8; i++) { - create_SD_SDI_Line(line_buffer, &info, FIELD_1, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - } - for (i = 9; i <= 22; i++) { - create_SD_SDI_Line(line_buffer, &info, FIELD_1, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - } - // line 23-310 ACTIVE: 287 lines SAV 0x200 EAV 0x274 - info.xyz = &FIELD_1_ACTIVE; - int f1counter = 1; // only odd lines - for (i = 23; i <= 310; i++) { - create_SD_SDI_Line(line_buffer, &info, FIELD_1, ACTIVE_VIDEO, vBuffer, aBuffer, i, f1counter, getDBN(my_DBN++), - AudioGroupCounter, getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - f1counter += 2; - } - i = 311; - // line 311-312 VERTICAL_BLANKING: 2 lines SAV 0x2ac EAV 0x2d8 - info.xyz = &FIELD_1_VERT_BLANKING; - create_SD_SDI_Line(line_buffer, &info, FIELD_1, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i++); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - create_SD_SDI_Line(line_buffer, &info, FIELD_1, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i++); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - - /*#####################################################*/ - /*######## FIELD 2 ########################*/ - /*#####################################################*/ - - info.xyz = &FIELD_2_VERT_BLANKING; - - // line 313-336 VERTICAL_BLANKING: 23 lines SAV 0x3b0 EAV 0x3c4 - create_SD_SDI_Line(line_buffer, &info, FIELD_2, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i++); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - - create_SD_SDI_Line(line_buffer, &info, FIELD_2, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i++); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - - create_SD_SDI_Line(line_buffer, &info, FIELD_2, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i++); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - - create_SD_SDI_Line(line_buffer, &info, FIELD_2, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i++); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - - create_SD_SDI_Line(line_buffer, &info, FIELD_2, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i++); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - - create_SD_SDI_Line(line_buffer, &info, FIELD_2, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i++); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - - // `getAudioGroups2Write()`=0 - for (i = 319; i <= 321; i++) { - create_SD_SDI_Line(line_buffer, &info, FIELD_2, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - } - for (i = 322; i <= 335; i++) { - create_SD_SDI_Line(line_buffer, &info, FIELD_2, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - } - // line 336-623 ACTIVE: 288 lines SAV 0x31c EAV 0x368 - info.xyz = &FIELD_2_ACTIVE; - int f2counter = 2; // only even Lines - for (i = 336; i <= 623; i++) { - - create_SD_SDI_Line(line_buffer, &info, FIELD_2, ACTIVE_VIDEO, vBuffer, aBuffer, i, f2counter, getDBN(my_DBN++), - AudioGroupCounter, getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - f2counter += 2; - } - // line 624-625 VERTICAL_BLANKING: 2 lines SAV 0x3b0 EAV 0x3c4 - info.xyz = &FIELD_2_VERT_BLANKING; - for (i = 624; i <= 625; i++) { - create_SD_SDI_Line(line_buffer, &info, FIELD_2, VERT_BLANKING, vBuffer, aBuffer, i, 0, getDBN(my_DBN++), AudioGroupCounter, - getNumberOfAudioGroups2Write(i), audio_streams); - AudioGroupCounter += getNumberOfAudioGroups2Write(i); - p = pack10(p, line_buffer, info.fmt->samples_per_line); - } - - } else { // use HD board without blanking - - // start with first even line - active_video_line = 1; - - /* ***************************************** - * *********** LINE DISTRIBUTION *********** - * ***************************************** - * - * << decide form of scanning (interlaced || progressive) >> - * if (interlaced) - * << decide lines per frame (1125 || 625 || 525) >> - * if(1125) 1080x1920 HD - * than create lines - * else if(625) 576x720 PAL - * than create lines - * else (525) 486x720 NTSC - * than create lines - * else (progressive) - * << decide resolution (1125 || 750) >> - * if(1125) 1080x1920 HD - * than create lines - * else(750) 720x1280 HD - * than create lines - * - **/ - - // Generate a frame - if (info.fmt->interlaced) { - - /**************************************** - * INTERLACED - ****************************************/ - - if (info.fmt->lines_per_frame == 1125) { - - if (info.blanking) { - elements = info.fmt->samples_per_line; - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 1; info.ln <= 20; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } else { - elements = info.fmt->active_samples_per_line; - } - info.xyz = &FIELD_1_ACTIVE; - for (info.ln = 21; info.ln <= 560; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - active_video_line += 2; - } - if (info.blanking) { - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 561; info.ln <= 563; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - info.xyz = &FIELD_2_VERT_BLANKING; - for (info.ln = 564; info.ln <= 583; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } - // start with first odd line - active_video_line = 2; - - info.xyz = &FIELD_2_ACTIVE; - for (info.ln = 584; info.ln <= 1123; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - active_video_line += 2; - } - if (info.blanking) { - info.xyz = &FIELD_2_VERT_BLANKING; - for (info.ln = 1124; info.ln <= 1125; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } - } else if (info.fmt->lines_per_frame == 625) { - - elements = info.fmt->active_samples_per_line; - - // start with first even line - active_video_line = 1; - - /** - * Generate an SDI PAL frame - **/ - if (info.blanking) { - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 1; info.ln <= 22; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } - info.xyz = &FIELD_1_ACTIVE; - for (info.ln = 23; info.ln <= 310; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - active_video_line += 2; - } - if (info.blanking) { - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 311; info.ln <= 312; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - info.xyz = &FIELD_2_VERT_BLANKING; - for (info.ln = 313; info.ln <= 335; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } - - // start with first odd line - active_video_line = 2; - - info.xyz = &FIELD_2_ACTIVE; - for (info.ln = 336; info.ln <= 623; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - active_video_line += 2; - } - if (info.blanking) { - info.xyz = &FIELD_2_VERT_BLANKING; - for (info.ln = 624; info.ln <= 625; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } - } else if (info.fmt->lines_per_frame == 525) { - - /** - * Generate an SDI NTSC frame - * - * - * 16 lines VERT_BLANKING FIELD_1_VERT_BLANKING - * 1 lines VERT_BLANKING FIELD_1_ACTIVE - * 3 lines ACTIVE_VIDEO FIELD_1_ACTIVE (opt. video data) - * 240 lines ACTIVE_VIDEO FIELD_1_ACTIVE - * 2 lines VERT_BLANKING FIELD_1_VERT_BLANKING - * - * 8 lines VERT_BLANKING FIELD_2_VERT_BLANKING - * 9 lines VERT_BLANKING FIELD_2_VERT_BLANKING - * 3 lines ACTIVE_VIDEO FIELD_2_ACTIVE (opt. video data) - * 240 lines ACTIVE_VIDEO FIELD_2_ACTIVE - * 4 lines VERT_BLANKING FIELD_2_VERT_BLANKING - * - **/ - - elements = info.fmt->active_samples_per_line; - - active_video_line = 1; - - if (info.blanking) { - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 1; info.ln <= 15; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - for (info.ln = 16; info.ln <= 16; info.ln++) { - info.xyz = &FIELD_1_ACTIVE; - mkline(line_buffer, &info, VERT_BLANKING); - p = pack(p, line_buffer, elements); - } - } - - info.xyz = &FIELD_1_ACTIVE; - - // 480 or 486 lines - if (info.fmt == &FMT_480i5994) { - // 3 lines opt. video data - for (info.ln = 17; info.ln <= 19; info.ln++) { - mkline(line_buffer, &info, BLACK); - p = pack(p, line_buffer, elements); - } - // 240 lines - for (info.ln = 20; info.ln <= 259; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - active_video_line += 2; - } - } else { - // 243 lines - for (info.ln = 17; info.ln <= 259; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - active_video_line += 2; - } - } - if (info.blanking) { - // 2 lines vertical data - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 260; info.ln <= 261; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - // 8 lines vertical data - info.xyz = &FIELD_2_VERT_BLANKING; - for (info.ln = 262; info.ln <= 269; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - // 9 lines - for (info.ln = 270; info.ln <= 278; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - - } - - active_video_line = 0; - - // 480 or 486 lines - if (info.fmt == &FMT_480i5994) { - // 3 lines opt. video data - info.xyz = &FIELD_2_ACTIVE; - for (info.ln = 279; info.ln <= 281; info.ln++) { - mkline(line_buffer, &info, BLACK); - p = pack(p, line_buffer, elements); - } - // 240 lines - for (info.ln = 282; info.ln <= 521; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - active_video_line += 2; - } - } else { - // 243 lines - for (info.ln = 279; info.ln <= 521; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - active_video_line += 2; - } - } - // 4 lines vertical data - if (info.blanking) { - info.xyz = &FIELD_2_VERT_BLANKING; - for (info.ln = 522; info.ln <= 525; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } - } - } else { - - /**************************************** - * PROGRESSIVE - ****************************************/ - - // start with first line numerber - active_video_line = 0; - - if (info.fmt->lines_per_frame == 1125) { - if (info.blanking) { - elements = info.fmt->samples_per_line; - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 1; info.ln <= 41; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } else { - elements = info.fmt->active_samples_per_line; - } - info.xyz = &FIELD_1_ACTIVE; - for (info.ln = 42; info.ln <= 1121; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line++, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - } - if (info.blanking) { - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 1122; info.ln <= 1125; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } - } else { - if (info.blanking) { - elements = info.fmt->samples_per_line; - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 1; info.ln <= 25; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } else { - elements = info.fmt->active_samples_per_line; - } - info.xyz = &FIELD_1_ACTIVE; - for (info.ln = 26; info.ln <= 745; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, active_video_line++, ACTIVE_VIDEO, vBuffer); - p = pack(p, line_buffer, elements); - } - if (info.blanking) { - info.xyz = &FIELD_1_VERT_BLANKING; - for (info.ln = 746; info.ln <= 750; info.ln++) { - create_HD_SDI_Line(line_buffer, &info, 0, VERT_BLANKING, vBuffer); - p = pack(p, line_buffer, elements); - } - } - } - } - } - - // sum of bytes that have already been written to file - int bytes = 0; - // store actual written bytes per 'write() - int written_bytes = 0; - - /** - * WRITE BUFFER TO FILEHANDLE - **/ - // Write the complete frame to output - // The "while" is necessary because the sdi device file does not take the complete frame at once - written_bytes = 0; - while (bytes < sdi_frame_size) { - - if ((written_bytes = write(fh_sdi_video, data + bytes, sdi_frame_size - bytes)) < 0) { - fprintf(stderr, "\nunable to write SDI video.\n"); - return -1; - } - bytes += written_bytes; - } - - // Check for events of the SDI board - unsigned int val; - if (ioctl(fh_sdi_video, SDI_IOC_TXGETEVENTS, &val) < 0) { - // Maybe this is not an SDI device... - //fprintf(stderr, "SDI VIDEO output:"); - //perror("unable to get the transmitter event flags"); - } else if (val) { - if (val & SDI_EVENT_TX_BUFFER) { - printf("SDI VIDEO driver transmit buffer queue underrun " - "detected.\n"); - fflush(stdout); - } - if (val & SDI_EVENT_TX_FIFO) { - printf("SDI VIDEO onboard transmit FIFO underrun detected.\n"); - fflush(stdout); - } - if (val & SDI_EVENT_TX_DATA) { - printf("SDI VIDEO transmit data change detected.\n"); - fflush(stdout); - } - } - - // if available write audio data - if (fh_sdi_audio) { - - // count written bytes - written_bytes = 0; - - // set number of samples and cut by 1600 if NTSC (handle problem of real time encoding of NTSC frequencies) - size_t samples_total_per_track = audio_format->samples; - uint16_t sample_number = 0; - size_t channels_per_track_total = 2; - uint8_t stream_number = 0; - - //printf("samples_total_per_track:%li\n", samples_total_per_track); - - // to write blockwise 2 samples of one track we must calculate the number of bytes we want to write per write-session - // 2samples = 2x16Bit = 32Bit = 4Byte - // 2samples = 2x32Bit = 64Bit = 8Byte - // set total bytes per session - size_t bytes_total = 0; - bytes_total = audio_format->aformat == mlt_audio_s16 ? channels_per_track_total * sizeof(int16_t) : bytes_total; - bytes_total = audio_format->aformat == mlt_audio_s32 ? channels_per_track_total * sizeof(int32_t) : bytes_total; - - // write all samples of all streams interleaved - /** - * aBuffer[track0]+sample1 - * aBuffer[track0]+sample2 - * aBuffer[track1]+sample1 - * aBuffer[track1]+sample2 - * aBuffer[track.]+sample1 - * aBuffer[track.]+sample2 - * - * aBuffer[track0]+sample3 - * aBuffer[track0]+sample4 - * aBuffer[track1]+sample3 - * aBuffer[track1]+sample4 - * aBuffer[track.]+sample3 - * aBuffer[track.]+sample4 - * - * aBuffer[track0]+sample5 - * aBuffer[track0]+sample6 - * aBuffer[track1]+sample5 - * aBuffer[track1]+sample6 - * aBuffer[track.]+sample5 - * aBuffer[track.]+sample6 - **/ - int sum_written_bytes = 0; - int sum_written_bytes_a = 0; - int sum_written_bytes_b = 0; - - // write all samples per track - while (sample_number < samples_total_per_track) { - - stream_number = 0; - - /** - * Because we have and write a fix number of audio streams to SDI board: - * we have a actual number of real audio tracks and a rest number of pseudo tracks - **/ - // write all streams - while (stream_number < audio_streams) { - - // write for every stream n samples - // n = number of channels per stream - written_bytes = 0; - while (written_bytes < bytes_total) { - written_bytes += write(fh_sdi_audio, (uint8_t *) aBuffer[stream_number] + sample_number * bytes_total + written_bytes, - bytes_total - written_bytes); - } - sum_written_bytes += written_bytes; - sum_written_bytes_a += written_bytes; - - stream_number++; - } - - // write pseudo tracks - // now fill rest of audio tracks(AES frames) with NULL or copy of first track - while (stream_number < audio_format->channels / 2) { - - // write for every stream n samples - // n = number of channels per stream - written_bytes = 0; - while (written_bytes < bytes_total) { - written_bytes += write(fh_sdi_audio, (uint8_t *) aBuffer[0] + sample_number * bytes_total + written_bytes, - bytes_total - written_bytes); - } - sum_written_bytes += written_bytes; - sum_written_bytes_b += written_bytes; - - stream_number++; - } - - sample_number++; - - // Check for events of the SDI audio device - unsigned int val; - if (ioctl(fh_sdi_audio, SDIAUDIO_IOC_TXGETEVENTS, &val) < 0) { - //Maybe this is not an SDI device... - // fprintf(stderr, "SDI AUDIO output:"); - // perror("unable to get the transmitter event flags"); - } else if (val) { - if (val & SDIAUDIO_EVENT_TX_BUFFER) { - printf("SDI AUDIO driver transmit buffer queue underrun " - "detected.\n"); - } - if (val & SDIAUDIO_EVENT_TX_FIFO) { - printf("SDI AUDIO onboard transmit FIFO underrun detected.\n"); - } - if (val & SDIAUDIO_EVENT_TX_DATA) { - printf("SDI AUDIO transmit data change detected.\n"); - } - } - } - } - - return getDBN(my_DBN); -} // end sdimaster_playout() - - -//**************************************************************************************** -//*************************** Create Line ********************************************** -//**************************************************************************************** - -/** generate one SDI line - * @param *buf: buffer to hold the line - * @param field: size of the video Buffer - * @param active: v-blank or active-video - * @param *video_buffer: video buffer - * @param *audio_buffer2: 1.audio buffer ch1-ch2 - * @param *audio_buffer1: 2.audio buffer ch2-ch3 - * @param line: linenumber - * @param AudioGroupCounter: count written AudioGroup - * @param AudioGroups2Write: number of samples to write - * @param audio_streams: number of audio streams to integrate - */ -static inline int create_SD_SDI_Line(uint16_t *buf, const struct line_info *info, int field, int active, uint8_t *video_buffer, - int16_t audio_buffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES], int linenumber_sdiframe, int active_video_line, int my_DBN, - int16_t AudioGroupCounter, int16_t AudioGroups2Write, int audio_streams) { - - // write line with TRS(EAV) ANC(audio) TRS(SAV) activeVideo(CbY1CrY2) - // ************************************************************************* - // 625 lines: | EAV | ANC | SAV | [CbY1CrY2] | - // ************************************************************************* - // 1728 SDI-words: | 4 | 280 | 4 | 720+360+360=1440 | - // ************************************************************************* - - // points to current position in line - uint16_t *p = buf; - - //######################################################################################### - /* TRS Timing Reference Signal for EAV - * [3ff] - * [000] - * [000] - * [XYZ-Wort] - * */ - - *p++ = 0x3ff; - *p++ = 0x000; - *p++ = 0x000; - *p++ = info->xyz->eav; - //######################################################################################### - - /* ANC Ancillary Data with AES - * - * [ADF][ADF][ADF][DID][DBN][DC][UDW]...[UDW][CS] - * - * */ - // write ANC Data and get number of samples are written - // step with `p` += to the number of written samples - - //printf("audio_streams:%i\n",audio_streams); - - // 1 stream, Audio Group 1 with AES Frame 1 - 2 - if (audio_streams == 1) { - p += writeANC(p, linenumber_sdiframe, 0x2FF, my_DBN, audio_buffer[0], audio_buffer[0], AudioGroupCounter, AudioGroups2Write); - } - // 2 streams, Audio Group 1 with AES Frame 1 - 2 - if (audio_streams == 2) { - p += writeANC(p, linenumber_sdiframe, 0x2FF, my_DBN, audio_buffer[0], audio_buffer[1], AudioGroupCounter, AudioGroups2Write); - } - // 3 streams, Audio Group 2 with AES Frame 1 - 4 - if (audio_streams == 3) { - p += writeANC(p, linenumber_sdiframe, 0x2FF, my_DBN, audio_buffer[0], audio_buffer[1], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FD, my_DBN, audio_buffer[2], audio_buffer[2], AudioGroupCounter, AudioGroups2Write); - } - // 4 streams, Audio Group 2 with AES Frame 1 - 4 - if (audio_streams == 4) { - p += writeANC(p, linenumber_sdiframe, 0x2FF, my_DBN, audio_buffer[0], audio_buffer[1], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FD, my_DBN, audio_buffer[2], audio_buffer[3], AudioGroupCounter, AudioGroups2Write); - } - // 5 streams, Audio Group 3 with AES Frame 1 - 6 - if (audio_streams == 5) { - p += writeANC(p, linenumber_sdiframe, 0x2FF, my_DBN, audio_buffer[0], audio_buffer[1], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FD, my_DBN, audio_buffer[2], audio_buffer[3], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FB, my_DBN, audio_buffer[4], audio_buffer[4], AudioGroupCounter, AudioGroups2Write); - } - // 6 streams, Audio Group 3 with AES Frame 1 - 6 - if (audio_streams == 6) { - p += writeANC(p, linenumber_sdiframe, 0x2FF, my_DBN, audio_buffer[0], audio_buffer[1], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FD, my_DBN, audio_buffer[2], audio_buffer[3], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FB, my_DBN, audio_buffer[4], audio_buffer[5], AudioGroupCounter, AudioGroups2Write); - } - // 7 streams, Audio Group 4 with AES Frame 1 - 7 - if (audio_streams == 7) { - p += writeANC(p, linenumber_sdiframe, 0x2FF, my_DBN, audio_buffer[0], audio_buffer[1], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FD, my_DBN, audio_buffer[2], audio_buffer[3], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FB, my_DBN, audio_buffer[4], audio_buffer[5], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x2F9, my_DBN, audio_buffer[6], audio_buffer[6], AudioGroupCounter, AudioGroups2Write); - } - // 8 streams, Audio Group 4 with AES Frame 1 - 7 - if (audio_streams == 8) { - p += writeANC(p, linenumber_sdiframe, 0x2FF, my_DBN, audio_buffer[0], audio_buffer[1], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FD, my_DBN, audio_buffer[2], audio_buffer[3], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x1FB, my_DBN, audio_buffer[4], audio_buffer[5], AudioGroupCounter, AudioGroups2Write); - p += writeANC(p, linenumber_sdiframe, 0x2F9, my_DBN, audio_buffer[6], audio_buffer[7], AudioGroupCounter, AudioGroups2Write); - } - - // Fill ANC data in until the end (position(p) to `ANCILLARY_DATA_SAMPLES`) - while (p < (buf + ANCILLARY_DATA_SAMPLES + 4)) { - // video color: black - *p++ = 0x200; - *p++ = 0x040; - } - //######################################################################################### - // TRS Timing Reference Signal for SAV - *p++ = 0x3ff; - *p++ = 0x000; - *p++ = 0x000; - *p++ = info->xyz->sav; - //######################################################################################### - - - // Because we skip the first line of video, it can happen that we read too far in the buffer - if (active_video_line >= info->fmt->active_lines_per_frame) { - active_video_line = info->fmt->active_lines_per_frame - 1; // in SD PAL was set 575 - } - //Index of the start of the current line in the video_buffer - int start_of_current_line = active_video_line * info->fmt->active_samples_per_line; - - // If VBlank then fill the line with 0x200 and 0x040 (total black) - switch (active) { - default: - case VERT_BLANKING: - while (p < (buf + info->fmt->samples_per_line)) { - *p++ = 0x200; - *p++ = 0x040; - } - break; - case ACTIVE_VIDEO: - - // Insert the video into the line - while (p < (buf + info->fmt->samples_per_line)) { // fill the rest of the line with active video - - // shift "<< 2" because 8 bit data in 10 bit word - - *p = video_buffer[start_of_current_line + ((p - 288) - buf) + 1] << 2; // Cb - p++; - if (*(p - 1) < 0x040) - *(p - 1) = 0x040; // check values - if (*(p - 1) > 0x3c0) - *(p - 1) = 0x3c0; - *p = video_buffer[start_of_current_line + ((p - 288) - buf) - 1] << 2; // Y1 - p++; - if (*(p - 1) < 0x040) - *(p - 1) = 0x040; - if (*(p - 1) > 0x3ac) - *(p - 1) = 0x3ac; - *p = video_buffer[start_of_current_line + ((p - 288) - buf) + 1] << 2; // Cr - p++; - if (*(p - 1) < 0x040) - *(p - 1) = 0x040; - if (*(p - 1) > 0x3c0) - *(p - 1) = 0x3c0; - *p = video_buffer[start_of_current_line + ((p - 288) - buf) - 1] << 2; // Y2 - p++; - if (*(p - 1) < 0x040) - *(p - 1) = 0x040; - if (*(p - 1) > 0x3ac) - *(p - 1) = 0x3ac; - - } - break; - } - return 0; -} - -/** - * create_HD_SDI_Line - generate one line - * @buf: pointer to a buffer - * @info: pointer to a line information structure - * @active_video_line - * @active: - * @video_buffer: pattern - * - * Returns a negative error code on failure and zero on success. - **/ -static inline int create_HD_SDI_Line(uint16_t *buf, const struct line_info *info, uint16_t active_video_line, unsigned int active, - uint8_t *video_buffer) { - uint16_t *p = buf, ln; - uint16_t samples = info->blanking ? info->fmt->samples_per_line : info->fmt->active_samples_per_line; - - if (active_video_line >= info->fmt->active_lines_per_frame) { - active_video_line = info->fmt->active_lines_per_frame - 1; - } - - int start_of_current_line = active_video_line * info->fmt->active_samples_per_line; - - if (info->blanking) { - - // write line with TRS(EAV) ANC(audio) TRS(SAV) activeVideo(CbY1CrY2) - // Example SD PAL: - // ************************************************************************* - // 625 lines: | EAV | ANC | SAV | [CbY1CrY2] | - // ************************************************************************* - // 1728 SDI-words: | 4 | 280 | 4 | 720+360+360=1440 | - // ************************************************************************* - - // write line with TRS(EAV) ANC(audio) TRS(SAV) activeVideo(CbY1CrY2) - // Example HD 1080i: - // ************************************************************************* - // 1125 lines: | EAV | LN | CRC | ANC | SAV | [CbY1CrY2] | - // ************************************************************************* - // 5280 SDI-words: | 6 | 4 | 4 | 280 | 6 | 1920+720+720=3840 | - // ************************************************************************* - - if (info->fmt == &FMT_576i50) { - /* EAV */ - *p++ = 0x3ff; - *p++ = 0x000; - *p++ = 0x000; - *p++ = info->xyz->eav; - } else { - /* EAV */ - *p++ = 1023; - *p++ = 1023; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = info->xyz->eav; - *p++ = info->xyz->eav; - /* LN */ - ln = ((info->ln & 0x07f) << 2) | (~info->ln & 0x040) << 3; - *p++ = ln; - *p++ = ln; - ln = ((info->ln & 0x780) >> 5) | 0x200; - *p++ = ln; - *p++ = ln; - /* CRC, added by serializer */ - *p++ = 512; - *p++ = 64; - *p++ = 512; - *p++ = 64; - - } - - /* Horizontal blanking */ - while (p < (buf + info->fmt->samples_per_line - info->fmt->active_samples_per_line - 4)) { - *p++ = 512; - *p++ = 64; - *p++ = 512; - *p++ = 64; - } - - if (info->fmt == &FMT_576i50) { - /* SAV */ - *p++ = 0x3ff; - *p++ = 0x000; - *p++ = 0x000; - *p++ = info->xyz->sav; - } else { - /* SAV */ - *p++ = 1023; - *p++ = 1023; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = 0; - *p++ = info->xyz->sav; - *p++ = info->xyz->sav; - } - } - - switch (active) { - default: - case VERT_BLANKING: - while (p < (buf + samples)) { - *p++ = 512; - *p++ = 64; - *p++ = 512; - *p++ = 64; - } - break; - case ACTIVE_VIDEO: - - { - - while (p < (buf + samples)) { - - *p = video_buffer[start_of_current_line + (p - buf) + 1] << 2; // Cb - p++; - //check values, this needs a lot of resources - // if (*(p - 1) < 0x040) - // *(p - 1) = 0x040; - // if (*(p - 1) > 0x3c0) - // *(p - 1) = 0x3c0; - // - *p = video_buffer[start_of_current_line + (p - buf) - 1] << 2; // Y1 - p++; - // if (*(p - 1) < 0x040) - // *(p - 1) = 0x040; - // if (*(p - 1) > 0x3ac) - // *(p - 1) = 0x3ac; - // - *p = video_buffer[start_of_current_line + (p - buf) + 1] << 2; // Cr - p++; - // if (*(p - 1) < 0x040) - // *(p - 1) = 0x040; - // if (*(p - 1) > 0x3c0) - // *(p - 1) = 0x3c0; - // - *p = video_buffer[start_of_current_line + (p - buf) - 1] << 2; // Y2 - p++; - // if (*(p - 1) < 0x040) - // *(p - 1) = 0x040; - // if (*(p - 1) > 0x3ac) - // *(p - 1) = 0x3ac; - } - } - break; - } - return 0; -} - -static int writeANC(uint16_t *p, int videoline_sdiframe, uint16_t DID, int my_DBN, int16_t *audio_buffer_A, int16_t *audio_buffer_B, - int16_t AudioGroupCounter, int16_t AudioGroups2Write) { - - /** - * ANC Ancillary Data (vgl. SMPTE 291-M page 6 ) - * [ADF][ADF][ADF][DID][DBN][DC][UDW]...[UDW][CS] - * - **/ - - // save only current position for return value - uint16_t *pp = p; - // 16bit buffer to write temporarily 10bit word - uint16_t buffer = 0; // set all explicit to zero, special the bit9 for parity - // parity_counter - int8_t parity_counter = 0; - - if (AudioGroups2Write > 0) { - - // 3 ADF (Ancillary Data Flag) - *p++ = 0x000; - *p++ = 0x3FF; - *p++ = 0x3FF; - - // 1 DID (Data Identification) - // save DID for checker() - uint16_t *DID_pointer = p; - *p++ = DID;// (AES Audio Data, Group - // *p++ = 0x2FF; // (AES Audio Data, Group1=0x2FF) - // *p++ = 0x1FD; // (AES Audio Data, Group2=0x1FD) - // *p++ = 0x1FB; // (AES Audio Data, Group3=0x1FB) - // *p++ = 0x2F9; // (AES Audio Data, Group4=0x2F9) - - // 1 DBN (Data Block Number) inactiv: 1000000000 b9,b8,b7-b0 ; SMPTE 272-M chapter15.1 - // *p++ = 0x200; - - // 1 DBN (dynamic version0.1-beta ), should start with previous DBN of SDI-Frame - // -need "previous DBN" or "current framenumber" - // SDI-LINE: DBN: - // [1] [1] << start sdi frame - // [2] [2] - // [.] [.] - // [255] [255] - // [256] [1] - // [257] [2] - // [.] [.] - // [510] [255] - // [511] [1] - // [512] [2] - // [.] [.] - // [625] [115] << end sdi frame - // [1] [116] << start sdi frame - // Accuracy of videoline_sdiframe(1 up to 625) to 8bit (1-255) - //buffer = ((videoline_sdiframe-1) % 255)+1; - buffer = my_DBN; - parity_counter = 0; - // count binary ones for parity - int i = 0; - for (i = 0; i < 8; i++) { - if (buffer & (1 << i)) - parity_counter++; - } - if ((parity_counter % 2) == 0) { //else leave the 0 - buffer += 512; // 10 0000 0000 // set bit8 = even parity bit and bit9 = !bit8 - } else { - buffer += 256; // 01 0000 0000 // set bit8 = even parity bit and bit9 = !bit8 - } - *p++ = buffer; - - // 1 DC (Data Counter) - // number of UDW = AudioGroups2Write x 2AESFrames x 2channesl x 3words(X,X+1,X+2) - buffer = AudioGroups2Write * 2 * 2 * 3; - parity_counter = 0; - // count binary ones for parity - for (i = 0; i < 8; i++) { - if (buffer & (1 << i)) - parity_counter++; - } - if ((parity_counter % 2) == 0) { //else leave the 0 - buffer += 512; // 10 0000 0000 // set bit8 = even parity bit and bit9 = !bit8 - } else { - buffer += 256; // 01 0000 0000 // set bit8 = even parity bit and bit9 = !bit8 - } - *p++ = buffer; - - int16_t sample_number = 0; - int16_t counter = 0; - // write subframes: - // = n x 1 AudioGroup - // = n x 2 x 1AESFrame - // = n x 2 x 2samples - // = 4 samples - // = 4 x 3words - while (counter < AudioGroups2Write * 2) { /* 4:3 */ - - // write one Audio Group with 4 x AES subframes - // ( samples for ch01,ch02,ch03,ch04 or ch05,ch06,ch07,ch08 or ch09,ch10,ch11,ch12 or ch13,ch14,ch15,ch16) - // and use audio_buffer_A(stereo) and audio_buffer_B(stereo) - // `pack_AES_subframe()` write 3 ANC words (3*10bit), also 1 sample - - sample_number = (AudioGroupCounter * 2) + counter; - pack_AES_subframe(p, getChannelStatusBit(sample_number / 2, 1), getZBit(sample_number / 2), 0, &audio_buffer_A[sample_number]); // left - p += 3; // step 3 words - - sample_number = (AudioGroupCounter * 2) + counter + 1; - pack_AES_subframe(p, getChannelStatusBit(sample_number / 2, 2), getZBit(sample_number / 2), 1, &audio_buffer_A[sample_number]); // right - p += 3; - - sample_number = (AudioGroupCounter * 2) + counter; - pack_AES_subframe(p, getChannelStatusBit(sample_number / 2, 3), getZBit(sample_number / 2), 2, &audio_buffer_B[sample_number]); // left - p += 3; - - sample_number = (AudioGroupCounter * 2) + counter + 1; - pack_AES_subframe(p, getChannelStatusBit(sample_number / 2, 4), getZBit(sample_number / 2), 3, &audio_buffer_B[sample_number]); // right - p += 3; - counter += 2; - } - - // 1 CS (Checksum from DID - UDW) - *p++ = checker(DID_pointer); - - // fill ANC with one dummy for videocolor black - // rest until end of `ANCILLARY_DATA_SAMPLES` will be fill in a loop after call this function - *p++ = 0x040; - } - return p - pp; -} - -// calculate checksumm of ANC (SMPTE 272-M 15.3 Checksum (CS)) -static uint16_t checker(uint16_t *DID_pointer) { - - // Checksumm - uint16_t cs = 0x00; - - // DID - Datablock Identification - cs += (*DID_pointer++) & 0x1FF; // 9 x LSB - - // DBN - Datablock Number - cs += (*DID_pointer++) & 0x1FF; // 9 x LSB - - // DC - DataCounter - cs += (*DID_pointer) & 0x1FF; // 9 x LSB - - // store address of DC an ad to the real value of DC - // DataCounter store - // ´ende´ point to DataCounter - uint16_t *ende = DID_pointer; - // ´ende´ point to last field - ende += (*DID_pointer) & 0xFF; // without parity-Bit and ¬9-Bit - - DID_pointer++; - - // while DID_pointer point to smaller address like 'ende' - while (DID_pointer <= ende) { - cs += (*DID_pointer++) & 0x1FF; // 9 x LSB - } - - // limit to 9Bit, because of overflow of sum - cs = cs & 0x1FF; - - // set bit10 NOT bit9: - // - cs invert - // - & with bitmask '01 0000 0000' - // - shift rest (1xbit)to left - // - add to cs - cs += ((~cs) & 0x100) << 1; - - return cs; -} // end checker - - -/** - * pack 16bit in AES subframe with 3 words (30 bit) and write in ´*p´ - * 10bit-words --> [X],[X+1], [X+2] implements 20bit for audio - * - * BIT 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 - * ##### ### ### ### ### ### ### ### ### ### - * [X] : [ !bit8, a5, a4, a3, a2, a1, a0, ch0, ch1, z ], - * [X+1] : [ !bit8, a14, a13, a12, a11, a10, a9, a8, a7 , a6 ], - * [X+2] : [ !bit8, P, C, U, V, a19, a18, a17, a16, a15 ] - * - * @param *p: Pointer to SDI frame buffer - * @param c: value of AES subframe Channel Status Bit - * @param z: value of AES subframe - * @param ch: channel od AES subframe (value:0,1,2,3) - * @param *audio_samplex: pointer to the audio buffer - **/ -static int pack_AES_subframe(uint16_t *p, int8_t c, int8_t z, int8_t ch, int16_t *audio_samplex) { - - /** - * NOTE: WE JUST SUPPORT ONLY 16BIT SAMPLE SIZE - **/ - - // push 16bit up to 20bit(32bit) - int32_t audio_sample = *audio_samplex; - audio_sample = audio_sample << 4; // Shift by 4 (louder) - - // parity_counter - int8_t parity_counter = 0; - - // 16bit buffer to write 10bit of [X]word,[X+1]word,[X+2]word, - uint16_t buffer = 0; - - //######################################################### - //### WORD X ############################################ - //######################################################### - // word X: !bit8, a5, a4, a3, a2, a1, a0, ch1, ch0, z - // SMPTE 272M s.7 - buffer = z; // z bit every 192bit = 1 - buffer += ch << 1; // ch1 - ch0 - buffer += (audio_sample & 0x3f) << 3; // a5 - a0 - buffer += ((~buffer) & 0x100) << 1; // !bit8 - - // write word ´X´ - *p++ = buffer; - - // count ones - int i = 0; - for (i = 0; i < 9; i++) { - if (buffer & 1 << i) - parity_counter++; - } - - //######################################################### - //### WORD X+1 ############################################ - //######################################################### - // word X+1: !bit8, a14, a13, a12, a11, a10, a9, a8, a7, a6 - // SMPTE 272M s.7 - buffer = 0; - buffer += (audio_sample >> 6) & 0x1ff; // a14 - a6 - buffer += ((~buffer) & 0x100) << 1; // !bit8 - - // write word ´X+1´ - *p++ = buffer; - - // count ones (zähle Einsen) - i = 0; - for (i = 0; i < 9; i++) { - if (buffer & 1 << i) - parity_counter++; - } - - //######################################################### - //### WORD X+2 ############################################ - //######################################################### - // word X+2: !bit8, P, C, U, V, a19, a18, a17, a16, a15 - // SMPTE 272M s.7 - buffer = 0; - buffer += (audio_sample >> 15) & 0x01F; // a15 - a19 - // default of [V][U][C] bits = `0` - //buffer += 1<<5; // V (AES sample validity bit) - //buffer += 1<<6; // U (AES user bit) - //buffer += 1<<7; // C (AES audio channel status bit) - buffer += c << 7; // C (AES audio channel status bit) - - // count ones (zähle Einsen) - for (i = 0; i < 8; i++) { - if (buffer & 1 << i) - parity_counter++; - } - - // if (!parity_counter%2) //else leave the 0 - // buffer+= 1 << 8; // P (AES even parity bit) - // - // buffer += ((~buffer) & 0x100 )<<1; // !bit8 - if ((parity_counter % 2) == 0) { //else leave the 0 - buffer += 512; // 10 0000 0000 // set bit8 = even parity bit and bit9 = !bit8 - } else { - buffer += 256; // 01 0000 0000 // set bit8 = even parity bit and bit9 = !bit8 - } - *p++ = buffer; - - // write word ´X+2´ - *p++ = buffer; - - return 1; -} - -static uint8_t getZBit(int sample_number) { - - // start in SDI line 6 also 18samples later - //sample_number+=192-18; - - if (sample_number % 192 == 0) { - //printf("1 %i\n", sample_number); - return 1; - } else { - //printf("0"); - return 0; - } -} - -static uint8_t getChannelStatusBit(uint16_t sample_number, uint8_t ch) { - - // return value - uint8_t AESChannelStatusBit = 0; - - // start in SDI line 6 also 18samples later - //AESChannelStatusBit=((sample_number+192-18)%192); - // interval in 192bit - AESChannelStatusBit = sample_number % 192; - - // when mulichannelmode is true - if (AESChannelStatusBitArray[31] == 1) { - // set bits for channel - if (AESChannelStatusBit == 30 && ch == 2) - return 1; - if (AESChannelStatusBit == 30 && ch == 4) - return 1; - if (AESChannelStatusBit == 29 && (ch == 4)) - return 1; - if (AESChannelStatusBit == 29 && (ch == 3)) - return 1; - } - return AESChannelStatusBitArray[AESChannelStatusBit]; -} - -static int16_t getNumberOfAudioGroups2Write(int linenumber) { - - // `4:3_VTR`-distribution - if (linenumber >= 11 && linenumber <= 95) { - if ((linenumber - 11) % 14 == 0) { - return 4; - } else { - return 3; - } - } else if (linenumber >= 108 && linenumber <= 220) { - if ((linenumber - 10) % 14 == 0) { - return 4; - } else { - return 3; - } - } else if (linenumber >= 233 && linenumber <= 345) { - if ((linenumber - 9) % 14 == 0) { - return 4; - } else { - return 3; - } - } else if (linenumber >= 358 && linenumber <= 470) { - if ((linenumber - 8) % 14 == 0) { - return 4; - } else { - return 3; - } - } else if (linenumber >= 483 && linenumber <= 595) { - if ((linenumber - 7) % 14 == 0) { - return 4; - } else { - return 3; - } - } else if (linenumber >= 608 && linenumber <= 622) { - if ((linenumber - 6) % 14 == 0) { - return 4; - } else { - return 3; - } - } else { - return 3; - } - - // // `4:3`-distribution - // if(linenumber<=315){ - // if(linenumber>=6 && linenumber<=8){ - // return 0; - // } - // if((linenumber+5)%10==0){ - // return 4; - // }else{ - // return 3; - // } - // }else{ - // if(linenumber>=319 && linenumber<=321){ - // return 0; - // } - // if((linenumber-8)%10==0){ - // return 4; - // }else{ - // return 3; - // } - // } - - // // full-distribution - // if(linenumber<=45){ - // return 4; - // }else{ - // return 3; - // } - - // // fullhalf-distribution - // if (linenumber==625) - // return 4; - // - // if (linenumber%14==0) { - // return 4; - // } else { - // return 3; - // } - -} -static uint8_t getDBN(int my_DBN) { - - return ((my_DBN - 1) % 255) + 1; -} - -/** - * pack8 - pack a line of 8-bit data - * @outbuf: pointer to the output buffer - * @inbuf: pointer to the input buffer - * @count: number of elements in the buffer - * - * Returns a pointer to the next output location. - **/ -static inline uint8_t * -pack8(uint8_t *outbuf, uint16_t *inbuf, size_t count) { - uint16_t *inp = inbuf; - uint8_t *outp = outbuf; - - while (inp < (inbuf + count)) { - *outp++ = *inp++ >> 2; - } - return outp; -} - -/** - * pack10 - pack a line of 10-bit data - * @outbuf: pointer to the output buffer - * @inbuf: pointer to the input buffer - * @count: number of elements in the buffer - * - * Returns a pointer to the next output location. - **/ -static inline uint8_t * pack10(uint8_t *outbuf, uint16_t *inbuf, size_t count) { - - uint16_t *inp = inbuf; - uint8_t *outp = outbuf; - - while (inp < (inbuf + count)) { - *outp++ = *inp & 0xff; - *outp = *inp++ >> 8; - *outp++ += (*inp << 2) & 0xfc; - *outp = *inp++ >> 6; - *outp++ += (*inp << 4) & 0xf0; - *outp = *inp++ >> 4; - *outp++ += (*inp << 6) & 0xc0; - *outp++ = *inp++ >> 2; - } - - return outp; -} -/** - * pack_v210 - pack a line of v210 data - * @outbuf: pointer to the output buffer - * @inbuf: pointer to the input buffer - * @count: number of elements in the buffer - * - * Returns a pointer to the next output location. - **/ -static inline uint8_t * pack_v210(uint8_t *outbuf, uint16_t *inbuf, size_t count) { - - uint16_t *inp = inbuf; - uint8_t *outp = outbuf; - - count = (count / 96) * 96 + ((count % 96) ? 96 : 0); - while (inp < (inbuf + count)) { - *outp++ = *inp & 0xff; - *outp = *inp++ >> 8; - *outp++ += (*inp << 2) & 0xfc; - *outp = *inp++ >> 6; - *outp++ += (*inp << 4) & 0xf0; - *outp++ = *inp++ >> 4; - } - return outp; -} - -// Clean up -static int sdimaster_close() { - - free(line_buffer); - free(data); - - if (fh_sdi_audio) - close(fh_sdi_audio); - if (fh_sdi_video) - close(fh_sdi_video); - - return 1; -} - -/** - * mkline - generate one line - * @buf: pointer to a buffer - * @info: pointer to a line information structure - * @pattern: pattern - * - * Returns a negative error code on failure and zero on success. - **/ -static int mkline(unsigned short int *buf, const struct line_info *info, unsigned int pattern) { - const unsigned int b = 205; - unsigned short int *p = buf, *endp; - unsigned int samples = info->blanking ? info->fmt->samples_per_line : info->fmt->active_samples_per_line; - - if (info->blanking) { - /* EAV */ - *p++ = 0x3ff; - *p++ = 0x000; - *p++ = 0x000; - *p++ = info->xyz->eav; - /* Horizontal blanking */ - while (p < (buf + 272)) { - *p++ = 0x200; - *p++ = 0x040; - *p++ = 0x200; - *p++ = 0x040; - } - /* SAV */ - *p++ = 0x3ff; - *p++ = 0x000; - *p++ = 0x000; - *p++ = info->xyz->sav; - } - /* Active region */ - endp = p; - switch (pattern) { - default: - case VERT_BLANKING: - while (p < (buf + samples)) { - *p++ = 0x200; - *p++ = 0x040; - *p++ = 0x200; - *p++ = 0x040; - } - break; - case BLACK: /* black line (filler for FMT_480i5994 ) */ - while (p < (buf + samples)) { - *p++ = 0x200; - *p++ = 0x040; - *p++ = 0x200; - *p++ = 0x040; - } - break; - case GREEN: /* green line for test purpose */ - while (p < (buf + samples)) { - *p++ = 289; - *p++ = 450; - *p++ = 231; - *p++ = 450; - } - break; - case MAIN_SET: - /* 75% gray */ - endp += b + 1; - while (p < endp) { - *p++ = 512; - *p++ = 721; - *p++ = 512; - *p++ = 721; - } - /* 75% yellow */ - endp += b + 1; - while (p < endp) { - *p++ = 176; - *p++ = 646; - *p++ = 567; - *p++ = 646; - } - /* 75% cyan */ - endp += b + 1; - while (p < endp) { - *p++ = 625; - *p++ = 525; - *p++ = 176; - *p++ = 525; - } - /* 75% green */ - endp += b - 1; - while (p < endp) { - *p++ = 289; - *p++ = 450; - *p++ = 231; - *p++ = 450; - } - /* 75% magenta */ - endp += b + 1; - while (p < endp) { - *p++ = 735; - *p++ = 335; - *p++ = 793; - *p++ = 335; - } - /* 75% red */ - endp += b + 1; - while (p < endp) { - *p++ = 399; - *p++ = 260; - *p++ = 848; - *p++ = 260; - } - /* 75% blue */ - while (p < (buf + samples)) { - *p++ = 848; - *p++ = 139; - *p++ = 457; - *p++ = 139; - } - break; - case CHROMA_SET: - /* 75% blue */ - endp += b + 1; - while (p < endp) { - *p++ = 848; - *p++ = 139; - *p++ = 457; - *p++ = 139; - } - /* black */ - endp += b + 1; - while (p < endp) { - *p++ = 0x200; - *p++ = 0x040; - *p++ = 0x200; - *p++ = 0x040; - } - /* 75% magenta */ - endp += b + 1; - while (p < endp) { - *p++ = 735; - *p++ = 335; - *p++ = 793; - *p++ = 335; - } - /* black */ - endp += b - 1; - while (p < endp) { - *p++ = 0x200; - *p++ = 0x040; - *p++ = 0x200; - *p++ = 0x040; - } - /* 75% cyan */ - endp += b + 1; - while (p < endp) { - *p++ = 625; - *p++ = 525; - *p++ = 176; - *p++ = 525; - } - /* black */ - endp += b + 1; - while (p < endp) { - *p++ = 0x200; - *p++ = 0x040; - *p++ = 0x200; - *p++ = 0x040; - } - /* 75% gray */ - while (p < (buf + samples)) { - *p++ = 512; - *p++ = 721; - *p++ = 512; - *p++ = 721; - } - break; - case BLACK_SET: - /* -I */ - endp += 257; - while (p < endp) { - *p++ = 624; - *p++ = 231; - *p++ = 390; - *p++ = 231; - } - /* white */ - endp += 257; - while (p < endp) { - *p++ = 0x200; - *p++ = 940; - *p++ = 0x200; - *p++ = 940; - } - /* +Q */ - endp += 257; - while (p < endp) { - *p++ = 684; - *p++ = 177; - *p++ = 591; - *p++ = 177; - } - /* black */ - endp += 257; - while (p < endp) { - *p++ = 0x200; - *p++ = 0x040; - *p++ = 0x200; - *p++ = 0x040; - } - /* blacker than black */ - endp += 68; - while (p < endp) { - *p++ = 0x200; - *p++ = 29; - *p++ = 0x200; - *p++ = 29; - } - /* black */ - endp += 68 + 2; - while (p < endp) { - *p++ = 0x200; - *p++ = 0x040; - *p++ = 0x200; - *p++ = 0x040; - } - /* whiter than black */ - endp += 68; - while (p < endp) { - *p++ = 0x200; - *p++ = 99; - *p++ = 0x200; - *p++ = 99; - } - /* black */ - while (p < (buf + samples)) { - *p++ = 0x200; - *p++ = 0x040; - *p++ = 0x200; - *p++ = 0x040; - } - break; - } - return 0; -} - -static int setSDIVideoProperties(enum sdi_setting_video_e setting, char * value, char * device) { - - const char fmt[] = "/sys/class/sdivideo/sdivideo%cx%i/%s"; - struct stat buf; - int num; - char type, name[256], data[256]; - char *endptr; - - /* Get the sysfs info */ - memset(&buf, 0, sizeof(buf)); - - /** - * Stat the file, fills the structure with info about the file - * Get the major number from device node - **/ - if (stat(device, &buf) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to get the file status"); - return -1; - } - - /* Check if it is a character device or not */ - if (!S_ISCHR (buf.st_mode)) { - fprintf(stderr, "%s: not a character device\n", device); - return -1; - } - - /* Check the minor number to determine if it is a receive or transmit device */ - type = (buf.st_rdev & 0x0080) ? 'r' : 't'; - - /* Get the receiver or transmitter number */ - num = buf.st_rdev & 0x007f; - - /* Build the path to sysfs file */ - snprintf(name, sizeof(name), fmt, type, num, "dev"); - memset(data, 0, sizeof(data)); - - /* Read sysfs file (dev) */ - if (util_read(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to get the device number"); - return -1; - } - /* Compare the major number taken from sysfs file to the one taken from device node */ - if (strtoul(data, &endptr, 0) != (buf.st_rdev >> 8)) { - fprintf(stderr, "%s: not a SMPTE 292M/SMPTE 259M-C device\n", device); - return -1; - } - if (*endptr != ':') { - fprintf(stderr, "%s: error reading %s\n", device, name); - return -1; - } - - // Which setting do we write - if (setting == SETTING_BUFFER_NUMBER_VIDEO) { - snprintf(name, sizeof(name), fmt, type, num, "buffers"); - snprintf(data, sizeof(data), "%s\n", value); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set the number of buffers"); - return -1; - } - printf("\tSet number of buffers = %s\n", value); - } else if (setting == SETTING_BUFFER_SIZE_VIDEO) { - snprintf(name, sizeof(name), fmt, type, num, "bufsize"); - snprintf(data, sizeof(data), "%s\n", value); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set the buffer size"); - return -1; - } - printf("\tSet buffer size = %s Bytes\n", value); - } else if (setting == SETTING_CLOCK_SOURCE) { - snprintf(name, sizeof(name), fmt, type, num, "clock_source"); - snprintf(data, sizeof(data), "%s\n", value); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set the clock source"); - return -1; - } - printf("\tSet clock source = %s\n", value); - } else if (setting == SETTING_DATA_MODE) { - snprintf(name, sizeof(name), fmt, type, num, "mode"); - snprintf(data, sizeof(data), "%s\n", value); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set the interface operating mode"); - return -1; - } - printf("\tSet data mode = %s\n", value); - } else if (setting == SETTING_FRAME_MODE) { - snprintf(name, sizeof(name), fmt, type, num, "frame_mode"); - snprintf(data, sizeof(data), "%s\n", value); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set the interface frame mode"); - return -1; - } - printf("\tSet frame mode = %s\n", value); - } - - return 0; - -} - -static int setSDIAudioProperties(enum sdi_setting_audio_e setting, char * value, char * device) { - const char fmt[] = "/sys/class/sdiaudio/sdiaudio%cx%i/%s"; - struct stat buf; - int num; - char type, name[256], data[256]; - char *endptr; - - /* Get the sysfs info */ - memset(&buf, 0, sizeof(buf)); - if (stat(device, &buf) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to get the file status"); - return -1; - } - if (!S_ISCHR (buf.st_mode)) { - fprintf(stderr, "%s: not a character device\n", device); - return -1; - } - type = (buf.st_rdev & 0x0080) ? 'r' : 't'; - num = buf.st_rdev & 0x007f; - snprintf(name, sizeof(name), fmt, type, num, "dev"); - memset(data, 0, sizeof(data)); - if (util_read(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to get the device number"); - return -1; - } - - if (strtoul(data, &endptr, 0) != (buf.st_rdev >> 8)) { - fprintf(stderr, "%s: not an audio device\n", device); - return -1; - } - if (*endptr != ':') { - fprintf(stderr, "%s: error reading %s\n", device, name); - return -1; - } - - if (setting == SETTING_BUFFER_NUMBER_AUDIO) { - snprintf(name, sizeof(name), fmt, type, num, "buffers"); - snprintf(data, sizeof(data), "%s\n", value); - - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set the number of buffers"); - return -1; - } - printf("\tSet number of buffers = %s\n", value); - } else if (setting == SETTING_BUFFER_SIZE_AUDIO) { - snprintf(name, sizeof(name), fmt, type, num, "bufsize"); - snprintf(data, sizeof(data), "%s\n", value); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set the buffer size"); - return -1; - } - printf("\tSet buffer size = %s Bytes\n", value); - } else if (setting == SETTING_SAMPLE_SIZE) { - snprintf(name, sizeof(name), fmt, type, num, "sample_size"); - snprintf(data, sizeof(data), "%s\n", value); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set the interface audio sample size"); - return -1; - } - switch (atol(value)) { - case SDIAUDIO_CTL_AUDSAMP_SZ_16: - printf("\tAssuming 16-bit audio.\n"); - break; - case SDIAUDIO_CTL_AUDSAMP_SZ_24: - printf("\tAssuming 24-bit audio.\n"); - break; - case SDIAUDIO_CTL_AUDSAMP_SZ_32: - printf("\tAssuming 32-bit audio.\n"); - break; - default: - printf("\tSet audio sample size = %lu.\n", atol(value)); - break; - } - } else if (setting == SETTING_SAMPEL_RATE) { - snprintf(name, sizeof(name), fmt, type, num, "sample_rate"); - snprintf(data, sizeof(data), "%lu\n", atol(value)); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set the interface audio sample rate"); - return -1; - } - switch (atoi(value)) { - case 32000: - printf("\tAssuming 32 kHz audio.\n"); - break; - case 44100: - printf("\tAssuming 44.1 kHz audio.\n"); - break; - case 48000: - printf("\tAssuming 48 kHz audio.\n"); - break; - default: - printf("\tSet audio sample rate = %lu.\n", atol(value)); - break; - } - } else if (setting == SETTING_CHANNELS) { - snprintf(name, sizeof(name), fmt, type, num, "channels"); - snprintf(data, sizeof(data), "%lu\n", atol(value)); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set " - "the interface audio channel enable"); - return -1; - } - switch (atol(value)) { - case SDIAUDIO_CTL_AUDCH_EN_0: - printf("\tDisabling audio.\n"); - break; - case SDIAUDIO_CTL_AUDCH_EN_2: - printf("\tAssuming 2 channels of audio.\n"); - break; - case SDIAUDIO_CTL_AUDCH_EN_4: - printf("\tAssuming 4 channels of audio.\n"); - break; - case SDIAUDIO_CTL_AUDCH_EN_6: - printf("\tAssuming 6 channels of audio.\n"); - break; - case SDIAUDIO_CTL_AUDCH_EN_8: - printf("\tAssuming 8 channels of audio.\n"); - break; - default: - printf("\tSet audio channel enable = %lu.\n", atol(value)); - break; - } - } else if (setting == SETTING_NON_AUDIO) { - snprintf(name, sizeof(name), fmt, type, num, "non_audio"); - snprintf(data, sizeof(data), "0x%04lX\n", atol(value)); - if (util_write(name, data, sizeof(data)) < 0) { - fprintf(stderr, "%s: ", device); - perror("unable to set " - "the interface non-audio"); - return -1; - } - switch (atol(value)) { - case 0x0000: - printf("\tPassing PCM audio.\n"); - break; - case 0x00ff: - printf("\tPassing non-audio.\n"); - break; - default: - printf("\tSet non-audio = 0x%04lX.\n", atol(value)); - break; - } - } - - return 0; -} - -static ssize_t util_read(const char *name, char *buf, size_t count) { - ssize_t fd, ret; - - if ((fd = open(name, O_RDONLY)) < 0) { - return fd; - } - ret = read(fd, buf, count); - close(fd); - return ret; -} - -static ssize_t util_write(const char *name, const char *buf, size_t count) { - ssize_t fd, ret; - - if ((fd = open(name, O_WRONLY)) < 0) { - return fd; - } - ret = write(fd, buf, count); - close(fd); - return ret; -} - -static char * itoa(uint64_t i) { - - if (i == 0) - return strdup("0"); - - char * mystring = (char *) malloc(50); - sprintf(mystring, "%"PRIu64, i); - - return mystring; -} diff --git a/src/modules/linsys/sdi_generator.h b/src/modules/linsys/sdi_generator.h deleted file mode 100644 index 66caa7ee0..000000000 --- a/src/modules/linsys/sdi_generator.h +++ /dev/null @@ -1,319 +0,0 @@ -/** - * sdi_generator.h - **/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#ifndef SDI_GENERATOR_H_ -#define SDI_GENERATOR_H_ - -// definitions are only for SD NTSC (mkline funktion for test pattern) -#define VERT_BLANKING 0 -#define MAIN_SET 1 -#define CHROMA_SET 2 -#define BLACK_SET 3 -#define BLACK 4 -#define GREEN 5 - -// defines for SD SDI with blanking -#define ANCILLARY_DATA_SAMPLES 280 -#define FIELD_1 1 -#define FIELD_2 2 -#define VERT_BLANKING 0 -#define ACTIVE_VIDEO 1 - -// Master SDI device -#define SDI_IOC_MAGIC '=' -#define SDI_IOC_TXGETEVENTS _IOR(SDI_IOC_MAGIC, 2, unsigned int) - -// Transmitter event flag bit locations -#define SDI_EVENT_TX_BUFFER_ORDER 0 -#define SDI_EVENT_TX_BUFFER (1 << SDI_EVENT_TX_BUFFER_ORDER) -#define SDI_EVENT_TX_FIFO_ORDER 1 -#define SDI_EVENT_TX_FIFO (1 << SDI_EVENT_TX_FIFO_ORDER) -#define SDI_EVENT_TX_DATA_ORDER 2 -#define SDI_EVENT_TX_DATA (1 << SDI_EVENT_TX_DATA_ORDER) - -// part of the linsys sdiaudio.h - -#define SDIAUDIO_IOC_TXGETCAP _IOR(SDIAUDIO_IOC_MAGIC, 1, unsigned int) -#define SDIAUDIO_IOC_TXGETEVENTS _IOR(SDIAUDIO_IOC_MAGIC, 2, unsigned int) -#define SDIAUDIO_IOC_TXGETBUFLEVEL _IOR(SDIAUDIO_IOC_MAGIC, 3, unsigned int) -#define SDIAUDIO_IOC_TXGETTXD _IOR(SDIAUDIO_IOC_MAGIC, 4, int) - -#define SDIAUDIO_IOC_MAGIC '~' /* This ioctl magic number is currently free. See - * /usr/src/linux/Documentation/ioctl-number.txt */ -/* Transmitter event flag bit locations */ -#define SDIAUDIO_EVENT_TX_BUFFER_ORDER 0 -#define SDIAUDIO_EVENT_TX_BUFFER (1 << SDIAUDIO_EVENT_TX_BUFFER_ORDER) -#define SDIAUDIO_EVENT_TX_FIFO_ORDER 1 -#define SDIAUDIO_EVENT_TX_FIFO (1 << SDIAUDIO_EVENT_TX_FIFO_ORDER) -#define SDIAUDIO_EVENT_TX_DATA_ORDER 2 -#define SDIAUDIO_EVENT_TX_DATA (1 << SDIAUDIO_EVENT_TX_DATA_ORDER) - -// Filehandler for sdi output -static int fh_sdi_video; -static int fh_sdi_audio; - -#define MAX_SAMPLES_PER_LINE (2*2750) -#define MAX_LINES_PER_FRAME 1125 -#define MAX_AUDIO_STREAMS (8) -// max. audio samples per frame -#define MAX_AUDIO_SAMPLES (2002*2) -/** - * 23.98Hz = fix:{2002} - * 24Hz = fix:{2000} - * 25Hz = fix:{1920} - * 29.97Hz = varies:{1601,1602,1602} - * 30Hz = fix:{1600} - **/ - -#define MAX_SDI_HEIGHT 1125 // HD-SDI -#define MAX_SDI_WIDTH 2750 // HD-SDI (FMT_1080p24 has up to 2750) -#define MAX_SDI_FRAMESIZE (MAX_SDI_HEIGHT*MAX_SDI_WIDTH*2) // SDI frame size, (2 Pixels are represented by 4 bytes, yuyv422) -struct source_format { - unsigned int lines_per_frame; - unsigned int active_lines_per_frame; - unsigned int samples_per_line; - unsigned int active_samples_per_line; - unsigned int interlaced; -}; - -struct audio_format { - - mlt_audio_format aformat; // default: mlt_audio_pcm - uint16_t samples; // default 2*1920 - uint16_t sample_rate; // default 48000 - /** - * 0 channels = audio disabled, transmit only - * 2 channels (stereo) - * 4 channels - * 6 channels - * 8 channels - **/ - int channels; // default 2 (stereo) -}; - -/** - * SDI DEVICE FILE SETTINGS AND MODES - **/ -enum sdi_setting_video_e { - - SETTING_BUFFER_NUMBER_VIDEO = 0, SETTING_BUFFER_SIZE_VIDEO = 1, SETTING_CLOCK_SOURCE = 2, SETTING_DATA_MODE = 3, SETTING_FRAME_MODE = 4 -}; -enum sdi_setting_audio_e { - - SETTING_BUFFER_NUMBER_AUDIO = 0, - SETTING_BUFFER_SIZE_AUDIO = 1, - SETTING_SAMPLE_SIZE = 2, - SETTING_CHANNELS = 3, - SETTING_SAMPEL_RATE = 4, - SETTING_NON_AUDIO = 5 -}; - -static int sdi_frame_mode = 0; - -/* Frame mode settings */ -#define SDIVIDEO_CTL_UNLOCKED 0 -#define SDIVIDEO_CTL_SMPTE_125M_486I_59_94HZ 1 -#define SDIVIDEO_CTL_BT_601_576I_50HZ 2 -#define SDIVIDEO_CTL_SMPTE_260M_1035I_60HZ 5 -#define SDIVIDEO_CTL_SMPTE_260M_1035I_59_94HZ 6 -#define SDIVIDEO_CTL_SMPTE_295M_1080I_50HZ 7 -#define SDIVIDEO_CTL_SMPTE_274M_1080I_60HZ 8 -#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_30HZ 9 -#define SDIVIDEO_CTL_SMPTE_274M_1080I_59_94HZ 10 -#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_29_97HZ 11 -#define SDIVIDEO_CTL_SMPTE_274M_1080I_50HZ 12 -#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_25HZ 13 -#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_24HZ 14 -#define SDIVIDEO_CTL_SMPTE_274M_1080PSF_23_98HZ 15 -#define SDIVIDEO_CTL_SMPTE_274M_1080P_30HZ 16 -#define SDIVIDEO_CTL_SMPTE_274M_1080P_29_97HZ 17 -#define SDIVIDEO_CTL_SMPTE_274M_1080P_25HZ 18 -#define SDIVIDEO_CTL_SMPTE_274M_1080P_24HZ 19 -#define SDIVIDEO_CTL_SMPTE_274M_1080P_23_98HZ 20 -#define SDIVIDEO_CTL_SMPTE_296M_720P_60HZ 21 -#define SDIVIDEO_CTL_SMPTE_296M_720P_59_94HZ 22 -#define SDIVIDEO_CTL_SMPTE_296M_720P_50HZ 23 -#define SDIVIDEO_CTL_SMPTE_296M_720P_30HZ 24 -#define SDIVIDEO_CTL_SMPTE_296M_720P_29_97HZ 25 -#define SDIVIDEO_CTL_SMPTE_296M_720P_25HZ 26 -#define SDIVIDEO_CTL_SMPTE_296M_720P_24HZ 27 -#define SDIVIDEO_CTL_SMPTE_296M_720P_23_98HZ 28 - -/* Audio sample size */ -#define SDIAUDIO_CTL_AUDSAMP_SZ_16 16 /* 16 bit */ -#define SDIAUDIO_CTL_AUDSAMP_SZ_24 24 /* 24 bit */ -#define SDIAUDIO_CTL_AUDSAMP_SZ_32 32 /* 32 bit */ - -/* Audio channel enable */ -#define SDIAUDIO_CTL_AUDCH_EN_0 0 /* 0 channel/disable audio */ -#define SDIAUDIO_CTL_AUDCH_EN_2 2 /* 2 channel */ -#define SDIAUDIO_CTL_AUDCH_EN_4 4 /* 4 channel */ -#define SDIAUDIO_CTL_AUDCH_EN_6 6 /* 6 channel */ -#define SDIAUDIO_CTL_AUDCH_EN_8 8 /* 8 channel */ - -static char * itoa(uint64_t i); -static ssize_t util_read(const char *name, char *buf, size_t count); -static ssize_t util_write(const char *name, const char *buf, size_t count); -static int setSDIVideoProperties(enum sdi_setting_video_e setting, char * value, char * device); -static int setSDIAudioProperties(enum sdi_setting_audio_e setting, char * value, char * device); - -// HD -static const struct source_format FMT_1080i60 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2200, - .active_samples_per_line = 2*1920, .interlaced = 1 }; - -static const struct source_format FMT_1080i5994 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2200, - .active_samples_per_line = 2*1920, .interlaced = 1 }; - -static const struct source_format FMT_1080i50 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2640, - .active_samples_per_line = 2*1920, .interlaced = 1 }; - -static const struct source_format FMT_1080p30 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2200, - .active_samples_per_line = 2*1920, .interlaced = 0 }; - -static const struct source_format FMT_1080p2997 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2200, - .active_samples_per_line = 2*1920, .interlaced = 0 }; - -static const struct source_format FMT_1080p25 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2640, - .active_samples_per_line = 2*1920, .interlaced = 0 }; - -static const struct source_format FMT_1080p24 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2750, - .active_samples_per_line = 2*1920, .interlaced = 0 }; - -static const struct source_format FMT_1080p2398 = { .lines_per_frame = 1125, .active_lines_per_frame = 1080, .samples_per_line = 2*2750, - .active_samples_per_line = 2*1920, .interlaced = 0 }; - -static const struct source_format FMT_720p60 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*1650, - .active_samples_per_line = 2*1280, .interlaced = 0 }; - -static const struct source_format FMT_720p5994 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*1650, - .active_samples_per_line = 2*1280, .interlaced = 0 }; - -static const struct source_format FMT_720p50 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*1980, - .active_samples_per_line = 2*1280, .interlaced = 0 }; - -static const struct source_format FMT_720p30 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*3300, - .active_samples_per_line = 2*1280, .interlaced = 0 }; - -static const struct source_format FMT_720p2997 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*3300, - .active_samples_per_line = 2*1280, .interlaced = 0 }; - -static const struct source_format FMT_720p25 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*3960, - .active_samples_per_line = 2*1280, .interlaced = 0 }; - -static const struct source_format FMT_720p24 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*4125, - .active_samples_per_line = 2*1280, .interlaced = 0 }; - -static const struct source_format FMT_720p2398 = { .lines_per_frame = 750, .active_lines_per_frame = 720, .samples_per_line = 2*4125, - .active_samples_per_line = 2*1280, .interlaced = 0 }; - -// SD PAL -static const struct source_format FMT_576i50 = { .lines_per_frame = 625, .active_lines_per_frame = 576, .samples_per_line = 2*864 /*1728*/, - .active_samples_per_line = 2*720 /* 720xY, 360xCb, 360xCr */, .interlaced = 1 }; - -// SD NTSC; 486 video lines -static const struct source_format FMT_486i5994 = { .lines_per_frame = 525, .active_lines_per_frame = 486, .samples_per_line = 2*858 /*1716*/, - .active_samples_per_line = 2*720 /* 720xY, 360xCb, 360xCr */, .interlaced = 1 }; - -// SD NTSC; 480 video lines, 6 lines opt. video data -/** - * sames as FMT_486i5994 but the first 6 lines will be filled with SDI-BLACK - * or can be used for opt. video data (s.SMPTE) - */ -static const struct source_format FMT_480i5994 = { .lines_per_frame = 525, .active_lines_per_frame = 486, .samples_per_line = 2*858 /*1716*/, - .active_samples_per_line = 2*720 /* 720xY, 360xCb, 360xCr */, .interlaced = 1 }; - -struct trs { - unsigned short int sav; - unsigned short int eav; -}; - -static const struct trs FIELD_1_ACTIVE = { .sav = 0x200, .eav = 0x274 }; -static const struct trs FIELD_1_VERT_BLANKING = { .sav = 0x2ac, .eav = 0x2d8 }; -static const struct trs FIELD_2_ACTIVE = { .sav = 0x31c, .eav = 0x368 }; -static const struct trs FIELD_2_VERT_BLANKING = { .sav = 0x3b0, .eav = 0x3c4 }; - -struct line_info { - const struct source_format *fmt; - unsigned int ln; - const struct trs *xyz; - uint8_t blanking; -}; - -struct SDI_atr { - int status; - int *fh; - uint8_t *data; - size_t framesize; -} SDI_atr; - -// 192bit for AESChannelStatusBits -uint8_t AESChannelStatusBitArray[192]; // beta array -//uint8_t AESChannelStatusBitArray[24]; // TODO better way for 24x8bit !!! - -// buffer for one sdi line -uint16_t * line_buffer; -// counter for active line number -uint16_t active_video_line; -// buffer for sdi frame size -uint64_t sdi_frame_size; -// buffer for the complete SDI frame -uint8_t * data; - -static char * device_file_video; -static char * device_file_audio; -static struct line_info info; -static uint8_t *(*pack)(uint8_t *outbuf, unsigned short int *inbuf, size_t count); -static size_t elements; -static unsigned int samples; - -// functions -static int sdi_init(char *device_video, char *device_audio, uint8_t blanking, mlt_profile myProfile, const struct audio_format * audio_format); - -static int sdimaster_close(); - -static int sdi_playout(uint8_t *vBuffer, int16_t aBuffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES], const struct audio_format * audio_format, int audio_streams, - int my_DBN); - -static int mkline(unsigned short int *buf, const struct line_info *info, unsigned int pattern); - -static inline int create_HD_SDI_Line(uint16_t *buf, const struct line_info *info, uint16_t active_video_line, unsigned int active, uint8_t *video_buffer); -static inline int create_SD_SDI_Line(uint16_t *buf, const struct line_info *info, int field, int active, uint8_t *video_buffer, - int16_t audio_buffer[MAX_AUDIO_STREAMS][MAX_AUDIO_SAMPLES], int linenumber_sdiframe, int active_video_line, int my_DBN, int16_t AudioGroupCounter, - int16_t AudioGroups2Write, int audio_streams); - -static int writeANC(uint16_t *p, int linenumber_sdiframe, uint16_t DID, int my_DBN, int16_t *audio_buffer_A, int16_t *audio_buffer_B, - int16_t AudioDataPacketCounter, int16_t AudioGroups2Write); -static uint16_t checker(uint16_t *DID_pointer); - -static uint8_t getZBit(int sample_number); -static uint8_t getChannelStatusBit(uint16_t sample_number, uint8_t ch); -static int16_t getNumberOfAudioGroups2Write(int linenuber); - -static uint8_t getDBN(int my_DBN); - -static inline uint8_t *pack8(uint8_t *outbuf, uint16_t *inbuf, size_t count); // alias 'pack_uyvy()' -static inline uint8_t *pack10(uint8_t *outbuf, uint16_t *inbuf, size_t count); -static inline uint8_t *pack_v210(uint8_t *outbuf, uint16_t *inbuf, size_t count); - -static int pack_AES_subframe(uint16_t *p, int8_t c, int8_t z, int8_t ch, int16_t *audio_sample); - -#endif /* SDI_GENERATOR_H_ */ From b5adba0f1648166f32e328e66bbe65d1ed89c4c1 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 8 Feb 2021 22:21:35 -0600 Subject: [PATCH 027/122] Remove deprecated swfdec module --- docs/install.txt | 2 - src/modules/core/loader.dict | 2 +- src/modules/swfdec/Makefile | 39 ---- src/modules/swfdec/configure | 33 --- src/modules/swfdec/producer_swfdec.c | 283 ------------------------- src/modules/swfdec/producer_swfdec.yml | 11 - 6 files changed, 1 insertion(+), 369 deletions(-) delete mode 100644 src/modules/swfdec/Makefile delete mode 100755 src/modules/swfdec/configure delete mode 100644 src/modules/swfdec/producer_swfdec.c delete mode 100644 src/modules/swfdec/producer_swfdec.yml diff --git a/docs/install.txt b/docs/install.txt index fa3562016..dc97b3a99 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -42,7 +42,6 @@ Last Revision: 2013-09-07 * rtaudio - audio consumer based on !RtAudio project code * sdl - SDL dependent services * sox - !SoX dependent audio filters - * swfdec - Swfdec dependent producer for Flash files * videostab - video stabilization filters (*) * vmfx - services contributed by (defunct) Visual Media FX * vorbis - vorbis dependenent services @@ -78,7 +77,6 @@ Last Revision: 2013-09-07 | resample | [[http://www.mega-nerd.com/SRC][libsamplerate]] 0.15 or later | | sdl | [[http://www.libsdl.org][SDL]] 1.2 or later | | sox | [[http://sox.sourceforge.net][SoX]] 13 or later | - | swfdec | [[http://github.com/mltframework/swfdec][swfdec]] 0.8 or later | | vorbis | [[http://www.vorbis.com][libvorbis]] 1.0.1 or later | | xml | [[http://www.xmlsoft.org][libxml2]] 2.5 or later | diff --git a/src/modules/core/loader.dict b/src/modules/core/loader.dict index 977a700ab..6c14f77ad 100644 --- a/src/modules/core/loader.dict +++ b/src/modules/core/loader.dict @@ -40,7 +40,7 @@ plain:https://*=webvfx:plain: *.qml=webvfx:plain: *.story=xml *.svg=qimage,pixbuf -*.swf=avformat,swfdec +*.swf=avformat *.tga=qimage,pixbuf *.tif=qimage,pixbuf *.tiff=qimage,pixbuf diff --git a/src/modules/swfdec/Makefile b/src/modules/swfdec/Makefile deleted file mode 100644 index ae18e44d4..000000000 --- a/src/modules/swfdec/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt -lm - -include ../../../config.mak -include config.mak - -TARGET = ../libmltswfdec$(LIBSUF) - -OBJS = producer_swfdec.o - -ifeq ($(targetos), MinGW) -LDFLAGS += -Wl,enable-auto-import -lz -endif - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" - install -d "$(DESTDIR)$(mltdatadir)/swfdec" - install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/swfdec" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/swfdec/configure b/src/modules/swfdec/configure deleted file mode 100755 index cffd6df9e..000000000 --- a/src/modules/swfdec/configure +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh - -if [ "$help" != "1" ] -then - pkg-config swfdec-0.9 2> /dev/null - disable_swfdec=$? - echo > config.mak - if [ "$disable_swfdec" = "0" ] - then - echo "CFLAGS += $(pkg-config --cflags swfdec-0.9)" >> config.mak - echo "LDFLAGS += $(pkg-config --libs swfdec-0.9)" >> config.mak - else - pkg-config swfdec-0.8 2> /dev/null - disable_swfdec=$? - if [ "$disable_swfdec" = "0" ] - then - echo "CFLAGS += $(pkg-config --cflags swfdec-0.8)" >> config.mak - echo "LDFLAGS += $(pkg-config --libs swfdec-0.8)" >> config.mak - else - pkg-config swfdec-0.7 2> /dev/null - disable_swfdec=$? - if [ "$disable_swfdec" = "0" ] - then - echo "CFLAGS += $(pkg-config --cflags swfdec-0.7)" >> config.mak - echo "LDFLAGS += $(pkg-config --libs swfdec-0.7)" >> config.mak - else - echo "- swfdec not found: disabling" - touch ../disable-swfdec - exit 0 - fi - fi - fi -fi diff --git a/src/modules/swfdec/producer_swfdec.c b/src/modules/swfdec/producer_swfdec.c deleted file mode 100644 index 877dc4555..000000000 --- a/src/modules/swfdec/producer_swfdec.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * producer_swfdec.c -- swfdec producer for Flash files - * Copyright (C) 2010 Dan Dennedy - * - * swfdec library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * swfdec library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with swfdec library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include -#include -#include -#include -#include - -typedef struct -{ - struct mlt_producer_s parent; - SwfdecPlayer *player; - SwfdecURL *url; - cairo_surface_t *surface; - cairo_t *cairo; - mlt_position last_position; - guint width; - guint height; -} *producer_swfdec; - -void swfdec_open( producer_swfdec swfdec, mlt_profile profile ) -{ - mlt_properties properties = MLT_PRODUCER_PROPERTIES( &swfdec->parent ); - - // Setup the swfdec player - swfdec->player = swfdec_player_new( NULL ); - if ( mlt_properties_get( properties, "variables") ) - swfdec_player_set_variables( swfdec->player, mlt_properties_get( properties, "variables" ) ); - swfdec_player_set_url( swfdec->player, swfdec->url ); - swfdec_player_set_maximum_runtime( swfdec->player, 10000 ); - - // Setup size - swfdec_player_get_default_size( swfdec->player, &swfdec->width, &swfdec->height ); - if ( swfdec->width == 0 || swfdec->height == 0 ) - { - swfdec_player_set_size( swfdec->player, profile->width, profile->height ); - swfdec->width = profile->width; - swfdec->height = profile->height; - } - - // Setup scaling - double scale = 1.0; - if ( swfdec->width > 2 * swfdec->height ) - scale = 0.5 * profile->width / swfdec->height; - else if ( swfdec->height > 2 * swfdec->width ) - scale = 0.5 * profile->height / swfdec->width; - else - scale = (double) profile->width / MAX( swfdec->width, swfdec->height ); - swfdec->width = ceil( scale * swfdec->width ); - swfdec->height = ceil( scale * swfdec->height ); - - // Compute the centering translation - double x = swfdec->width > profile->width ? (swfdec->width - profile->width) / 2 : 0; - double y = swfdec->height > profile->height ? (swfdec->height - profile->height) / 2 : 0; - - // Setup cairo - swfdec->surface = cairo_image_surface_create( CAIRO_FORMAT_ARGB32, MIN(profile->width, swfdec->width), MIN(profile->height, swfdec->height) ); - swfdec->cairo = cairo_create( swfdec->surface ); - cairo_translate( swfdec->cairo, -x, -y ); - cairo_scale( swfdec->cairo, scale, scale ); -} - -void swfdec_close( producer_swfdec swfdec ) -{ - if ( swfdec->cairo ) - cairo_destroy( swfdec->cairo ); - swfdec->cairo = NULL; - if ( swfdec->player ) - g_object_unref( swfdec->player ); - swfdec->player = NULL; - if ( swfdec->surface ) - cairo_surface_destroy( swfdec->surface ); - swfdec->surface = NULL; -} - -// Cairo uses 32 bit native endian ARGB -static void bgra_to_rgba( uint8_t *src, uint8_t* dst, int width, int height ) -{ - int n = width * height + 1; - - while ( --n ) - { - *dst++ = src[2]; - *dst++ = src[1]; - *dst++ = src[0]; - *dst++ = src[3]; - src += 4; - } -} - -static int get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) -{ - producer_swfdec swfdec = mlt_frame_pop_service( frame ); - mlt_service service = MLT_PRODUCER_SERVICE( &swfdec->parent ); - mlt_profile profile = mlt_service_profile( service ); - - mlt_service_lock( service ); - - if ( !swfdec->player ) - swfdec_open( swfdec, profile ); - - // Set width and height - *width = swfdec->width; - *height = swfdec->height; - *format = mlt_image_rgb24a; - int size = mlt_image_format_size( *format, *width, *height, NULL ); - - *buffer = mlt_pool_alloc( size ); - mlt_frame_set_image( frame, *buffer, size, mlt_pool_release ); - - // Seek - mlt_position pos = mlt_frame_original_position( frame ); - if ( pos > swfdec->last_position ) - { - gulong msec = 1000UL * ( pos - swfdec->last_position ) * profile->frame_rate_den / profile->frame_rate_num; - while ( msec > 0 ) - msec -= swfdec_player_advance( swfdec->player, msec ); - } - else if ( pos < swfdec->last_position ) - { - swfdec_close( swfdec ); - swfdec_open( swfdec, mlt_service_profile( service ) ); - gulong msec = 1000UL * pos * profile->frame_rate_den / profile->frame_rate_num; - while ( msec > 0 ) - msec -= swfdec_player_advance( swfdec->player, msec ); - } - swfdec->last_position = pos; - - // Render - cairo_save( swfdec->cairo ); - //cairo_set_source_rgba( swfdec->cairo, r, g, b, a ); - cairo_set_operator( swfdec->cairo, CAIRO_OPERATOR_CLEAR ); - cairo_paint( swfdec->cairo ); - cairo_restore( swfdec->cairo ); - swfdec_player_render( swfdec->player, swfdec->cairo ); - - // Get image from surface - uint8_t *image = cairo_image_surface_get_data( swfdec->surface ); - - mlt_service_unlock( service ); - - // Convert to RGBA - bgra_to_rgba( image, *buffer, swfdec->width, swfdec->height ); - - return 0; -} - -static int get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Access the private data - producer_swfdec swfdec = producer->child; - - // Create an empty frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - // Get the frames properties - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Update other info on the frame - mlt_properties_set_int( properties, "test_image", 0 ); - mlt_properties_set_int( properties, "width", swfdec->width ); - mlt_properties_set_int( properties, "height", swfdec->height ); - mlt_properties_set_int( properties, "progressive", 1 ); - mlt_properties_set_double( properties, "aspect_ratio", 1.0 ); - - // Push the get_image method on to the stack - mlt_frame_push_service( *frame, swfdec ); - mlt_frame_push_get_image( *frame, get_image ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer parent ) -{ - // Obtain swfdec - producer_swfdec swfdec = parent->child; - - // Close the file - swfdec_close( swfdec ); - if ( swfdec->url ) - swfdec_url_free( swfdec->url ); - - // Close the parent - parent->close = NULL; - mlt_producer_close( parent ); - - // Free the memory - free( swfdec ); -} - -mlt_producer producer_swfdec_init( mlt_profile profile, mlt_service_type type, const char *id, char *filename ) -{ - if ( !filename ) return NULL; - producer_swfdec swfdec = calloc( 1, sizeof( *swfdec ) ); - mlt_producer producer = NULL; - - if ( swfdec && mlt_producer_init( &swfdec->parent, swfdec ) == 0 ) - { - // Initialize swfdec and try to open the file - swfdec->url = swfdec_url_new_from_input( filename ); - if ( swfdec->url ) - { - // Set the return value - producer = &swfdec->parent; - - // Set the resource property (required for all producers) - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - mlt_properties_set( properties, "resource", filename ); - - // Set the callbacks - producer->close = (mlt_destructor) producer_close; - producer->get_frame = get_frame; - - // Set the meta media attributes - swfdec->width = profile->width; - swfdec->height = profile->height; - mlt_properties_set_int( properties, "meta.media.nb_streams", 1 ); - mlt_properties_set( properties, "meta.media.0.stream.type", "video" ); - mlt_properties_set( properties, "meta.media.0.codec.name", "swf" ); - mlt_properties_set( properties, "meta.media.0.codec.long_name", "Adobe Flash" ); - mlt_properties_set( properties, "meta.media.0.codec.pix_fmt", "bgra" ); - mlt_properties_set_int( properties, "meta.media.width", profile->width ); - mlt_properties_set_int( properties, "meta.media.height", profile->height ); - mlt_properties_set_double( properties, "meta.media.sample_aspect_num", 1.0 ); - mlt_properties_set_double( properties, "meta.media.sample_aspect_den", 1.0 ); - mlt_properties_set_int( properties, "meta.media.frame_rate_num", profile->frame_rate_num ); - mlt_properties_set_int( properties, "meta.media.frame_rate_den", profile->frame_rate_den ); - mlt_properties_set_int( properties, "meta.media.progressive", 1 ); - } - else - { - g_object_unref( swfdec->player ); - mlt_producer_close( &swfdec->parent ); - free( swfdec ); - } - } - else - { - free( swfdec ); - } - - return producer; -} - -static mlt_properties metadata( mlt_service_type type, const char *id, void *data ) -{ - char file[ PATH_MAX ]; - snprintf( file, PATH_MAX, "%s/swfdec/%s", mlt_environment( "MLT_DATA" ), (char*) data ); - return mlt_properties_parse_yaml( file ); -} - -MLT_REPOSITORY -{ - swfdec_init(); - MLT_REGISTER( mlt_service_producer_type, "swfdec", producer_swfdec_init ); - MLT_REGISTER_METADATA( mlt_service_producer_type, "swfdec", metadata, "producer_swfdec.yml" ); -} diff --git a/src/modules/swfdec/producer_swfdec.yml b/src/modules/swfdec/producer_swfdec.yml deleted file mode 100644 index 987aadc43..000000000 --- a/src/modules/swfdec/producer_swfdec.yml +++ /dev/null @@ -1,11 +0,0 @@ -schema_version: 0.1 -type: producer -identifier: swfdec -title: Flash -version: 1 -copyright: Dan Dennedy -creator: Dan Dennedy -license: LGPLv2.1 -language: en -tags: - - Video From 77ac0d7db924426debf3cab6eb56b8325ca91f46 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 8 Feb 2021 22:27:56 -0600 Subject: [PATCH 028/122] Remove deprecated videostab module --- docs/install.txt | 2 +- src/modules/videostab/Makefile | 44 - src/modules/videostab/factory.c | 44 - src/modules/videostab/filter_videostab.c | 224 ---- src/modules/videostab/filter_videostab.yml | 44 - src/modules/videostab/filter_videostab2.c | 304 ------ src/modules/videostab/filter_videostab2.yml | 220 ---- src/modules/videostab/gpl | 0 src/modules/videostab/stab/estimate.c | 142 --- src/modules/videostab/stab/estimate.h | 30 - src/modules/videostab/stab/klt/base.h | 38 - src/modules/videostab/stab/klt/convolve.c | 279 ----- src/modules/videostab/stab/klt/convolve.h | 32 - src/modules/videostab/stab/klt/error.c | 55 - src/modules/videostab/stab/klt/error.h | 15 - src/modules/videostab/stab/klt/klt.c | 342 ------- src/modules/videostab/stab/klt/klt.h | 143 --- src/modules/videostab/stab/klt/klt_util.c | 52 - src/modules/videostab/stab/klt/klt_util.h | 28 - src/modules/videostab/stab/klt/pyramid.c | 139 --- src/modules/videostab/stab/klt/pyramid.h | 32 - .../videostab/stab/klt/selectGoodFeatures.c | 430 -------- .../videostab/stab/klt/trackFeatures.c | 549 ---------- src/modules/videostab/stab/main.c | 191 ---- src/modules/videostab/stab/resample.c | 103 -- src/modules/videostab/stab/resample.h | 20 - src/modules/videostab/stab/utils.c | 133 --- src/modules/videostab/stab/utils.h | 34 - src/modules/videostab/stab/vector.c | 126 --- src/modules/videostab/stab/vector.h | 27 - src/modules/videostab/stabilize.c | 954 ------------------ src/modules/videostab/stabilize.h | 186 ---- src/modules/videostab/tlist.c | 57 -- src/modules/videostab/tlist.h | 18 - src/modules/videostab/transform.c | 315 ------ src/modules/videostab/transform.h | 124 --- src/modules/videostab/transform_image.c | 714 ------------- src/modules/videostab/transform_image.h | 125 --- src/modules/xml/consumer_xml.yml | 2 +- 39 files changed, 2 insertions(+), 6315 deletions(-) delete mode 100644 src/modules/videostab/Makefile delete mode 100644 src/modules/videostab/factory.c delete mode 100644 src/modules/videostab/filter_videostab.c delete mode 100644 src/modules/videostab/filter_videostab.yml delete mode 100644 src/modules/videostab/filter_videostab2.c delete mode 100644 src/modules/videostab/filter_videostab2.yml delete mode 100644 src/modules/videostab/gpl delete mode 100644 src/modules/videostab/stab/estimate.c delete mode 100644 src/modules/videostab/stab/estimate.h delete mode 100644 src/modules/videostab/stab/klt/base.h delete mode 100644 src/modules/videostab/stab/klt/convolve.c delete mode 100644 src/modules/videostab/stab/klt/convolve.h delete mode 100644 src/modules/videostab/stab/klt/error.c delete mode 100644 src/modules/videostab/stab/klt/error.h delete mode 100644 src/modules/videostab/stab/klt/klt.c delete mode 100644 src/modules/videostab/stab/klt/klt.h delete mode 100644 src/modules/videostab/stab/klt/klt_util.c delete mode 100644 src/modules/videostab/stab/klt/klt_util.h delete mode 100644 src/modules/videostab/stab/klt/pyramid.c delete mode 100644 src/modules/videostab/stab/klt/pyramid.h delete mode 100644 src/modules/videostab/stab/klt/selectGoodFeatures.c delete mode 100644 src/modules/videostab/stab/klt/trackFeatures.c delete mode 100644 src/modules/videostab/stab/main.c delete mode 100644 src/modules/videostab/stab/resample.c delete mode 100644 src/modules/videostab/stab/resample.h delete mode 100644 src/modules/videostab/stab/utils.c delete mode 100644 src/modules/videostab/stab/utils.h delete mode 100644 src/modules/videostab/stab/vector.c delete mode 100644 src/modules/videostab/stab/vector.h delete mode 100644 src/modules/videostab/stabilize.c delete mode 100644 src/modules/videostab/stabilize.h delete mode 100644 src/modules/videostab/tlist.c delete mode 100644 src/modules/videostab/tlist.h delete mode 100644 src/modules/videostab/transform.c delete mode 100644 src/modules/videostab/transform.h delete mode 100644 src/modules/videostab/transform_image.c delete mode 100644 src/modules/videostab/transform_image.h diff --git a/docs/install.txt b/docs/install.txt index dc97b3a99..a5f4cec7b 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -42,7 +42,7 @@ Last Revision: 2013-09-07 * rtaudio - audio consumer based on !RtAudio project code * sdl - SDL dependent services * sox - !SoX dependent audio filters - * videostab - video stabilization filters (*) + * vid.stab - video stabilization filters (*) * vmfx - services contributed by (defunct) Visual Media FX * vorbis - vorbis dependenent services * xine - Xine-derived sources (*) diff --git a/src/modules/videostab/Makefile b/src/modules/videostab/Makefile deleted file mode 100644 index c9d6eedfb..000000000 --- a/src/modules/videostab/Makefile +++ /dev/null @@ -1,44 +0,0 @@ -include ../../../config.mak - -CFLAGS += -I../.. -ifdef SSE2_FLAGS -CFLAGS += -msse2 -endif - -LDFLAGS += -L../../framework -lmlt -lm - - -TARGET = ../libmltvideostab$(LIBSUF) - -OBJS = factory.o \ - filter_videostab.o filter_videostab2.o \ - stabilize.o transform.o transform_image.o tlist.o\ - stab/klt/convolve.o stab/klt/klt.o stab/klt/pyramid.o stab/klt/trackFeatures.o \ - stab/klt/error.o stab/klt/klt_util.o stab/klt/selectGoodFeatures.o \ - stab/estimate.o stab/resample.o stab/utils.o stab/vector.o - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" - install -d $(DESTDIR)$(mltdatadir)/videostab - install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/videostab" - - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/videostab/factory.c b/src/modules/videostab/factory.c deleted file mode 100644 index 6cd47c7c5..000000000 --- a/src/modules/videostab/factory.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (c) 2011 Marco Gittler - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -extern mlt_filter filter_videostab_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_videostab2_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -static mlt_properties videostab_metadata( mlt_service_type type, const char *id, void *data ) -{ - char file[ PATH_MAX ]; - snprintf( file, PATH_MAX, "%s/videostab/filter_%s.yml", mlt_environment( "MLT_DATA" ), id ); - return mlt_properties_parse_yaml( file ); -} - -MLT_REPOSITORY -{ - MLT_REGISTER( mlt_service_filter_type, "videostab", filter_videostab_init ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "videostab", videostab_metadata, NULL ); - MLT_REGISTER( mlt_service_filter_type, "videostab2", filter_videostab2_init ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "videostab2", videostab_metadata, NULL ); - -} - - - diff --git a/src/modules/videostab/filter_videostab.c b/src/modules/videostab/filter_videostab.c deleted file mode 100644 index 4e71f200f..000000000 --- a/src/modules/videostab/filter_videostab.c +++ /dev/null @@ -1,224 +0,0 @@ -/* - * filter_imagestab.c -- video stabilization with code from http://vstab.sourceforge.net/ - * Copyright (c) 2011 Marco Gittler - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "stab/vector.h" -#include "stab/utils.h" -#include "stab/estimate.h" -#include "stab/resample.h" - - -typedef struct { - mlt_filter parent; - int initialized; - int* lanc_kernels; - es_ctx *es; - vc *pos_i; - vc *pos_h; - vc *pos_y; - rs_ctx *rs; -} *videostab; - -static void serialize_vectors( videostab self, mlt_position length ) -{ - mlt_geometry g = mlt_geometry_init(); - - if ( g ) - { - struct mlt_geometry_item_s item; - int i; - - // Initialize geometry item - item.key = item.f[0] = item.f[1] = 1; - item.f[2] = item.f[3] = item.f[4] = 0; - - for ( i = 0; i < length; i++ ) - { - // Set the geometry item - item.frame = i; - item.x = self->pos_h[i].x; - item.y = self->pos_h[i].y; - - // Add the geometry item - mlt_geometry_insert( g, &item ); - } - - // Put the analysis results in a property - mlt_geometry_set_length( g, length ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( self->parent ), "vectors", g, 0, - (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise ); - } -} - -static void deserialize_vectors( videostab self, char *vectors, mlt_position length ) -{ - mlt_geometry g = mlt_geometry_init(); - - // Parse the property as a geometry - if ( g && !mlt_geometry_parse( g, vectors, length, -1, -1 ) ) - { - struct mlt_geometry_item_s item; - int i; - - // Copy the geometry items to a vc array for interp() - for ( i = 0; i < length; i++ ) - { - mlt_geometry_fetch( g, &item, i ); - self->pos_h[i].x = item.x; - self->pos_h[i].y = item.y; - } - } - else - { - mlt_log_warning( MLT_FILTER_SERVICE(self->parent), "failed to parse vectors\n" ); - } - - // We are done with this mlt_geometry - if ( g ) mlt_geometry_close( g ); -} - -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_filter filter = mlt_frame_pop_service( frame ); - mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter)); - - // Disable consumer scaling - if (profile && profile->width && profile->height) { - *width = profile->width; - *height = profile->height; - } - - *format = mlt_image_rgb24; - mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "consumer_deinterlace", 1 ); - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - if ( !error && *image ) - { - videostab self = filter->child; - mlt_position length = mlt_filter_get_length2( filter, frame ); - int h = *height; - int w = *width; - - // Service locks are for concurrency control - mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); - if ( !self->initialized ) - { - // Initialize our context - self->initialized = 1; - self->es = es_init( w, h ); - self->pos_i = (vc*) malloc( length * sizeof(vc) ); - self->pos_h = (vc*) malloc( length * sizeof(vc) ); - self->pos_y = (vc*) malloc( h * sizeof(vc) ); - self->rs = rs_init( w, h ); - } - char *vectors = mlt_properties_get( MLT_FILTER_PROPERTIES(filter), "vectors" ); - if ( !vectors ) - { - // Analyse - int pos = (int) mlt_filter_get_position( filter, frame ); - self->pos_i[pos] = vc_add( pos == 0 ? vc_zero() : self->pos_i[pos - 1], es_estimate( self->es, *image ) ); - - // On last frame - if ( pos == length - 1 ) - { - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE(filter) ); - double fps = mlt_profile_fps( profile ); - - // Filter and store the results - hipass( self->pos_i, self->pos_h, length, fps ); - serialize_vectors( self, length ); - } - } else { - // Apply - if ( self->initialized != 2 ) - { - // Load analysis results from property - self->initialized = 2; - deserialize_vectors( self, vectors, length ); - } - if ( self->initialized == 2 ) - { - // Stabilize - float shutter_angle = mlt_properties_get_double( MLT_FRAME_PROPERTIES(frame) , "shutterangle" ); - float pos = mlt_filter_get_position( filter, frame ); - int i; - - for (i = 0; i < h; i ++) - self->pos_y[i] = interp( self->lanc_kernels,self->pos_h, length, pos + (i - h / 2.0) * shutter_angle / (h * 360.0) ); - rs_resample( self->lanc_kernels,self->rs, *image, self->pos_y ); - } - } - mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); - } - return error; -} - -static mlt_frame filter_process( mlt_filter filter, mlt_frame frame ) -{ - mlt_frame_push_service( frame, filter ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -void filter_close( mlt_filter parent ) -{ - videostab self = parent->child; - if ( self->es ) es_free( self->es ); - free( self->pos_i ); - free( self->pos_h ); - free( self->pos_y ); - if ( self->rs ) rs_free( self->rs ); - if ( self->lanc_kernels) free_lanc_kernels(self->lanc_kernels); - free( self ); - parent->close = NULL; - parent->child = NULL; -} - -mlt_filter filter_videostab_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - videostab self = calloc( 1, sizeof(*self) ); - if ( self ) - { - mlt_filter parent = mlt_filter_new(); - if ( !parent ) - { - free( self ); - return NULL; - } - parent->child = self; - parent->close = filter_close; - parent->process = filter_process; - self->parent = parent; - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "shutterangle", "0" ); // 0 - 180 , default 0 - self->lanc_kernels=prepare_lanc_kernels(); - return parent; - } - return NULL; -} diff --git a/src/modules/videostab/filter_videostab.yml b/src/modules/videostab/filter_videostab.yml deleted file mode 100644 index be309cee0..000000000 --- a/src/modules/videostab/filter_videostab.yml +++ /dev/null @@ -1,44 +0,0 @@ -schema_version: 0.1 -type: filter -identifier: videostab -title: Videostab (*deprecated*) -copyright: Copyright (C) 2011 Marco Gittler -creator: Marco Gittler < -contributor: - - Dan Dennedy -version: 0.1 -license: GPL -language: en -url: http://vstab.sourceforge.net/ -creator: Marco Gittler -tags: - - Video -description: Stabilize Video (for wiggly video) -notes: > - This filter is deprecated and will eventually be removed; use the vidstab - filter instead. - This filter requires two passes. The first pass performs analysis and stores - the result in the vectors property. The second pass applies the vectors to - the image. - To use with melt, use 'melt ... -consumer xml:output.mlt all=1' for the - first pass. For the second pass, use output.mlt as the input. - -parameters: - - identifier: shutterangle - title: Shutterangle - type: integer - description: Angle that Images could be maximum rotated - readonly: no - required: no - minimum: 0 - maximum: 180 - default: 0 - mutable: yes - widget: spinner - - identifier: vectors - title: Vectors - type: geometry - description: > - A set of X/Y coordinates by which to adjust the image. - When this is not supplied, the filter computes the vectors and stores - them in this property when the last frame has been processed. diff --git a/src/modules/videostab/filter_videostab2.c b/src/modules/videostab/filter_videostab2.c deleted file mode 100644 index c6527291d..000000000 --- a/src/modules/videostab/filter_videostab2.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * filter_imagestab.c -- video stabilization with code from http://vstab.sourceforge.net/ - * Copyright (c) 2011 Marco Gittler - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "stabilize.h" -#include "transform_image.h" - -typedef struct { - StabData* stab; - TransformData* trans; - int initialized; - void* parent; -} videostab2_data; - -static void serialize_vectors( videostab2_data* self, mlt_position length ) -{ - mlt_geometry g = mlt_geometry_init(); - if ( g ) - { - struct mlt_geometry_item_s item; - mlt_position i; - - // Initialize geometry item - item.key = item.f[0] = item.f[1] = item.f[2] = item.f[3] = 1; - item.f[4] = 0; - - tlist* transform_data =self->stab->transs; - for ( i = 0; i < length; i++ ) - { - // Set the geometry item - item.frame = i; - if (transform_data){ - if ( transform_data->data){ - Transform* t=transform_data->data; - item.x=t->x; - item.y=t->y; - item.w=t->alpha; - item.h=t->zoom; - transform_data=transform_data->next; - } - } - // Add the geometry item - mlt_geometry_insert( g, &item ); - } - - // Put the analysis results in a property - mlt_geometry_set_length( g, length ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( (mlt_filter) self->parent ), "vectors", g, 0, - (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise ); - } -} -// scale zoom implements the factor that the vetcors must be scaled since the vector is calculated for real with, now we need it for (scaled)width -Transform* deserialize_vectors( char *vectors, mlt_position length ,float scale_zoom ) -{ - mlt_geometry g = mlt_geometry_init(); - Transform* tx=NULL; - // Parse the property as a geometry - if ( g && !mlt_geometry_parse( g, vectors, length, -1, -1 ) ) - { - struct mlt_geometry_item_s item; - int i; - tx=calloc(1,sizeof(Transform)*length); - // Copy the geometry items to a vc array for interp() - for ( i = 0; i < length; i++ ) - { - mlt_geometry_fetch( g, &item, i ); - Transform t; - t.x=scale_zoom*item.x; - t.y=scale_zoom*item.y; - t.alpha=item.w; - t.zoom=scale_zoom*item.h; - t.extra=0; - tx[i]=t; - } - - } - else - { - //mlt_log_warning( NULL, "failed to parse vectors\n" ); - } - - // We are done with this mlt_geometry - if ( g ) mlt_geometry_close( g ); - return tx; -} - -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_filter filter = mlt_frame_pop_service( frame ); - char *vectors = mlt_properties_get( MLT_FILTER_PROPERTIES(filter), "vectors" ); - mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter)); - - // Disable consumer scaling - if (profile && profile->width && profile->height) { - *width = profile->width; - *height = profile->height; - } - - *format = mlt_image_yuv422; - if (vectors) - *format= mlt_image_rgb24; - mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "consumer_deinterlace", 1 ); - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - if ( !error && *image ) - { - videostab2_data* data = filter->child; - if ( data==NULL ) { // big error, abort - return 1; - } - mlt_position length = mlt_filter_get_length2( filter, frame ); - int h = *height; - int w = *width; - - // Service locks are for concurrency control - mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); - - // Handle signal from app to re-init data - if ( mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter) , "refresh" ) ) - { - mlt_properties_set( MLT_FILTER_PROPERTIES(filter) , "refresh", NULL ); - data->initialized = 0; - } - - if ( !vectors) { - if ( !data->initialized ) - { - // Initialize our context - data->initialized = 1; - data->stab->width=w; - data->stab->height=h; - if (*format==mlt_image_yuv420p) data->stab->framesize=w*h* 3/2;//( mlt_image_format_size ( *format, w,h , 0) ; // 3/2 =1 too small - if (*format==mlt_image_yuv422) data->stab->framesize=w*h; - data->stab->shakiness = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter) , "shakiness" ); - data->stab->accuracy = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter) , "accuracy" ); - data->stab->stepsize = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter) , "stepsize" ); - data->stab->algo = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter) , "algo" ); - data->stab->show = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter) , "show" ); - data->stab->contrast_threshold = mlt_properties_get_double( MLT_FILTER_PROPERTIES(filter) , "mincontrast" ); - stabilize_configure(data->stab); - } - // Analyse - mlt_position pos = mlt_filter_get_position( filter, frame ); - stabilize_filter_video ( data->stab , *image, *format ); - - // On last frame - if ( pos == length - 1 ) - { - serialize_vectors( data , length ); - } - } - else - { - if ( data->initialized!=1 ) - { - char *interps = mlt_properties_get( MLT_FRAME_PROPERTIES( frame ), "rescale.interp" ); - - if ( data->initialized != 2 ) - { - // Load analysis results from property - data->initialized = 2; - - int interp = 2; // default to bilinear - float scale_zoom=1.0; - if ( *width != mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "meta.media.width" ) ) - scale_zoom = (float) *width / (float) mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "meta.media.width" ); - if ( strcmp( interps, "nearest" ) == 0 || strcmp( interps, "neighbor" ) == 0 ) - interp = 0; - else if ( strcmp( interps, "tiles" ) == 0 || strcmp( interps, "fast_bilinear" ) == 0 ) - interp = 1; - - data->trans->interpoltype = interp; - data->trans->smoothing = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "smoothing" ); - data->trans->maxshift = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "maxshift" ); - data->trans->maxangle = mlt_properties_get_double( MLT_FILTER_PROPERTIES(filter), "maxangle" ); - data->trans->crop = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "crop" ); - data->trans->invert = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "invert" ); - data->trans->relative = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "relative" ); - data->trans->zoom = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "zoom" ); - data->trans->optzoom = mlt_properties_get_int( MLT_FILTER_PROPERTIES(filter), "optzoom" ); - data->trans->sharpen = mlt_properties_get_double( MLT_FILTER_PROPERTIES(filter), "sharpen" ); - - transform_configure(data->trans,w,h,*format ,*image, deserialize_vectors( vectors, length , scale_zoom ),length); - - } - if ( data->initialized == 2 ) - { - // Stabilize - float pos = mlt_filter_get_position( filter, frame ); - data->trans->current_trans=pos; - transform_filter_video(data->trans, *image, *format ); - - } - } - } - mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); - } - return error; -} - -static mlt_frame filter_process( mlt_filter filter, mlt_frame frame ) -{ - mlt_frame_push_service( frame, filter ); - mlt_frame_push_get_image( frame, filter_get_image ); - return frame; -} - -static void filter_close( mlt_filter parent ) -{ - videostab2_data* data = parent->child; - if (data){ - if (data->stab) stabilize_stop(data->stab); - if (data->trans){ - free(data->trans->src); - free (data->trans); - } - free( data ); - } - parent->close = NULL; - parent->child = NULL; -} - -mlt_filter filter_videostab2_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - videostab2_data* data= calloc( 1, sizeof(videostab2_data)); - if ( data ) - { - data->stab = calloc( 1, sizeof(StabData) ); - if ( !data->stab ) - { - free( data ); - return NULL; - } - - data->trans = calloc( 1, sizeof (TransformData) ) ; - if ( !data->trans ) - { - free( data->stab ); - free( data ); - return NULL; - } - - mlt_filter parent = mlt_filter_new(); - if ( !parent ) - { - free( data->trans ); - free( data->stab ); - free( data ); - return NULL; - } - - parent->child = data; - parent->close = filter_close; - parent->process = filter_process; - data->parent = parent; - //properties for stabilize - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "shakiness", "4" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "accuracy", "4" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "stepsize", "6" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "algo", "1" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "mincontrast", "0.3" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "show", "0" ); - - //properties for transform - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "smoothing", "10" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "maxshift", "-1" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "maxangle", "-1" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "crop", "0" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "invert", "0" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "relative", "1" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "zoom", "0" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "optzoom", "1" ); - mlt_properties_set( MLT_FILTER_PROPERTIES(parent), "sharpen", "0.8" ); - return parent; - } - return NULL; -} diff --git a/src/modules/videostab/filter_videostab2.yml b/src/modules/videostab/filter_videostab2.yml deleted file mode 100644 index 39d851c9a..000000000 --- a/src/modules/videostab/filter_videostab2.yml +++ /dev/null @@ -1,220 +0,0 @@ -schema_version: 0.1 -type: filter -identifier: videostab2 -title: Videostab2 (*deprecated*) -copyright: Copyright (C) 2011 Marco Gittler -creator: Marco Gittler -version: 0.1 -license: GPL -language: en -url: http://public.hronopik.de/vid.stab/ -tags: - - Video -description: Stabilize Video (for wiggly/rolling video) -notes: > - This filter is deprecated and will eventually be removed; use the vidstab - filter instead. - This filter requires two passes. The first pass performs analysis and stores - the result in the vectors property. The second pass applies the vectors to - the image. - To use with melt, use 'melt ... -consumer xml:output.mlt all=1' for the - first pass. For the second pass, use output.mlt as the input. - -parameters: - - identifier: vectors (transform) - title: Vectors - type: geometry - description: > - A set of X/Y coordinates by which to adjust the image. - When this is not supplied, the filter computes the vectors and stores - them in this property when the last frame has been processed. - - - identifier: shakiness - title: Shakiness - type: integer - description: How shaky is the video (analysis) - readonly: no - required: no - minimum: 1 - maximum: 10 - default: 4 - mutable: yes - widget: spinner - - - identifier: accuracy - title: Accuracy - type: integer - description: Accuracy of shakiness detection (analysis) - readonly: no - required: no - minimum: 1 - maximum: 15 - default: 4 - mutable: yes - widget: spinner - - - identifier: stepsize - title: Stepsize - type: integer - description: Step size of search process (analysis) - readonly: no - required: no - minimum: 0 - maximum: 100 - default: 6 - mutable: yes - widget: spinner - - - identifier: algo - title: Algorithm - type: integer - description: 0 = brute force (translation only), 1 = small measurement fields (analysis) - readonly: no - required: no - minimum: 0 - maximum: 1 - default: 1 - mutable: yes - widget: spinner - - - identifier: mincontrast - title: Minimum Contrast - type: float - description: Below this contrast, a field is discarded (analysis) - readonly: no - required: no - minimum: 0 - maximum: 1 - default: 0.3 - mutable: yes - widget: spinner - - - identifier: show - title: Show - type: integer - description: 0 = draw nothing, 1 or 2 = show fields and transforms (analysis) - readonly: no - required: no - minimum: 0 - maximum: 2 - default: 0 - mutable: yes - widget: spinner - - - identifier: smoothing - title: Smoothing - type: integer - description: number of frames for lowpass filtering (2N + 1 frames) (transform) - readonly: no - required: no - minimum: 0 - maximum: 100 - default: 10 - mutable: yes - widget: spinner - - - identifier: maxshift - title: Maxshift - type: integer - description: maximum translation, -1 = no limit (transform) - unit: pixels - readonly: no - required: no - minimum: -1 - maximum: 1000 - default: -1 - mutable: yes - widget: spinner - - - identifier: maxangle - title: Maxangle - type: float - description: max angle to rotate, -1 = no limit (transform) - unit: radians - readonly: no - required: no - minimum: -1 - maximum: 3.142 - default: -1 - mutable: yes - widget: spinner - - - identifier: crop - title: Crop - type: integer - description: 0 = keep border, 1 = black background (transform) - readonly: no - required: no - minimum: 0 - maximum: 1 - default: 0 - mutable: yes - widget: spinner - - - identifier: invert - title: Invert - type: integer - description: Invert transforms (transform) - readonly: no - required: no - minimum: 0 - maximum: 1 - default: 0 - mutable: yes - widget: spinner - - - identifier: relative - title: Relative Transform - type: integer - description: 0 = absolute, 1 = relative (transform) - readonly: no - required: no - minimum: 0 - maximum: 1 - default: 1 - mutable: yes - widget: spinner - - - identifier: zoom - title: Zoom - type: integer - description: additional zoom amount (transform) - unit: percent - readonly: no - required: no - minimum: -500 - maximum: 500 - default: 0 - mutable: yes - widget: spinner - - - identifier: optzoom - title: Optimal Zoom - type: integer - description: automatically determine optimal zoom (transform) - readonly: no - required: no - minimum: 0 - maximum: 1 - default: 1 - mutable: yes - widget: spinner - - - identifier: sharpen - title: Sharpen Image - type: float - description: amount of sharpening (transform) - readonly: no - required: no - minimum: 0 - maximum: 10 - default: 0.8 - mutable: yes - widget: spinner - - - identifier: refresh - description: > - Applications should set this when it updates a transform parameter. - type: integer - minimum: 0 - maximum: 1 diff --git a/src/modules/videostab/gpl b/src/modules/videostab/gpl deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/modules/videostab/stab/estimate.c b/src/modules/videostab/stab/estimate.c deleted file mode 100644 index b80ab510d..000000000 --- a/src/modules/videostab/stab/estimate.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Video stabilizer - * - * Copyright (c) 2008 Lenny - * - * 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. - * - */ - -#include -#include -#include -#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(_WIN32) && !defined(__NetBSD__) && !defined(__OpenBSD__) -#include -#endif - -#include "estimate.h" -#include "vector.h" -#include "utils.h" - -#if !defined(MAXFLOAT) -#define MAXFLOAT HUGE_VAL -#endif - -es_ctx *es_init(int nc, int nr) { - - es_ctx *es = (es_ctx *)malloc(sizeof(es_ctx)); - - es->tc = KLTCreateTrackingContext(); - - es->tc->sequentialMode = TRUE; - es->tc->min_eigenvalue = 8; - es->tc->verbose = FALSE; - - KLTChangeTCPyramid(es->tc, 31); - - KLTUpdateTCBorder(es->tc); - - es->fr[0] = (KLT_PixelType *)malloc(nc * nr * sizeof(KLT_PixelType)); - es->fr[1] = (KLT_PixelType *)malloc(nc * nr * sizeof(KLT_PixelType)); - - es->fl = KLTCreateFeatureList(64); - - es->dv = (vc *)malloc(64 * sizeof(vc)); - es->nv = 0; - - es->nc = nc; - es->nr = nr; - - es->ff = FALSE; - - return es; -} - -vc es_estimate(es_ctx *es, unsigned char *fr) { - - KLT_PixelType *t; - int is, id; - - t = es->fr[0]; es->fr[0] = es->fr[1]; es->fr[1] = t; - - for (is = 0, id = 0; id < es->nc * es->nr; is += 3, id ++) - es->fr[1][id] = (fr[is + 0] * 30 + fr[is + 1] * 59 + fr[is + 2] * 11) / 100; - - if (es->ff == FALSE) { - - es->ff = TRUE; - - } else { - - vc bv = vc_set(0.0, 0.0); - float be = MAXFLOAT; - - int i, i2; - - KLTSelectGoodFeatures( - es->tc, es->fr[0], es->nc, es->nr, es->fl - ); - - for (i = 0; i < es->fl->nFeatures; i ++) - es->dv[i] = vc_set(es->fl->feature[i]->x, es->fl->feature[i]->y); - - KLTTrackFeatures( - es->tc, es->fr[0], es->fr[1], es->nc, es->nr, es->fl - ); - - es->nv = 0; - - for (i = 0; i < es->fl->nFeatures; i ++) { - - if (es->fl->feature[i]->val == KLT_TRACKED) { - - es->dv[es->nv] = vc_set( - es->fl->feature[i]->x - es->dv[i].x, - es->fl->feature[i]->y - es->dv[i].y - ); - - es->nv ++; - } - } - - for (i = 0; i < es->nv; i ++) { - - float ce = 0.0; - - for (i2 = 0; i2 < es->nv; i2 ++) - ce += vc_len(vc_sub(es->dv[i2], es->dv[i])); - - if (ce < be) { - - bv = es->dv[i]; - be = ce; - } - } - - return bv; - } - - return vc_zero(); -} - -void es_free(es_ctx *es) { - - free(es->dv); - - free(es->fr[0]); - free(es->fr[1]); - - KLTFreeFeatureList(es->fl); - KLTFreeTrackingContext(es->tc); - - free(es); -} - diff --git a/src/modules/videostab/stab/estimate.h b/src/modules/videostab/stab/estimate.h deleted file mode 100644 index 282c499ae..000000000 --- a/src/modules/videostab/stab/estimate.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef ESTIMATE_H -#define ESTIMATE_H - -#include "klt/klt.h" - -#include "vector.h" - -typedef struct { - - KLT_TrackingContext tc; - KLT_PixelType *fr[2]; - KLT_FeatureList fl; - - vc *dv; - int nv; - - int nc, nr; - - int ff; - -} es_ctx; - -es_ctx *es_init(int, int); - -vc es_estimate(es_ctx *, unsigned char *); - -void es_free(es_ctx *); - -#endif - diff --git a/src/modules/videostab/stab/klt/base.h b/src/modules/videostab/stab/klt/base.h deleted file mode 100644 index 35d709447..000000000 --- a/src/modules/videostab/stab/klt/base.h +++ /dev/null @@ -1,38 +0,0 @@ -/********************************************************************* - * base.h - *********************************************************************/ - -#ifndef _BASE_H_ -#define _BASE_H_ - -#ifndef uchar -#define uchar unsigned char -#endif - -#ifndef schar -#define schar signed char -#endif - -#ifndef uint -#define uint unsigned int -#endif - -#ifndef ushort -#define ushort unsigned short -#endif - -#ifndef ulong -#define ulong unsigned long -#endif - -#ifndef max -#define max(a,b) ((a) > (b) ? (a) : (b)) -#endif -#ifndef min -#define min(a,b) ((a) < (b) ? (a) : (b)) -#endif -#define max3(a,b,c) ((a) > (b) ? max((a),(c)) : max((b),(c))) -#define min3(a,b,c) ((a) < (b) ? min((a),(c)) : min((b),(c))) - -#endif - diff --git a/src/modules/videostab/stab/klt/convolve.c b/src/modules/videostab/stab/klt/convolve.c deleted file mode 100644 index f8107a279..000000000 --- a/src/modules/videostab/stab/klt/convolve.c +++ /dev/null @@ -1,279 +0,0 @@ -/********************************************************************* - * convolve.c - *********************************************************************/ - -/* Standard includes */ -#include -#include /* malloc(), realloc() */ - -/* Our includes */ -#include "base.h" -#include "error.h" -#include "convolve.h" -#include "klt_util.h" /* printing */ - -#define MAX_KERNEL_WIDTH 71 - - -typedef struct { - int width; - float data[MAX_KERNEL_WIDTH]; -} ConvolutionKernel; - -/* Kernels */ -ConvolutionKernel gauss_kernel; -ConvolutionKernel gaussderiv_kernel; -float sigma_last = -10.0; - - -/********************************************************************* - * _KLTToFloatImage - * - * Given a pointer to image data (probably unsigned chars), copy - * data to a float image. - */ - -void _KLTToFloatImage( - KLT_PixelType *img, - int ncols, int nrows, - _KLT_FloatImage floatimg) -{ - KLT_PixelType *ptrend = img + ncols*nrows; - float *ptrout = floatimg->data; - - floatimg->ncols = ncols; - floatimg->nrows = nrows; - - while (img < ptrend) *ptrout++ = (float) *img++; -} - - -/********************************************************************* - * _computeKernels - */ - -void _computeKernels( - float sigma, - ConvolutionKernel *gauss, - ConvolutionKernel *gaussderiv) -{ - const float factor = 0.01f; /* for truncating tail */ - int i; - - /* Compute kernels, and automatically determine widths */ - { - const int hw = MAX_KERNEL_WIDTH / 2; - float max_gauss = 1.0f, max_gaussderiv = (float) (sigma*exp(-0.5f)); - - /* Compute gauss and deriv */ - for (i = -hw ; i <= hw ; i++) { - gauss->data[i+hw] = (float) exp(-i*i / (2*sigma*sigma)); - gaussderiv->data[i+hw] = -i * gauss->data[i+hw]; - } - - /* Compute widths */ - gauss->width = MAX_KERNEL_WIDTH; - for (i = -hw ; fabs(gauss->data[i+hw] / max_gauss) < factor ; - i++, gauss->width -= 2); - gaussderiv->width = MAX_KERNEL_WIDTH; - for (i = -hw ; fabs(gaussderiv->data[i+hw] / max_gaussderiv) < factor ; - i++, gaussderiv->width -= 2); - if (gauss->width == MAX_KERNEL_WIDTH || - gaussderiv->width == MAX_KERNEL_WIDTH) - KLTError("(_computeKernels) MAX_KERNEL_WIDTH %d is too small for " - "a sigma of %f", MAX_KERNEL_WIDTH, sigma); - } - - /* Shift if width less than MAX_KERNEL_WIDTH */ - for (i = 0 ; i < gauss->width ; i++) - gauss->data[i] = gauss->data[i+(MAX_KERNEL_WIDTH-gauss->width)/2]; - for (i = 0 ; i < gaussderiv->width ; i++) - gaussderiv->data[i] = gaussderiv->data[i+(MAX_KERNEL_WIDTH-gaussderiv->width)/2]; - /* Normalize gauss and deriv */ - { - const int hw = gaussderiv->width / 2; - float den; - - den = 0.0; - for (i = 0 ; i < gauss->width ; i++) den += gauss->data[i]; - for (i = 0 ; i < gauss->width ; i++) gauss->data[i] /= den; - den = 0.0; - for (i = -hw ; i <= hw ; i++) den -= i*gaussderiv->data[i+hw]; - for (i = -hw ; i <= hw ; i++) gaussderiv->data[i+hw] /= den; - } - - sigma_last = sigma; -} - - -/********************************************************************* - * _KLTGetKernelWidths - * - */ - -void _KLTGetKernelWidths( - float sigma, - int *gauss_width, - int *gaussderiv_width) -{ - _computeKernels(sigma, &gauss_kernel, &gaussderiv_kernel); - *gauss_width = gauss_kernel.width; - *gaussderiv_width = gaussderiv_kernel.width; -} - - -/********************************************************************* - * _convolveImageHoriz - */ - -void _convolveImageHoriz( - _KLT_FloatImage imgin, - ConvolutionKernel kernel, - _KLT_FloatImage imgout) -{ - float *ptrrow = imgin->data; /* Points to row's first pixel */ - float *ptrout = imgout->data, /* Points to next output pixel */ - *ppp; - float sum; - int radius = kernel.width / 2; - int ncols = imgin->ncols, nrows = imgin->nrows; - int i, j, k; - - /* For each row, do ... */ - for (j = 0 ; j < nrows ; j++) { - - /* Zero leftmost columns */ - for (i = 0 ; i < radius ; i++) - *ptrout++ = 0.0; - - /* Convolve middle columns with kernel */ - for ( ; i < ncols - radius ; i++) { - ppp = ptrrow + i - radius; - sum = 0.0; - for (k = kernel.width-1 ; k >= 0 ; k--) - sum += *ppp++ * kernel.data[k]; - *ptrout++ = sum; - } - - /* Zero rightmost columns */ - for ( ; i < ncols ; i++) - *ptrout++ = 0.0; - - ptrrow += ncols; - } -} - - -/********************************************************************* - * _convolveImageVert - */ - -void _convolveImageVert( - _KLT_FloatImage imgin, - ConvolutionKernel kernel, - _KLT_FloatImage imgout) -{ - float *ptrcol = imgin->data; /* Points to row's first pixel */ - float *ptrout = imgout->data, /* Points to next output pixel */ - *ppp; - float sum; - int radius = kernel.width / 2; - int ncols = imgin->ncols, nrows = imgin->nrows; - int i, j, k; - - /* For each column, do ... */ - for (i = 0 ; i < ncols ; i++) { - - /* Zero topmost rows */ - for (j = 0 ; j < radius ; j++) { - *ptrout = 0.0; - ptrout += ncols; - } - - /* Convolve middle rows with kernel */ - for ( ; j < nrows - radius ; j++) { - ppp = ptrcol + ncols * (j - radius); - sum = 0.0; - for (k = kernel.width-1 ; k >= 0 ; k--) { - sum += *ppp * kernel.data[k]; - ppp += ncols; - } - *ptrout = sum; - ptrout += ncols; - } - - /* Zero bottommost rows */ - for ( ; j < nrows ; j++) { - *ptrout = 0.0; - ptrout += ncols; - } - - ptrcol++; - ptrout -= nrows * ncols - 1; - } -} - - -/********************************************************************* - * _convolveSeparate - */ - -void _convolveSeparate( - _KLT_FloatImage imgin, - ConvolutionKernel horiz_kernel, - ConvolutionKernel vert_kernel, - _KLT_FloatImage imgout) -{ - /* Create temporary image */ - _KLT_FloatImage tmpimg; - tmpimg = _KLTCreateFloatImage(imgin->ncols, imgin->nrows); - - /* Do convolution */ - _convolveImageHoriz(imgin, horiz_kernel, tmpimg); - - _convolveImageVert(tmpimg, vert_kernel, imgout); - - /* Free memory */ - _KLTFreeFloatImage(tmpimg); -} - - -/********************************************************************* - * _KLTComputeGradients - */ - -void _KLTComputeGradients( - _KLT_FloatImage img, - float sigma, - _KLT_FloatImage gradx, - _KLT_FloatImage grady) -{ - - /* Compute kernels, if necessary */ - if (fabs(sigma - sigma_last) > 0.05) - _computeKernels(sigma, &gauss_kernel, &gaussderiv_kernel); - - _convolveSeparate(img, gaussderiv_kernel, gauss_kernel, gradx); - _convolveSeparate(img, gauss_kernel, gaussderiv_kernel, grady); - -} - - -/********************************************************************* - * _KLTComputeSmoothedImage - */ - -void _KLTComputeSmoothedImage( - _KLT_FloatImage img, - float sigma, - _KLT_FloatImage smooth) -{ - /* Compute kernel, if necessary; gauss_deriv is not used */ - if (fabs(sigma - sigma_last) > 0.05) - _computeKernels(sigma, &gauss_kernel, &gaussderiv_kernel); - - _convolveSeparate(img, gauss_kernel, gauss_kernel, smooth); -} - - - diff --git a/src/modules/videostab/stab/klt/convolve.h b/src/modules/videostab/stab/klt/convolve.h deleted file mode 100644 index 6043a7e25..000000000 --- a/src/modules/videostab/stab/klt/convolve.h +++ /dev/null @@ -1,32 +0,0 @@ -/********************************************************************* - * convolve.h - *********************************************************************/ - -#ifndef _CONVOLVE_H_ -#define _CONVOLVE_H_ - -#include "klt.h" -#include "klt_util.h" - -void _KLTToFloatImage( - KLT_PixelType *img, - int ncols, int nrows, - _KLT_FloatImage floatimg); - -void _KLTComputeGradients( - _KLT_FloatImage img, - float sigma, - _KLT_FloatImage gradx, - _KLT_FloatImage grady); - -void _KLTGetKernelWidths( - float sigma, - int *gauss_width, - int *gaussderiv_width); - -void _KLTComputeSmoothedImage( - _KLT_FloatImage img, - float sigma, - _KLT_FloatImage smooth); - -#endif diff --git a/src/modules/videostab/stab/klt/error.c b/src/modules/videostab/stab/klt/error.c deleted file mode 100644 index 5cb4ee4ed..000000000 --- a/src/modules/videostab/stab/klt/error.c +++ /dev/null @@ -1,55 +0,0 @@ -/********************************************************************* - * error.c - * - * Error and warning messages, and system commands. - *********************************************************************/ - - -/* Standard includes */ -#include -#include -#include -#include - -/********************************************************************* - * KLTError - * - * Prints an error message and dies. - * - * INPUTS - * exactly like printf - */ - -void KLTError(char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - mlt_log_error(NULL, "KLT Error: "); - mlt_log_error(NULL, fmt, args); - mlt_log_error(NULL, "\n"); - va_end(args); -} - - -/********************************************************************* - * KLTWarning - * - * Prints a warning message. - * - * INPUTS - * exactly like printf - */ - -void KLTWarning(char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - fprintf(stderr, "KLT Warning: "); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - fflush(stderr); - va_end(args); -} - diff --git a/src/modules/videostab/stab/klt/error.h b/src/modules/videostab/stab/klt/error.h deleted file mode 100644 index 4dac13651..000000000 --- a/src/modules/videostab/stab/klt/error.h +++ /dev/null @@ -1,15 +0,0 @@ -/********************************************************************* - * error.h - *********************************************************************/ - -#ifndef _ERROR_H_ -#define _ERROR_H_ - -#include -#include - -void KLTError(char *fmt, ...); -void KLTWarning(char *fmt, ...); - -#endif - diff --git a/src/modules/videostab/stab/klt/klt.c b/src/modules/videostab/stab/klt/klt.c deleted file mode 100644 index 76ed461c6..000000000 --- a/src/modules/videostab/stab/klt/klt.c +++ /dev/null @@ -1,342 +0,0 @@ -/********************************************************************* - * klt.c - * - * Kanade-Lucas-Tomasi tracker - *********************************************************************/ - -/* Standard includes */ -#include /* logf() */ -#include /* malloc() */ - -/* Our includes */ -#include "base.h" -#include "convolve.h" -#include "error.h" -#include "klt.h" -#include "pyramid.h" - -/********************************************************************* - * KLTCreateTrackingContext - * - */ - -KLT_TrackingContext KLTCreateTrackingContext() -{ - KLT_TrackingContext tc = NULL; - - /* Allocate memory */ - tc = (KLT_TrackingContext) calloc(1, sizeof(KLT_TrackingContextRec)); - - /* Set values to default values */ - tc->mindist = 10; - tc->window_width = 7; - tc->window_height = 7; - tc->sequentialMode = FALSE; - tc->smoothBeforeSelecting = TRUE; - tc->min_eigenvalue = 1; - tc->min_determinant = 0.01; - tc->max_iterations = 10; - tc->min_displacement = 0.1; - tc->max_residue = 10.0; - tc->grad_sigma = 1.0; - tc->smooth_sigma_fact = 0.1; - tc->pyramid_sigma_fact = 0.9; - tc->step_factor = 1.0; - tc->nSkippedPixels = 0; - tc->pyramid_last = NULL; - tc->pyramid_last_gradx = NULL; - tc->pyramid_last_grady = NULL; - tc->verbose = TRUE; - - /* Change nPyramidLevels and subsampling */ - KLTChangeTCPyramid(tc, 31); - - /* Update border, which is dependent upon */ - /* smooth_sigma_fact, pyramid_sigma_fact, window_size, and subsampling */ - KLTUpdateTCBorder(tc); - - return(tc); -} - -/********************************************************************* - * KLTCreateFeatureList - * - */ - -KLT_FeatureList KLTCreateFeatureList( - int nFeatures) -{ - KLT_FeatureList fl; - KLT_Feature first; - int nbytes = sizeof(KLT_FeatureListRec) + - nFeatures * sizeof(KLT_Feature) + - nFeatures * sizeof(KLT_FeatureRec); - int i; - - /* Allocate memory for feature list */ - fl = (KLT_FeatureList) malloc(nbytes); - - /* Set parameters */ - fl->nFeatures = nFeatures; - - /* Set pointers */ - fl->feature = (KLT_Feature *) (fl + 1); - first = (KLT_Feature) (fl->feature + nFeatures); - for (i = 0 ; i < nFeatures ; i++) - fl->feature[i] = first + i; - - /* Return feature list */ - return(fl); -} - -/********************************************************************* - * KLTPrintTrackingContext - */ - -void KLTPrintTrackingContext( - KLT_TrackingContext tc) -{ - fprintf(stderr, "\n\nTracking context:\n\n"); - fprintf(stderr, "\tmindist = %d\n", tc->mindist); - fprintf(stderr, "\twindow_width = %d\n", tc->window_width); - fprintf(stderr, "\twindow_height = %d\n", tc->window_height); - fprintf(stderr, "\tsequentialMode = %s\n", - tc->sequentialMode ? "TRUE" : "FALSE"); - fprintf(stderr, "\tsmoothBeforeSelecting = %s\n", - tc->smoothBeforeSelecting ? "TRUE" : "FALSE"); - - fprintf(stderr, "\tmin_eigenvalue = %d\n", tc->min_eigenvalue); - fprintf(stderr, "\tmin_determinant = %f\n", tc->min_determinant); - fprintf(stderr, "\tmin_displacement = %f\n", tc->min_displacement); - fprintf(stderr, "\tmax_iterations = %d\n", tc->max_iterations); - fprintf(stderr, "\tmax_residue = %f\n", tc->max_residue); - fprintf(stderr, "\tgrad_sigma = %f\n", tc->grad_sigma); - fprintf(stderr, "\tsmooth_sigma_fact = %f\n", tc->smooth_sigma_fact); - fprintf(stderr, "\tpyramid_sigma_fact = %f\n", tc->pyramid_sigma_fact); - fprintf(stderr, "\tnSkippedPixels = %d\n", tc->nSkippedPixels); - fprintf(stderr, "\tborderx = %d\n", tc->borderx); - fprintf(stderr, "\tbordery = %d\n", tc->bordery); - fprintf(stderr, "\tnPyramidLevels = %d\n", tc->nPyramidLevels); - fprintf(stderr, "\tsubsampling = %d\n", tc->subsampling); - - fprintf(stderr, "\n\tpyramid_last = %s\n", (tc->pyramid_last!=NULL) ? - "points to old image" : "NULL"); - fprintf(stderr, "\tpyramid_last_gradx = %s\n", - (tc->pyramid_last_gradx!=NULL) ? - "points to old image" : "NULL"); - fprintf(stderr, "\tpyramid_last_grady = %s\n", - (tc->pyramid_last_grady!=NULL) ? - "points to old image" : "NULL"); - fprintf(stderr, "\n\n"); -} - - -/********************************************************************* - * KLTChangeTCPyramid - * - */ - -void KLTChangeTCPyramid( - KLT_TrackingContext tc, - int search_range) -{ - float window_halfwidth; - float subsampling; - - /* Check window size (and correct if necessary) */ - if (tc->window_width % 2 != 1) { - tc->window_width = tc->window_width+1; - KLTWarning("(KLTChangeTCPyramid) Window width must be odd. " - "Changing to %d.\n", tc->window_width); - } - if (tc->window_height % 2 != 1) { - tc->window_height = tc->window_height+1; - KLTWarning("(KLTChangeTCPyramid) Window height must be odd. " - "Changing to %d.\n", tc->window_height); - } - if (tc->window_width < 3) { - tc->window_width = 3; - KLTWarning("(KLTChangeTCPyramid) Window width must be at least three. \n" - "Changing to %d.\n", tc->window_width); - } - if (tc->window_height < 3) { - tc->window_height = 3; - KLTWarning("(KLTChangeTCPyramid) Window height must be at least three. \n" - "Changing to %d.\n", tc->window_height); - } - window_halfwidth = min(tc->window_width,tc->window_height)/2.0f; - - subsampling = ((float) search_range) / window_halfwidth; - - if (subsampling < 1.0) { /* 1.0 = 0+1 */ - tc->nPyramidLevels = 1; - } else if (subsampling <= 3.0) { /* 3.0 = 2+1 */ - tc->nPyramidLevels = 2; - tc->subsampling = 2; - } else if (subsampling <= 5.0) { /* 5.0 = 4+1 */ - tc->nPyramidLevels = 2; - tc->subsampling = 4; - } else if (subsampling <= 9.0) { /* 9.0 = 8+1 */ - tc->nPyramidLevels = 2; - tc->subsampling = 8; - } else { - /* The following lines are derived from the formula: - search_range = - window_halfwidth * \sum_{i=0}^{nPyramidLevels-1} 8^i, - which is the same as: - search_range = - window_halfwidth * (8^nPyramidLevels - 1)/(8 - 1). - Then, the value is rounded up to the nearest integer. */ - float val = (float) (log(7.0*subsampling+1.0)/log(8.0)); - tc->nPyramidLevels = (int) (val + 0.99); - tc->subsampling = 8; - } -} - - -/********************************************************************* - * NOTE: Manually must ensure consistency with _KLTComputePyramid() - */ - -float _pyramidSigma( - KLT_TrackingContext tc) -{ - return (tc->pyramid_sigma_fact * tc->subsampling); -} - - -/********************************************************************* - * Updates border, which is dependent upon - * smooth_sigma_fact, pyramid_sigma_fact, window_size, and subsampling - */ - -void KLTUpdateTCBorder( - KLT_TrackingContext tc) -{ - float val; - int pyramid_gauss_hw; - int smooth_gauss_hw; - int gauss_width, gaussderiv_width; - int num_levels = tc->nPyramidLevels; - int n_invalid_pixels; - int window_hw; - int ss = tc->subsampling; - int ss_power; - int border; - int i; - - /* Check window size (and correct if necessary) */ - if (tc->window_width % 2 != 1) { - tc->window_width = tc->window_width+1; - KLTWarning("(KLTUpdateTCBorder) Window width must be odd. " - "Changing to %d.\n", tc->window_width); - } - if (tc->window_height % 2 != 1) { - tc->window_height = tc->window_height+1; - KLTWarning("(KLTUpdateTCBorder) Window height must be odd. " - "Changing to %d.\n", tc->window_height); - } - if (tc->window_width < 3) { - tc->window_width = 3; - KLTWarning("(KLTUpdateTCBorder) Window width must be at least three. \n" - "Changing to %d.\n", tc->window_width); - } - if (tc->window_height < 3) { - tc->window_height = 3; - KLTWarning("(KLTUpdateTCBorder) Window height must be at least three. \n" - "Changing to %d.\n", tc->window_height); - } - window_hw = max(tc->window_width, tc->window_height)/2; - - /* Find widths of convolution windows */ - _KLTGetKernelWidths(_KLTComputeSmoothSigma(tc), - &gauss_width, &gaussderiv_width); - smooth_gauss_hw = gauss_width/2; - _KLTGetKernelWidths(_pyramidSigma(tc), - &gauss_width, &gaussderiv_width); - pyramid_gauss_hw = gauss_width/2; - - /* Compute the # of invalid pixels at each level of the pyramid. - n_invalid_pixels is computed with respect to the ith level - of the pyramid. So, e.g., if n_invalid_pixels = 5 after - the first iteration, then there are 5 invalid pixels in - level 1, which translated means 5*subsampling invalid pixels - in the original level 0. */ - n_invalid_pixels = smooth_gauss_hw; - for (i = 1 ; i < num_levels ; i++) { - val = ((float) n_invalid_pixels + pyramid_gauss_hw) / ss; - n_invalid_pixels = (int) (val + 0.99); /* Round up */ - } - - /* ss_power = ss^(num_levels-1) */ - ss_power = 1; - for (i = 1 ; i < num_levels ; i++) - ss_power *= ss; - - /* Compute border by translating invalid pixels back into */ - /* original image */ - border = (n_invalid_pixels + window_hw) * ss_power; - - tc->borderx = border; - tc->bordery = border; -} - - -/********************************************************************* - * KLTFreeTrackingContext - * KLTFreeFeatureList - * KLTFreeFeatureHistory - * KLTFreeFeatureTable - */ - -void KLTFreeTrackingContext( - KLT_TrackingContext tc) -{ - if (tc->pyramid_last) - _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last); - if (tc->pyramid_last_gradx) - _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last_gradx); - if (tc->pyramid_last_grady) - _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last_grady); - free(tc); -} - -void KLTFreeFeatureList(KLT_FeatureList fl) { - - free(fl); -} - -/********************************************************************* - * KLTStopSequentialMode - */ - -void KLTStopSequentialMode( - KLT_TrackingContext tc) -{ - tc->sequentialMode = FALSE; - _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last); - _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last_gradx); - _KLTFreePyramid((_KLT_Pyramid) tc->pyramid_last_grady); - tc->pyramid_last = NULL; - tc->pyramid_last_gradx = NULL; - tc->pyramid_last_grady = NULL; -} - - -/********************************************************************* - * KLTCountRemainingFeatures - */ - -int KLTCountRemainingFeatures( - KLT_FeatureList fl) -{ - int count = 0; - int i; - - for (i = 0 ; i < fl->nFeatures ; i++) - if (fl->feature[i]->val >= 0) - count++; - - return count; -} - diff --git a/src/modules/videostab/stab/klt/klt.h b/src/modules/videostab/stab/klt/klt.h deleted file mode 100644 index f583f6b3c..000000000 --- a/src/modules/videostab/stab/klt/klt.h +++ /dev/null @@ -1,143 +0,0 @@ -/********************************************************************* - * klt.h - * - * Kanade-Lucas-Tomasi tracker - *********************************************************************/ - -#ifndef _KLT_H_ -#define _KLT_H_ - -typedef float KLT_locType; -typedef unsigned char KLT_PixelType; - -#define KLT_BOOL int - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#ifndef NULL -#define NULL 0 -#endif - -#define KLT_TRACKED 0 -#define KLT_NOT_FOUND -1 -#define KLT_SMALL_DET -2 -#define KLT_MAX_ITERATIONS -3 -#define KLT_OOB -4 -#define KLT_LARGE_RESIDUE -5 - -#include "klt_util.h" /* for affine mapping */ - -/******************* - * Structures - */ - -typedef struct { - /* Available to user */ - int mindist; /* min distance b/w features */ - int window_width, window_height; - KLT_BOOL sequentialMode; /* whether to save most recent image to save time */ - /* can set to TRUE manually, but don't set to */ - /* FALSE manually */ - KLT_BOOL smoothBeforeSelecting; /* whether to smooth image before */ - /* selecting features */ - - /* Available, but hopefully can ignore */ - int min_eigenvalue; /* smallest eigenvalue allowed for selecting */ - float min_determinant; /* th for determining lost */ - float min_displacement; /* th for stopping tracking when pixel changes little */ - int max_iterations; /* th for stopping tracking when too many iterations */ - float max_residue; /* th for stopping tracking when residue is large */ - float grad_sigma; - float smooth_sigma_fact; - float pyramid_sigma_fact; - float step_factor; /* size of Newton steps; 2.0 comes from equations, 1.0 seems to avoid overshooting */ - int nSkippedPixels; /* # of pixels skipped when finding features */ - int borderx; /* border in which features will not be found */ - int bordery; - int nPyramidLevels; /* computed from search_ranges */ - int subsampling; /* " */ - - /* User must not touch these */ - void *pyramid_last; - void *pyramid_last_gradx; - void *pyramid_last_grady; - - int verbose; - -} KLT_TrackingContextRec, *KLT_TrackingContext; - -typedef struct { - KLT_locType x; - KLT_locType y; - int val; -} KLT_FeatureRec, *KLT_Feature; - -typedef struct { - int nFeatures; - KLT_Feature *feature; -} KLT_FeatureListRec, *KLT_FeatureList; - -typedef struct { - int nFrames; - KLT_Feature *feature; -} KLT_FeatureHistoryRec, *KLT_FeatureHistory; - -typedef struct { - int nFrames; - int nFeatures; - KLT_Feature **feature; -} KLT_FeatureTableRec, *KLT_FeatureTable; - -/******************* - * Functions - */ - -/* Create */ -KLT_TrackingContext KLTCreateTrackingContext(); -KLT_FeatureList KLTCreateFeatureList(int); - -/* Free */ -void KLTFreeTrackingContext(KLT_TrackingContext); -void KLTFreeFeatureList(KLT_FeatureList); - -/* Processing */ -void KLTSelectGoodFeatures( - KLT_TrackingContext tc, - KLT_PixelType *img, - int ncols, - int nrows, - KLT_FeatureList fl); -void KLTTrackFeatures( - KLT_TrackingContext tc, - KLT_PixelType *img1, - KLT_PixelType *img2, - int ncols, - int nrows, - KLT_FeatureList fl); -void KLTReplaceLostFeatures( - KLT_TrackingContext tc, - KLT_PixelType *img, - int ncols, - int nrows, - KLT_FeatureList fl); - -/* Utilities */ -int KLTCountRemainingFeatures( - KLT_FeatureList fl); -void KLTPrintTrackingContext( - KLT_TrackingContext tc); -void KLTChangeTCPyramid( - KLT_TrackingContext tc, - int search_range); -void KLTUpdateTCBorder( - KLT_TrackingContext tc); -void KLTStopSequentialMode( - KLT_TrackingContext tc); -float _KLTComputeSmoothSigma( - KLT_TrackingContext tc); - -#endif - diff --git a/src/modules/videostab/stab/klt/klt_util.c b/src/modules/videostab/stab/klt/klt_util.c deleted file mode 100644 index 36a357351..000000000 --- a/src/modules/videostab/stab/klt/klt_util.c +++ /dev/null @@ -1,52 +0,0 @@ -/********************************************************************* - * klt_util.c - *********************************************************************/ - -/* Standard includes */ -#include -#include - -/* Our includes */ -#include "base.h" -#include "error.h" -#include "klt.h" -#include "klt_util.h" - -/*********************************************************************/ - -float _KLTComputeSmoothSigma( - KLT_TrackingContext tc) -{ - return (tc->smooth_sigma_fact * max(tc->window_width, tc->window_height)); -} - - -/********************************************************************* - * _KLTCreateFloatImage - */ - -_KLT_FloatImage _KLTCreateFloatImage(int ncols, int nrows) { - - int nbytes = sizeof(_KLT_FloatImageRec) + ncols * nrows * sizeof(float); - - _KLT_FloatImage floatimg; - - floatimg = (_KLT_FloatImage)malloc(nbytes); - floatimg->ncols = ncols; - floatimg->nrows = nrows; - floatimg->data = (float *)(floatimg + 1); - - return(floatimg); -} - - -/********************************************************************* - * _KLTFreeFloatImage - */ - -void _KLTFreeFloatImage( - _KLT_FloatImage floatimg) -{ - free(floatimg); -} - diff --git a/src/modules/videostab/stab/klt/klt_util.h b/src/modules/videostab/stab/klt/klt_util.h deleted file mode 100644 index bb1a7432e..000000000 --- a/src/modules/videostab/stab/klt/klt_util.h +++ /dev/null @@ -1,28 +0,0 @@ -/********************************************************************* - * klt_util.h - *********************************************************************/ - -#ifndef _KLT_UTIL_H_ -#define _KLT_UTIL_H_ - -typedef struct { - int ncols; - int nrows; - float *data; -} _KLT_FloatImageRec, *_KLT_FloatImage; - -_KLT_FloatImage _KLTCreateFloatImage( - int ncols, - int nrows); - -void _KLTFreeFloatImage( - _KLT_FloatImage); - -void _KLTPrintSubFloatImage( - _KLT_FloatImage floatimg, - int x0, int y0, - int width, int height); - -#endif - - diff --git a/src/modules/videostab/stab/klt/pyramid.c b/src/modules/videostab/stab/klt/pyramid.c deleted file mode 100644 index 47077ce87..000000000 --- a/src/modules/videostab/stab/klt/pyramid.c +++ /dev/null @@ -1,139 +0,0 @@ -/********************************************************************* - * pyramid.c - * - *********************************************************************/ - -/* Standard includes */ -#include /* malloc() ? */ -#include /* memset() ? */ -#include /* */ - -/* Our includes */ -#include "base.h" -#include "error.h" -#include "convolve.h" /* for computing pyramid */ -#include "pyramid.h" - - -/********************************************************************* - * - */ - -_KLT_Pyramid _KLTCreatePyramid( - int ncols, - int nrows, - int subsampling, - int nlevels) -{ - _KLT_Pyramid pyramid; - int nbytes = sizeof(_KLT_PyramidRec) + - nlevels * sizeof(_KLT_FloatImage *) + - nlevels * sizeof(int) + - nlevels * sizeof(int); - int i; - - if (subsampling != 2 && subsampling != 4 && - subsampling != 8 && subsampling != 16 && subsampling != 32) - KLTError("(_KLTCreatePyramid) Pyramid's subsampling must " - "be either 2, 4, 8, 16, or 32"); - - - /* Allocate memory for structure and set parameters */ - pyramid = (_KLT_Pyramid)malloc(nbytes); - - /* Set parameters */ - pyramid->subsampling = subsampling; - pyramid->nLevels = nlevels; - pyramid->img = (_KLT_FloatImage *) (pyramid + 1); - pyramid->ncols = (int *) (pyramid->img + nlevels); - pyramid->nrows = (int *) (pyramid->ncols + nlevels); - - /* Allocate memory for each level of pyramid and assign pointers */ - for (i = 0 ; i < nlevels ; i++) { - pyramid->img[i] = _KLTCreateFloatImage(ncols, nrows); - pyramid->ncols[i] = ncols; - pyramid->nrows[i] = nrows; - ncols /= subsampling; - nrows /= subsampling; - } - - return pyramid; -} - - -/********************************************************************* - * - */ - -void _KLTFreePyramid( - _KLT_Pyramid pyramid) -{ - int i; - - /* Free images */ - for (i = 0 ; i < pyramid->nLevels ; i++) - _KLTFreeFloatImage(pyramid->img[i]); - - /* Free structure */ - free(pyramid); -} - - -/********************************************************************* - * - */ - -void _KLTComputePyramid( - _KLT_FloatImage img, - _KLT_Pyramid pyramid, - float sigma_fact) -{ - _KLT_FloatImage currimg, tmpimg; - int ncols = img->ncols, nrows = img->nrows; - int subsampling = pyramid->subsampling; - int subhalf = subsampling / 2; - float sigma = subsampling * sigma_fact; /* empirically determined */ - int oldncols; - int i, x, y; - - if (subsampling != 2 && subsampling != 4 && - subsampling != 8 && subsampling != 16 && subsampling != 32) - KLTError("(_KLTComputePyramid) Pyramid's subsampling must " - "be either 2, 4, 8, 16, or 32"); - - /* Copy original image to level 0 of pyramid */ - memcpy(pyramid->img[0]->data, img->data, ncols*nrows*sizeof(float)); - - currimg = img; - for (i = 1 ; i < pyramid->nLevels ; i++) { - tmpimg = _KLTCreateFloatImage(ncols, nrows); - _KLTComputeSmoothedImage(currimg, sigma, tmpimg); - - - /* Subsample */ - oldncols = ncols; - ncols /= subsampling; nrows /= subsampling; - for (y = 0 ; y < nrows ; y++) - for (x = 0 ; x < ncols ; x++) - pyramid->img[i]->data[y*ncols+x] = - tmpimg->data[(subsampling*y+subhalf)*oldncols + - (subsampling*x+subhalf)]; - - /* Reassign current image */ - currimg = pyramid->img[i]; - - _KLTFreeFloatImage(tmpimg); - } -} - - - - - - - - - - - - diff --git a/src/modules/videostab/stab/klt/pyramid.h b/src/modules/videostab/stab/klt/pyramid.h deleted file mode 100644 index eca9e6692..000000000 --- a/src/modules/videostab/stab/klt/pyramid.h +++ /dev/null @@ -1,32 +0,0 @@ -/********************************************************************* - * pyramid.h - *********************************************************************/ - -#ifndef _PYRAMID_H_ -#define _PYRAMID_H_ - -#include "klt_util.h" - -typedef struct { - int subsampling; - int nLevels; - _KLT_FloatImage *img; - int *ncols, *nrows; -} _KLT_PyramidRec, *_KLT_Pyramid; - - -_KLT_Pyramid _KLTCreatePyramid( - int ncols, - int nrows, - int subsampling, - int nlevels); - -void _KLTComputePyramid( - _KLT_FloatImage floatimg, - _KLT_Pyramid pyramid, - float sigma_fact); - -void _KLTFreePyramid( - _KLT_Pyramid pyramid); - -#endif diff --git a/src/modules/videostab/stab/klt/selectGoodFeatures.c b/src/modules/videostab/stab/klt/selectGoodFeatures.c deleted file mode 100644 index bb38a4c6c..000000000 --- a/src/modules/videostab/stab/klt/selectGoodFeatures.c +++ /dev/null @@ -1,430 +0,0 @@ -/********************************************************************* - * selectGoodFeatures.c - * - *********************************************************************/ - -/* Standard includes */ -#include /* malloc(), qsort() */ -#include /* fflush() */ -#include /* memset() */ -#include /* sqrt() */ - -/* Our includes */ -#include "base.h" -#include "error.h" -#include "convolve.h" -#include "klt.h" -#include "klt_util.h" -#include "pyramid.h" - -typedef enum {SELECTING_ALL, REPLACING_SOME} selectionMode; - -/*********************************************************************/ - -void _fillFeaturemap( - int x, int y, - uchar *featuremap, - int mindist, - int ncols, - int nrows) -{ - int ix, iy; - - for (iy = y - mindist ; iy <= y + mindist ; iy++) - for (ix = x - mindist ; ix <= x + mindist ; ix++) - if (ix >= 0 && ix < ncols && iy >= 0 && iy < nrows) - featuremap[iy*ncols+ix] = 1; -} - - -/********************************************************************* - * _enforceMinimumDistance - * - * Removes features that are within close proximity to better features. - * - * INPUTS - * featurelist: A list of features. The nFeatures property - * is used. - * - * OUTPUTS - * featurelist: Is overwritten. Nearby "redundant" features are removed. - * Writes -1's into the remaining elements. - * - * RETURNS - * The number of remaining features. - */ - -void _enforceMinimumDistance( - int *pointlist, /* featurepoints */ - int npoints, /* number of featurepoints */ - KLT_FeatureList featurelist, /* features */ - int ncols, int nrows, /* size of images */ - int mindist, /* min. dist b/w features */ - int min_eigenvalue, /* min. eigenvalue */ - KLT_BOOL overwriteAllFeatures) -{ - int indx; /* Index into features */ - int x, y, val; /* Location and trackability of pixel under consideration */ - uchar *featuremap; /* Boolean array recording proximity of features */ - int *ptr; - - /* Cannot add features with an eigenvalue less than one */ - if (min_eigenvalue < 1) min_eigenvalue = 1; - - /* Allocate memory for feature map and clear it */ - featuremap = (uchar *) malloc(ncols * nrows * sizeof(uchar)); - memset(featuremap, 0, ncols*nrows); - - /* Necessary because code below works with (mindist-1) */ - mindist--; - - /* If we are keeping all old good features, then add them to the featuremap */ - if (!overwriteAllFeatures) - for (indx = 0 ; indx < featurelist->nFeatures ; indx++) - if (featurelist->feature[indx]->val >= 0) { - x = (int) featurelist->feature[indx]->x; - y = (int) featurelist->feature[indx]->y; - _fillFeaturemap(x, y, featuremap, mindist, ncols, nrows); - } - - /* For each feature point, in descending order of importance, do ... */ - ptr = pointlist; - indx = 0; - while (1) { - - /* If we can't add all the points, then fill in the rest - of the featurelist with -1's */ - if (ptr >= pointlist + 3*npoints) { - while (indx < featurelist->nFeatures) { - if (overwriteAllFeatures || - featurelist->feature[indx]->val < 0) { - featurelist->feature[indx]->x = -1; - featurelist->feature[indx]->y = -1; - featurelist->feature[indx]->val = KLT_NOT_FOUND; - } - indx++; - } - break; - } - - x = *ptr++; - y = *ptr++; - val = *ptr++; - - while (!overwriteAllFeatures && - indx < featurelist->nFeatures && - featurelist->feature[indx]->val >= 0) - indx++; - - if (indx >= featurelist->nFeatures) break; - - /* If no neighbor has been selected, and if the minimum - eigenvalue is large enough, then add feature to the current list */ - if (!featuremap[y*ncols+x] && val >= min_eigenvalue) { - featurelist->feature[indx]->x = (KLT_locType) x; - featurelist->feature[indx]->y = (KLT_locType) y; - featurelist->feature[indx]->val = (int) val; - indx++; - - /* Fill in surrounding region of feature map, but - make sure that pixels are in-bounds */ - _fillFeaturemap(x, y, featuremap, mindist, ncols, nrows); - } - } - - /* Free feature map */ - free(featuremap); -} - - -/********************************************************************* - * _comparePoints - * - * Used by qsort (in _KLTSelectGoodFeatures) to determine - * which feature is better. - * By switching the '>' with the '<', qsort is fooled into sorting - * in descending order. - */ - -int _comparePoints(const void *a, const void *b) -{ - int v1 = *(((int *) a) + 2); - int v2 = *(((int *) b) + 2); - - if (v1 > v2) return(-1); - else if (v1 < v2) return(1); - else return(0); -} - -/********************************************************************* - * _sortPointList - */ - -void _sortPointList( - int *pointlist, - int npoints) -{ - qsort(pointlist, npoints, 3*sizeof(int), _comparePoints); -} - - -/********************************************************************* - * _minEigenvalue - * - * Given the three distinct elements of the symmetric 2x2 matrix - * [gxx gxy] - * [gxy gyy], - * Returns the minimum eigenvalue of the matrix. - */ - -float _minEigenvalue(float gxx, float gxy, float gyy) -{ - return (float) ((gxx + gyy - sqrt((gxx - gyy)*(gxx - gyy) + 4*gxy*gxy)) / 2.0); -} - - -/*********************************************************************/ - -void _KLTSelectGoodFeatures( - KLT_TrackingContext tc, - KLT_PixelType *img, - int ncols, - int nrows, - KLT_FeatureList featurelist, - selectionMode mode) -{ - _KLT_FloatImage floatimg, gradx, grady; - int window_hw, window_hh; - int *pointlist; - int npoints = 0; - KLT_BOOL overwriteAllFeatures = (mode == SELECTING_ALL) ? TRUE : FALSE; - KLT_BOOL floatimages_created = FALSE; - - /* Check window size (and correct if necessary) */ - if (tc->window_width % 2 != 1) { - tc->window_width = tc->window_width+1; - KLTWarning("Tracking context's window width must be odd. " - "Changing to %d.\n", tc->window_width); - } - if (tc->window_height % 2 != 1) { - tc->window_height = tc->window_height+1; - KLTWarning("Tracking context's window height must be odd. " - "Changing to %d.\n", tc->window_height); - } - if (tc->window_width < 3) { - tc->window_width = 3; - KLTWarning("Tracking context's window width must be at least three. \n" - "Changing to %d.\n", tc->window_width); - } - if (tc->window_height < 3) { - tc->window_height = 3; - KLTWarning("Tracking context's window height must be at least three. \n" - "Changing to %d.\n", tc->window_height); - } - window_hw = tc->window_width/2; - window_hh = tc->window_height/2; - - /* Create pointlist, which is a simplified version of a featurelist, */ - /* for speed. Contains only integer locations and values. */ - pointlist = (int *) malloc(ncols * nrows * 3 * sizeof(int)); - - /* Create temporary images, etc. */ - if (mode == REPLACING_SOME && tc->sequentialMode && tc->pyramid_last != NULL) { - - floatimg = ((_KLT_Pyramid) tc->pyramid_last)->img[0]; - gradx = ((_KLT_Pyramid) tc->pyramid_last_gradx)->img[0]; - grady = ((_KLT_Pyramid) tc->pyramid_last_grady)->img[0]; - - } else { - - floatimages_created = TRUE; - floatimg = _KLTCreateFloatImage(ncols, nrows); - gradx = _KLTCreateFloatImage(ncols, nrows); - grady = _KLTCreateFloatImage(ncols, nrows); - - if (tc->smoothBeforeSelecting) { - - _KLT_FloatImage tmpimg; - tmpimg = _KLTCreateFloatImage(ncols, nrows); - _KLTToFloatImage(img, ncols, nrows, tmpimg); - _KLTComputeSmoothedImage(tmpimg, _KLTComputeSmoothSigma(tc), floatimg); - _KLTFreeFloatImage(tmpimg); - - } else { - - _KLTToFloatImage(img, ncols, nrows, floatimg); - } - - /* Compute gradient of image in x and y direction */ - _KLTComputeGradients(floatimg, tc->grad_sigma, gradx, grady); - } - - /* Compute trackability of each image pixel as the minimum - of the two eigenvalues of the Z matrix */ - { - float gx, gy; - float gxx, gxy, gyy; - int xx, yy; - int *ptr; - float val; - unsigned int limit = 1; - int borderx = tc->borderx; /* Must not touch cols */ - int bordery = tc->bordery; /* lost by convolution */ - int x, y; - int i; - - if (borderx < window_hw) borderx = window_hw; - if (bordery < window_hh) bordery = window_hh; - - /* Find largest value of an int */ - for (i = 0 ; i < sizeof(int) ; i++) limit *= 256; - limit = limit/2 - 1; - - /* For most of the pixels in the image, do ... */ - ptr = pointlist; - for (y = bordery ; y < nrows - bordery ; y += tc->nSkippedPixels + 1) - for (x = borderx ; x < ncols - borderx ; x += tc->nSkippedPixels + 1) { - - /* Sum the gradients in the surrounding window */ - gxx = 0; gxy = 0; gyy = 0; - for (yy = y-window_hh ; yy <= y+window_hh ; yy++) - for (xx = x-window_hw ; xx <= x+window_hw ; xx++) { - gx = *(gradx->data + ncols*yy+xx); - gy = *(grady->data + ncols*yy+xx); - gxx += gx * gx; - gxy += gx * gy; - gyy += gy * gy; - } - - /* Store the trackability of the pixel as the minimum - of the two eigenvalues */ - *ptr++ = x; - *ptr++ = y; - val = _minEigenvalue(gxx, gxy, gyy); - if (val > limit) { - KLTWarning("(_KLTSelectGoodFeatures) minimum eigenvalue %f is " - "greater than the capacity of an int; setting " - "to maximum value", val); - val = (float) limit; - } - *ptr++ = (int) val; - npoints++; - } - } - - /* Sort the features */ - _sortPointList(pointlist, npoints); - - /* Check tc->mindist */ - if (tc->mindist < 0) { - KLTWarning("(_KLTSelectGoodFeatures) Tracking context field tc->mindist " - "is negative (%d); setting to zero", tc->mindist); - tc->mindist = 0; - } - - /* Enforce minimum distance between features */ - _enforceMinimumDistance( - pointlist, - npoints, - featurelist, - ncols, nrows, - tc->mindist, - tc->min_eigenvalue, - overwriteAllFeatures); - - /* Free memory */ - free(pointlist); - if (floatimages_created) { - _KLTFreeFloatImage(floatimg); - _KLTFreeFloatImage(gradx); - _KLTFreeFloatImage(grady); - } -} - - -/********************************************************************* - * KLTSelectGoodFeatures - * - * Main routine, visible to the outside. Finds the good features in - * an image. - * - * INPUTS - * tc: Contains parameters used in computation (size of image, - * size of window, min distance b/w features, sigma to compute - * image gradients, # of features desired). - * img: Pointer to the data of an image (probably unsigned chars). - * - * OUTPUTS - * features: List of features. The member nFeatures is computed. - */ - -void KLTSelectGoodFeatures( - KLT_TrackingContext tc, - KLT_PixelType *img, - int ncols, - int nrows, - KLT_FeatureList fl) -{ - if (tc->verbose >= 1) { - fprintf(stderr, "(KLT) Selecting the %d best features " - "from a %d by %d image... ", fl->nFeatures, ncols, nrows); - fflush(stderr); - } - - _KLTSelectGoodFeatures(tc, img, ncols, nrows, - fl, SELECTING_ALL); - - if (tc->verbose >= 1) - fprintf( - stderr, - "\n\t%d features found.\n", - KLTCountRemainingFeatures(fl) - ); -} - - -/********************************************************************* - * KLTReplaceLostFeatures - * - * Main routine, visible to the outside. Replaces the lost features - * in an image. - * - * INPUTS - * tc: Contains parameters used in computation (size of image, - * size of window, min distance b/w features, sigma to compute - * image gradients, # of features desired). - * img: Pointer to the data of an image (probably unsigned chars). - * - * OUTPUTS - * features: List of features. The member nFeatures is computed. - */ - -void KLTReplaceLostFeatures( - KLT_TrackingContext tc, - KLT_PixelType *img, - int ncols, - int nrows, - KLT_FeatureList fl) -{ - int nLostFeatures = fl->nFeatures - KLTCountRemainingFeatures(fl); - - if (tc->verbose >= 1) { - fprintf(stderr, "(KLT) Attempting to replace %d features " - "in a %d by %d image... ", nLostFeatures, ncols, nrows); - fflush(stderr); - } - - /* If there are any lost features, replace them */ - if (nLostFeatures > 0) - _KLTSelectGoodFeatures(tc, img, ncols, nrows, - fl, REPLACING_SOME); - - if (tc->verbose >= 1) - fprintf( - stderr, - "\n\t%d features replaced.\n", - nLostFeatures - fl->nFeatures + KLTCountRemainingFeatures(fl) - ); -} - - diff --git a/src/modules/videostab/stab/klt/trackFeatures.c b/src/modules/videostab/stab/klt/trackFeatures.c deleted file mode 100644 index 59acca151..000000000 --- a/src/modules/videostab/stab/klt/trackFeatures.c +++ /dev/null @@ -1,549 +0,0 @@ -/********************************************************************* - * trackFeatures.c - * - *********************************************************************/ - -/* Standard includes */ -#include /* fabs() */ -#include /* malloc() */ -#include /* fflush() */ - -/* Our includes */ -#include "base.h" -#include "error.h" -#include "convolve.h" /* for computing pyramid */ -#include "klt.h" -#include "klt_util.h" /* _KLT_FloatImage */ -#include "pyramid.h" /* _KLT_Pyramid */ - -typedef float *_FloatWindow; - -/********************************************************************* - * _interpolate - * - * Given a point (x,y) in an image, computes the bilinear interpolated - * gray-level value of the point in the image. - */ - -float _interpolate(float x, float y, _KLT_FloatImage img) { - - int xt = x; - int yt = y; - - float ax = x - xt; - float ay = y - yt; - - float *ptr = img->data + (img->ncols * yt) + xt; - - return ( - (1 - ax) * (1 - ay) * (*ptr) + - ax * (1 - ay) * (*(ptr + 1)) + - (1 - ax) * ay * (*(ptr + img->ncols)) + - ax * ay * (*(ptr + img->ncols + 1)) - ); -} - -/********************************************************************* - * _computeIntensityDifference - * - * Given two images and the window center in both images, - * aligns the images wrt the window and computes the difference - * between the two overlaid images. - */ - -void _computeIntensityDifference( - _KLT_FloatImage img1, /* images */ - _KLT_FloatImage img2, - float x1, float y1, /* center of window in 1st img */ - float x2, float y2, /* center of window in 2nd img */ - int width, int height, /* size of window */ - _FloatWindow imgdiff) /* output */ -{ - int hw = width/2, hh = height/2; - float g1, g2; - int i, j; - - /* Compute values */ - for (j = -hh ; j <= hh ; j++) - for (i = -hw ; i <= hw ; i++) { - g1 = _interpolate(x1+i, y1+j, img1); - g2 = _interpolate(x2+i, y2+j, img2); - *imgdiff++ = g1 - g2; - } -} - - -/********************************************************************* - * _computeGradientSum - * - * Given two gradients and the window center in both images, - * aligns the gradients wrt the window and computes the sum of the two - * overlaid gradients. - */ - -void _computeGradientSum( - _KLT_FloatImage gradx1, /* gradient images */ - _KLT_FloatImage grady1, - _KLT_FloatImage gradx2, - _KLT_FloatImage grady2, - float x1, float y1, /* center of window in 1st img */ - float x2, float y2, /* center of window in 2nd img */ - int width, int height, /* size of window */ - _FloatWindow gradx, /* output */ - _FloatWindow grady) /* " */ -{ - int hw = width/2, hh = height/2; - float g1, g2; - int i, j; - - /* Compute values */ - for (j = -hh ; j <= hh ; j++) - for (i = -hw ; i <= hw ; i++) { - g1 = _interpolate(x1+i, y1+j, gradx1); - g2 = _interpolate(x2+i, y2+j, gradx2); - *gradx++ = g1 + g2; - g1 = _interpolate(x1+i, y1+j, grady1); - g2 = _interpolate(x2+i, y2+j, grady2); - *grady++ = g1 + g2; - } -} - -/********************************************************************* - * _compute2by2GradientMatrix - * - */ - -void _compute2by2GradientMatrix( - _FloatWindow gradx, - _FloatWindow grady, - int width, /* size of window */ - int height, - float *gxx, /* return values */ - float *gxy, - float *gyy) - -{ - float gx, gy; - int i; - - /* Compute values */ - *gxx = 0.0; *gxy = 0.0; *gyy = 0.0; - for (i = 0 ; i < width * height ; i++) { - gx = *gradx++; - gy = *grady++; - *gxx += gx*gx; - *gxy += gx*gy; - *gyy += gy*gy; - } -} - - -/********************************************************************* - * _compute2by1ErrorVector - * - */ - -void _compute2by1ErrorVector( - _FloatWindow imgdiff, - _FloatWindow gradx, - _FloatWindow grady, - int width, /* size of window */ - int height, - float step_factor, /* 2.0 comes from equations, 1.0 seems to avoid overshooting */ - float *ex, /* return values */ - float *ey) -{ - float diff; - int i; - - /* Compute values */ - *ex = 0; *ey = 0; - for (i = 0 ; i < width * height ; i++) { - diff = *imgdiff++; - *ex += diff * (*gradx++); - *ey += diff * (*grady++); - } - *ex *= step_factor; - *ey *= step_factor; -} - - -/********************************************************************* - * _solveEquation - * - * Solves the 2x2 matrix equation - * [gxx gxy] [dx] = [ex] - * [gxy gyy] [dy] = [ey] - * for dx and dy. - * - * Returns KLT_TRACKED on success and KLT_SMALL_DET on failure - */ - -int _solveEquation( - float gxx, float gxy, float gyy, - float ex, float ey, - float small, - float *dx, float *dy) -{ - float det = gxx*gyy - gxy*gxy; - - - if (det < small) return KLT_SMALL_DET; - - *dx = (gyy*ex - gxy*ey)/det; - *dy = (gxx*ey - gxy*ex)/det; - return KLT_TRACKED; -} - - -/********************************************************************* - * _allocateFloatWindow - */ - -_FloatWindow _allocateFloatWindow(int width, int height) { - - return (_FloatWindow)malloc(width * height * sizeof(float)); -} - -/********************************************************************* - * _sumAbsFloatWindow - */ - -float _sumAbsFloatWindow( - _FloatWindow fw, - int width, - int height) -{ - float sum = 0.0; - int w; - - for ( ; height > 0 ; height--) - for (w=0 ; w < width ; w++) - sum += (float) fabs(*fw++); - - return sum; -} - - -/********************************************************************* - * _trackFeature - * - * Tracks a feature point from one image to the next. - * - * RETURNS - * KLT_SMALL_DET if feature is lost, - * KLT_MAX_ITERATIONS if tracking stopped because iterations timed out, - * KLT_TRACKED otherwise. - */ - -int _trackFeature( - float x1, /* location of window in first image */ - float y1, - float *x2, /* starting location of search in second image */ - float *y2, - _KLT_FloatImage img1, - _KLT_FloatImage gradx1, - _KLT_FloatImage grady1, - _KLT_FloatImage img2, - _KLT_FloatImage gradx2, - _KLT_FloatImage grady2, - int width, /* size of window */ - int height, - float step_factor, /* 2.0 comes from equations, 1.0 seems to avoid overshooting */ - int max_iterations, - float small, /* determinant threshold for declaring KLT_SMALL_DET */ - float th, /* displacement threshold for stopping */ - float max_residue) /* residue threshold for declaring KLT_LARGE_RESIDUE */ -{ - _FloatWindow imgdiff, gradx, grady; - float gxx, gxy, gyy, ex, ey, dx, dy; - int iteration = 0; - int status; - int hw = width / 2; - int hh = height / 2; - int nc = img1->ncols; - int nr = img1->nrows; - float one_plus_eps = 1.001f; /* To prevent rounding errors */ - - - /* Allocate memory for windows */ - imgdiff = _allocateFloatWindow(width, height); - gradx = _allocateFloatWindow(width, height); - grady = _allocateFloatWindow(width, height); - - /* Iteratively update the window position */ - do { - - /* If out of bounds, exit loop */ - if ( x1-hw < 0.0f || nc-( x1+hw) < one_plus_eps || - *x2-hw < 0.0f || nc-(*x2+hw) < one_plus_eps || - y1-hh < 0.0f || nr-( y1+hh) < one_plus_eps || - *y2-hh < 0.0f || nr-(*y2+hh) < one_plus_eps) { - status = KLT_OOB; - break; - } - - /* Compute gradient and difference windows */ - _computeIntensityDifference(img1, img2, x1, y1, *x2, *y2, - width, height, imgdiff); - _computeGradientSum(gradx1, grady1, gradx2, grady2, - x1, y1, *x2, *y2, width, height, gradx, grady); - - - /* Use these windows to construct matrices */ - _compute2by2GradientMatrix(gradx, grady, width, height, - &gxx, &gxy, &gyy); - _compute2by1ErrorVector(imgdiff, gradx, grady, width, height, step_factor, - &ex, &ey); - - /* Using matrices, solve equation for new displacement */ - status = _solveEquation(gxx, gxy, gyy, ex, ey, small, &dx, &dy); - if (status == KLT_SMALL_DET) break; - - *x2 += dx; - *y2 += dy; - iteration++; - - } while ((fabs(dx)>=th || fabs(dy)>=th) && iteration < max_iterations); - - /* Check whether window is out of bounds */ - if (*x2-hw < 0.0f || nc-(*x2+hw) < one_plus_eps || - *y2-hh < 0.0f || nr-(*y2+hh) < one_plus_eps) - status = KLT_OOB; - - /* Check whether residue is too large */ - if (status == KLT_TRACKED) { - - _computeIntensityDifference( - img1, img2, x1, y1, *x2, *y2, - width, height, imgdiff); - - if (_sumAbsFloatWindow(imgdiff, width, height)/(width*height) > max_residue) - status = KLT_LARGE_RESIDUE; - } - - /* Free memory */ - free(imgdiff); - free(gradx); - free(grady); - - /* Return appropriate value */ - if (status == KLT_SMALL_DET) - return KLT_SMALL_DET; - else if (status == KLT_OOB) - return KLT_OOB; - else if (status == KLT_LARGE_RESIDUE) - return KLT_LARGE_RESIDUE; - else if (iteration >= max_iterations) - return KLT_MAX_ITERATIONS; - else - return KLT_TRACKED; - -} - - -/*********************************************************************/ - -KLT_BOOL _outOfBounds( - float x, - float y, - int ncols, - int nrows, - int borderx, - int bordery) -{ - return (x < borderx || x > ncols-1-borderx || - y < bordery || y > nrows-1-bordery ); -} - -/********************************************************************* - * KLTTrackFeatures - * - * Tracks feature points from one image to the next. - */ - -void KLTTrackFeatures( - KLT_TrackingContext tc, - KLT_PixelType *img1, - KLT_PixelType *img2, - int ncols, - int nrows, - KLT_FeatureList featurelist) -{ - _KLT_FloatImage tmpimg = NULL; - _KLT_FloatImage floatimg1 = NULL; - _KLT_FloatImage floatimg2 = NULL; - - _KLT_Pyramid pyramid1, pyramid1_gradx, pyramid1_grady; - _KLT_Pyramid pyramid2, pyramid2_gradx, pyramid2_grady; - - int val = 0; - KLT_BOOL floatimg1_created = FALSE; - - float subsampling = (float)tc->subsampling; - float xloc, yloc, xlocout, ylocout; - int i, indx, r; - - if (tc->verbose >= 1) { - fprintf(stderr, "(KLT) Tracking %d features in a %d by %d image... ", - KLTCountRemainingFeatures(featurelist), ncols, nrows); - fflush(stderr); - } - - /* Check window size (and correct if necessary) */ - if (tc->window_width % 2 != 1) { - tc->window_width = tc->window_width+1; - KLTWarning("Tracking context's window width must be odd. " - "Changing to %d.\n", tc->window_width); - } - if (tc->window_height % 2 != 1) { - tc->window_height = tc->window_height+1; - KLTWarning("Tracking context's window height must be odd. " - "Changing to %d.\n", tc->window_height); - } - if (tc->window_width < 3) { - tc->window_width = 3; - KLTWarning("Tracking context's window width must be at least three. \n" - "Changing to %d.\n", tc->window_width); - } - if (tc->window_height < 3) { - tc->window_height = 3; - KLTWarning("Tracking context's window height must be at least three. \n" - "Changing to %d.\n", tc->window_height); - } - - /* Create temporary image */ - tmpimg = _KLTCreateFloatImage(ncols, nrows); - - /* Process first image by converting to float, smoothing, computing */ - /* pyramid, and computing gradient pyramids */ - if (tc->sequentialMode && tc->pyramid_last != NULL) { - pyramid1 = (_KLT_Pyramid) tc->pyramid_last; - pyramid1_gradx = (_KLT_Pyramid) tc->pyramid_last_gradx; - pyramid1_grady = (_KLT_Pyramid) tc->pyramid_last_grady; - if (pyramid1->ncols[0] != ncols || pyramid1->nrows[0] != nrows) - KLTError("(KLTTrackFeatures) Size of incoming image (%d by %d) " - "is different from size of previous image (%d by %d)\n", - ncols, nrows, pyramid1->ncols[0], pyramid1->nrows[0]); - } else { - floatimg1_created = TRUE; - floatimg1 = _KLTCreateFloatImage(ncols, nrows); - _KLTToFloatImage(img1, ncols, nrows, tmpimg); - _KLTComputeSmoothedImage(tmpimg, _KLTComputeSmoothSigma(tc), floatimg1); - pyramid1 = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); - _KLTComputePyramid(floatimg1, pyramid1, tc->pyramid_sigma_fact); - pyramid1_gradx = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); - pyramid1_grady = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); - for (i = 0 ; i < tc->nPyramidLevels ; i++) - _KLTComputeGradients(pyramid1->img[i], tc->grad_sigma, - pyramid1_gradx->img[i], - pyramid1_grady->img[i]); - } - - /* Do the same thing with second image */ - floatimg2 = _KLTCreateFloatImage(ncols, nrows); - _KLTToFloatImage(img2, ncols, nrows, tmpimg); - _KLTComputeSmoothedImage(tmpimg, _KLTComputeSmoothSigma(tc), floatimg2); - pyramid2 = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); - _KLTComputePyramid(floatimg2, pyramid2, tc->pyramid_sigma_fact); - pyramid2_gradx = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); - pyramid2_grady = _KLTCreatePyramid(ncols, nrows, (int) subsampling, tc->nPyramidLevels); - for (i = 0 ; i < tc->nPyramidLevels ; i++) - _KLTComputeGradients(pyramid2->img[i], tc->grad_sigma, - pyramid2_gradx->img[i], - pyramid2_grady->img[i]); - - /* For each feature, do ... */ - for (indx = 0 ; indx < featurelist->nFeatures ; indx++) { - - /* Only track features that are not lost */ - if (featurelist->feature[indx]->val >= 0) { - - xloc = featurelist->feature[indx]->x; - yloc = featurelist->feature[indx]->y; - - /* Transform location to coarsest resolution */ - for (r = tc->nPyramidLevels - 1 ; r >= 0 ; r--) { - xloc /= subsampling; yloc /= subsampling; - } - xlocout = xloc; ylocout = yloc; - - /* Beginning with coarsest resolution, do ... */ - for (r = tc->nPyramidLevels - 1 ; r >= 0 ; r--) { - - /* Track feature at current resolution */ - xloc *= subsampling; yloc *= subsampling; - xlocout *= subsampling; ylocout *= subsampling; - - val = _trackFeature(xloc, yloc, - &xlocout, &ylocout, - pyramid1->img[r], - pyramid1_gradx->img[r], pyramid1_grady->img[r], - pyramid2->img[r], - pyramid2_gradx->img[r], pyramid2_grady->img[r], - tc->window_width, tc->window_height, - tc->step_factor, - tc->max_iterations, - tc->min_determinant, - tc->min_displacement, - tc->max_residue); - - if (val==KLT_SMALL_DET || val==KLT_OOB) - break; - } - - /* Record feature */ - if (val == KLT_OOB) { - featurelist->feature[indx]->x = -1.0; - featurelist->feature[indx]->y = -1.0; - featurelist->feature[indx]->val = KLT_OOB; - } else if (_outOfBounds(xlocout, ylocout, ncols, nrows, tc->borderx, tc->bordery)) { - featurelist->feature[indx]->x = -1.0; - featurelist->feature[indx]->y = -1.0; - featurelist->feature[indx]->val = KLT_OOB; - } else if (val == KLT_SMALL_DET) { - featurelist->feature[indx]->x = -1.0; - featurelist->feature[indx]->y = -1.0; - featurelist->feature[indx]->val = KLT_SMALL_DET; - } else if (val == KLT_LARGE_RESIDUE) { - featurelist->feature[indx]->x = -1.0; - featurelist->feature[indx]->y = -1.0; - featurelist->feature[indx]->val = KLT_LARGE_RESIDUE; - } else if (val == KLT_MAX_ITERATIONS) { - featurelist->feature[indx]->x = -1.0; - featurelist->feature[indx]->y = -1.0; - featurelist->feature[indx]->val = KLT_MAX_ITERATIONS; - } else { - featurelist->feature[indx]->x = xlocout; - featurelist->feature[indx]->y = ylocout; - featurelist->feature[indx]->val = KLT_TRACKED; - } - } - } - - if (tc->sequentialMode) { - tc->pyramid_last = pyramid2; - tc->pyramid_last_gradx = pyramid2_gradx; - tc->pyramid_last_grady = pyramid2_grady; - } else { - _KLTFreePyramid(pyramid2); - _KLTFreePyramid(pyramid2_gradx); - _KLTFreePyramid(pyramid2_grady); - } - - /* Free memory */ - _KLTFreeFloatImage(tmpimg); - if (floatimg1_created) _KLTFreeFloatImage(floatimg1); - _KLTFreeFloatImage(floatimg2); - _KLTFreePyramid(pyramid1); - _KLTFreePyramid(pyramid1_gradx); - _KLTFreePyramid(pyramid1_grady); - - if (tc->verbose >= 1) - fprintf( - stderr, - "\n\t%d features successfully tracked.\n", - KLTCountRemainingFeatures(featurelist) - ); -} - diff --git a/src/modules/videostab/stab/main.c b/src/modules/videostab/stab/main.c deleted file mode 100644 index 24b5c2ebf..000000000 --- a/src/modules/videostab/stab/main.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Video stabilizer - * - * Copyright (c) 2008 Lenny - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -//#include - -#include "avi/avi.h" - -#include "vector.h" -#include "utils.h" -#include "estimate.h" -#include "resample.h" - -AviMovie mv_in, mv_out; - -void print_help(char *argv[]) { - - printf( - " \n" - "Video stabilizer \n" - " \n" - "Usage: \n" - " %s [options] \n" - " \n" - "Options: \n" - " -r # | Rolling shutter angle | default: 0 | range: 0 - 180 \n" - " -q # | Output MJPEG quality | default: 100 | range: 50 - 100 \n" - " \n", - argv[0] - ); - - exit(EXIT_FAILURE); -} - -int main(int argc, char *argv[]) { - - int opt_shutter_angle = 0; - int opt_mjpeg_quality = 100; - - int nf, i, nc, nr; - int tfs, fps; - - vc *pos_i, *pos_h, *pos_y; - - es_ctx *es; - rs_ctx *rs; - - opterr = 0; - - while ((i = getopt(argc, argv, "r:q:")) != -1) { - - switch (i) { - - case 'r': - opt_shutter_angle = atoi(optarg); - break; - - case 'q': - opt_mjpeg_quality = atoi(optarg); - break; - - default: - print_help(argv); - } - } - - if (argc < optind + 2) - print_help(argv); - - if (AVI_open_movie(argv[optind], &mv_in) != AVI_ERROR_NONE) { - - printf("error: can't read from %s\n", argv[optind]); - return EXIT_FAILURE; - } - - if (mv_in.header->Streams < 1 || mv_in.streams[0].sh.Type != AVIST_VIDEO) { - - printf("error: video stream not found on %s\n", argv[optind]); - return EXIT_FAILURE; - } - - if (AVI_open_compress(argv[optind + 1], &mv_out, 1, AVI_FORMAT_MJPEG) != AVI_ERROR_NONE) { - - printf("error: can't write to %s\n", argv[optind + 1]); - return EXIT_FAILURE; - } - - printf("status: setup\n"); - - prepare_lanc_kernels(); - - nc = mv_in.header->Width; - nr = mv_in.header->Height; - - tfs = mv_in.header->TotalFrames; - fps = 1000000 / mv_in.header->MicroSecPerFrame; - - pos_i = (vc *)malloc(tfs * sizeof(vc)); - pos_h = (vc *)malloc(tfs * sizeof(vc)); - - pos_y = (vc *)malloc(nr * sizeof(vc)); - - AVI_set_compress_option(&mv_out, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_WIDTH, &nc); - AVI_set_compress_option(&mv_out, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_HEIGHT, &nr); - AVI_set_compress_option(&mv_out, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_FRAMERATE, &fps); - AVI_set_compress_option(&mv_out, AVI_OPTION_TYPE_MAIN, 0, AVI_OPTION_QUALITY, &opt_mjpeg_quality); - - es = es_init(nc, nr); - rs = rs_init(nc, nr); - - printf("status: estimating\n"); - - for (nf = 0; nf < tfs; nf ++) { - - unsigned char *fr = (unsigned char *)AVI_read_frame(&mv_in, AVI_FORMAT_RGB24, nf, 0); - - pos_i[nf] = vc_add( - nf > 0 ? pos_i[nf - 1] : vc_set(0.0, 0.0), - es_estimate(es, fr) - ); - - free(fr); - - if ((nf + 1) % 10 == 0) { - - printf("."); - fflush(stdout); - } - } - - printf("\nstatus: filtering\n"); - - hipass(pos_i, pos_h, tfs, fps / 2); - - printf("status: resampling\n"); - - for (nf = 0; nf < tfs; nf ++) { - - unsigned char *fr = (unsigned char *)AVI_read_frame(&mv_in, AVI_FORMAT_RGB24, nf, 0); - - for (i = 0; i < nr; i ++) { - - pos_y[i] = interp( - pos_h, tfs, - nf + (i - nr / 2.0) * opt_shutter_angle / (nr * 360.0) - ); - } - - rs_resample(rs, fr, pos_y); - - AVI_write_frame(&mv_out, nf, AVI_FORMAT_RGB24, fr, nc * nr * 3 * sizeof(unsigned char)); - - if ((nf + 1) % 10 == 0) { - - printf("."); - fflush(stdout); - } - } - - printf("\nstatus: closing\n"); - - es_free(es); - rs_free(rs); - - free_lanc_kernels(); - - AVI_close(&mv_in); - AVI_close_compress(&mv_out); - - return EXIT_SUCCESS; -} - diff --git a/src/modules/videostab/stab/resample.c b/src/modules/videostab/stab/resample.c deleted file mode 100644 index 12d82af70..000000000 --- a/src/modules/videostab/stab/resample.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Video stabilizer - * - * Copyright (c) 2008 Lenny - * - * 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. - * - */ - -#include -#include - -#include "resample.h" -#include "utils.h" - -rs_ctx *rs_init(int nc, int nr) { - - rs_ctx *rs = (rs_ctx *)malloc(sizeof(rs_ctx)); - - rs->tf = (unsigned char *)malloc(nc * nr * 3 * sizeof(unsigned char)); - - rs->nc = nc; - rs->nr = nr; - - return rs; -} - -void rs_resample(int* lanc_kernels,rs_ctx *rs, unsigned char *f, vc *p) { - - int i, x, y, c; - - for (y = 0; y < rs->nr; y ++) { - - int yp = y * rs->nc; - int xd = floor(p[y].x); - - int *lk = select_lanc_kernel(lanc_kernels,p[y].x); - - for (x = 0; x < rs->nc; x ++) { - - int pd = (yp + x) * 3; - int a[3]; - - for (c = 0; c < 3; c ++) - a[c] = 0; - - for (i = -3; i < 5; i ++) { - - int ps = (yp + clamp(x + xd + i, 0, rs->nc - 1)) * 3; - - for (c = 0; c < 3; c ++) - a[c] += f[ps + c] * lk[i + 3]; - } - - for (c = 0; c < 3; c ++) - rs->tf[pd + c] = clamp(a[c] / 1024, 0, 255); - } - } - - for (y = 0; y < rs->nr; y ++) { - - int yp = y * rs->nc; - int yd = floor(p[y].y); - - int *lk = select_lanc_kernel(lanc_kernels,p[y].y); - - for (x = 0; x < rs->nc; x ++) { - - int pd = (yp + x) * 3; - int a[3]; - - for (c = 0; c < 3; c ++) - a[c] = 0; - - for (i = -3; i < 5; i ++) { - - int ps = (clamp(y + yd + i, 0, rs->nr - 1) * rs->nc + x) * 3; - - for (c = 0; c < 3; c ++) - a[c] += rs->tf[ps + c] * lk[i + 3]; - } - - for (c = 0; c < 3; c ++) - f[pd + c] = clamp(a[c] / 1024, 0, 255); - } - } -} - -void rs_free(rs_ctx *rs) { - - free(rs->tf); - - free(rs); -} - diff --git a/src/modules/videostab/stab/resample.h b/src/modules/videostab/stab/resample.h deleted file mode 100644 index aefa4a806..000000000 --- a/src/modules/videostab/stab/resample.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef RESAMPLE_H -#define RESAMPLE_H - -#include "vector.h" - -typedef struct { - - unsigned char *tf; - int nc, nr; - -} rs_ctx; - -rs_ctx *rs_init(int, int); - -void rs_resample(int*,rs_ctx *, unsigned char *, vc *); - -void rs_free(rs_ctx *); - -#endif - diff --git a/src/modules/videostab/stab/utils.c b/src/modules/videostab/stab/utils.c deleted file mode 100644 index 43fc30efd..000000000 --- a/src/modules/videostab/stab/utils.c +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Video stabilizer - * - * Copyright (c) 2008 Lenny - * - * 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. - * - */ - -#include -#include -#include - -#include "utils.h" - -float lanc(float x, float r) { - - float t = x * M_PI; - - if (x == 0.0) - return 1.0; - - if (x <= -r || x >= r) - return 0.0; - - return r * sin(t) * sin(t / r) / (t * t); -} - -float hann(float x, float d) { - - if (x < 0.0 || x > d) - return 0.0; - - return 0.5 * (1.0 - cos((M_PI * 2.0 * x) / (d - 1.0))); -} - -int clamp(int a, int b, int c) { - - if (a < b) - a = b; - - if (a > c) - a = c; - - return a; -} - -void lopass(vc *vi, vc *vo, int l, int r) { - - int d = r * 2 + 1; - float *ck = (float *)malloc(d * sizeof(float)); - float cw = 0.0; - - int i, j; - - for (i = 0; i < d; i ++) - cw += ck[i] = hann(i, d - 1); - - for (i = 0; i < l; i ++) { - - vc a = vc_zero(); - - for (j = i - r; j <= i + r; j ++) { - - int jc = clamp(j, 0, l - 1); - - vc_mul_acc(&a, vi[jc], ck[j - i + r]); - } - - vo[i] = vc_div(a, cw); - } - - free(ck); -} - -void hipass(vc *vi, vc *vo, int l, int r) { - - int i; - - lopass(vi, vo, l, r); - - for (i = 0; i < l; i ++) - vo[i] = vc_sub(vi[i], vo[i]); -} - -int* prepare_lanc_kernels() { - - int i, j; - - int* lanc_kernels = (int *)malloc(256 * 8 * sizeof(int)); - - for (i = 0; i < 256; i ++) - for (j = -3; j < 5; j ++) - lanc_kernels[i * 8 + j + 3] = lanc(j - i / 256.0, 4) * 1024.0; - return lanc_kernels; -} - -int *select_lanc_kernel(int* lanc_kernels,float x) { - - return lanc_kernels + (int)((x - floor(x)) * 256.0) * 8; -} - -void free_lanc_kernels(int *lanc_kernels) { - - free(lanc_kernels); -} - -vc interp(int* lanc_kernels, vc *vi, int l, float x) { - - vc a = vc_zero(); - int xd = floor(x); - int *lk = select_lanc_kernel(lanc_kernels,x); - - int i; - - for (i = -3; i < 5; i ++) { - - int ic = clamp(xd + i, 0, l - 1); - - vc_mul_acc(&a, vi[ic], lk[i + 3]); - } - - return vc_div(a, 1024.0); -} - diff --git a/src/modules/videostab/stab/utils.h b/src/modules/videostab/stab/utils.h deleted file mode 100644 index a8c388626..000000000 --- a/src/modules/videostab/stab/utils.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef UTILS_H -#define UTILS_H - -#include "vector.h" - -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -#ifndef FALSE -#define FALSE 0 -#endif - - -float lanc(float, float); -float hann(float, float); - -int clamp(int, int, int); - -void lopass(vc *, vc *, int, int); -void hipass(vc *, vc *, int, int); - -int* prepare_lanc_kernels(); -int *select_lanc_kernel(int*,float); -void free_lanc_kernels(int*); - -vc interp(int*,vc *, int, float); - -#endif - diff --git a/src/modules/videostab/stab/vector.c b/src/modules/videostab/stab/vector.c deleted file mode 100644 index 9c14d3654..000000000 --- a/src/modules/videostab/stab/vector.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Video stabilizer - * - * Copyright (c) 2008 Lenny - * - * 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. - * - */ - -#include - -#include "vector.h" - -vc vc_zero() { - - vc v3; - - v3.x = 0.0; - v3.y = 0.0; - - return v3; -} - -vc vc_one() { - - vc v3; - - v3.x = 1.0; - v3.y = 1.0; - - return v3; -} - -vc vc_set(float x, float y) { - - vc v3; - - v3.x = x; - v3.y = y; - - return v3; -} - -vc vc_add(vc v1, vc v2) { - - vc v3; - - v3.x = v1.x + v2.x; - v3.y = v1.y + v2.y; - - return v3; -} - -vc vc_sub(vc v1, vc v2) { - - vc v3; - - v3.x = v1.x - v2.x; - v3.y = v1.y - v2.y; - - return v3; -} - -vc vc_mul(vc v1, float v2) { - - vc v3; - - v3.x = v1.x * v2; - v3.y = v1.y * v2; - - return v3; -} - -vc vc_div(vc v1, float v2) { - - vc v3; - - v3.x = v1.x / v2; - v3.y = v1.y / v2; - - return v3; -} - -void vc_acc(vc *v1, vc v2) { - - v1->x += v2.x; - v1->y += v2.y; -} - -void vc_mul_acc(vc *v1, vc v2, float v3) { - - v1->x += v2.x * v3; - v1->y += v2.y * v3; -} - -float vc_len(vc v) { - - return sqrt(v.x * v.x + v.y * v.y); -} - -float vc_ang(vc v1, vc v2) { - - float c = v1.x * v2.y - v1.y * v2.x; - - if (fabs(c) > 0.0) { - - float l = vc_len(v1) * vc_len(v2); - float d = acos((v1.x * v2.x + v1.y * v2.y) / l); - - if (c > 0.0) - return d; - else - return -d; - } - - return 0.0; -} - diff --git a/src/modules/videostab/stab/vector.h b/src/modules/videostab/stab/vector.h deleted file mode 100644 index 0a773f0a5..000000000 --- a/src/modules/videostab/stab/vector.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef VECTOR_H -#define VECTOR_H - -typedef struct { - - float x, y; - -} vc; - -vc vc_zero(); -vc vc_one(); -vc vc_set(float, float); - -vc vc_add(vc, vc); -vc vc_sub(vc, vc); - -vc vc_mul(vc, float); -vc vc_div(vc, float); - -void vc_acc(vc *, vc); -void vc_mul_acc(vc *, vc, float); - -float vc_len(vc); -float vc_ang(vc, vc); - -#endif - diff --git a/src/modules/videostab/stabilize.c b/src/modules/videostab/stabilize.c deleted file mode 100644 index 00b4017a4..000000000 --- a/src/modules/videostab/stabilize.c +++ /dev/null @@ -1,954 +0,0 @@ -/* - * filter_stabilize.c - * - * Copyright (C) Georg Martius - June 2007 - * georg dot martius at web dot de - * mlt adaption by Marco Gittler marco at gitma dot de 2011 - * - * This file is part of transcode, a video stream processing tool - * - * transcode 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, or (at your option) - * any later version. - * - * transcode 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 GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* Typical call: - * transcode -V -J stabilize=shakiness=5:show=1,preview - * -i inp.mpeg -y null,null -o dummy - * all parameters are optional -*/ - -#define MOD_NAME "filter_stabilize.so" -#define MOD_VERSION "v0.75 (2010-04-07)" -#define MOD_CAP "extracts relative transformations of \n\ - subsequent frames (used for stabilization together with the\n\ - transform filter in a second pass)" -#define MOD_AUTHOR "Georg Martius" - -/* Ideas: - - Try OpenCL/Cuda, this should work great - - use smoothing on the frames and then use gradient decent! - - stepsize could be adapted (maybe to check only one field with large - stepsize and use the maximally required for the other fields -*/ - -#define MOD_FEATURES \ - TC_MODULE_FEATURE_FILTER|TC_MODULE_FEATURE_VIDEO -#define MOD_FLAGS \ - TC_MODULE_FLAG_RECONFIGURABLE | TC_MODULE_FLAG_DELAY -#define MAX(a,b) ((a < b) ? (b) : (a)) -#define MIN(a,b) ((a < b) ? (a) : (b)) -#include "stabilize.h" -#include -#include -#include -#include -#ifdef USE_SSE2 -#include -#endif - -void addTrans(StabData* sd, Transform sl) -{ - if (!sd->transs) { - sd->transs = tlist_new(0); - } - tlist_append(sd->transs, &sl,sizeof(Transform) ); -} - - - -/** initialise measurement fields on the frame. - The size of the fields and the maxshift is used to - calculate an optimal distribution in the frame. -*/ -int initFields(StabData* sd) -{ - int size = sd->field_size; - int rows = MAX(3,(sd->height - sd->maxshift*2)/size-1); - int cols = MAX(3,(sd->width - sd->maxshift*2)/size-1); - // make sure that the remaining rows have the same length - sd->field_num = rows*cols; - sd->field_rows = rows; - mlt_log_debug (NULL,"field setup: rows: %i cols: %i Total: %i fields", - rows, cols, sd->field_num); - - if (!(sd->fields = malloc(sizeof(Field) * sd->field_num))) { - mlt_log_error ( NULL, "malloc failed!\n"); - return 0; - } else { - int i, j; - // the border is the amount by which the field centers - // have to be away from the image boundary - // (stepsize is added in case shift is increased through stepsize) - int border = size/2 + sd->maxshift + sd->stepsize; - int step_x = (sd->width - 2*border)/MAX(cols-1,1); - int step_y = (sd->height - 2*border) / MAX(rows-1,1); - for (j = 0; j < rows; j++) { - for (i = 0; i < cols; i++) { - int idx = j*cols+i; - sd->fields[idx].x = border + i*step_x; - sd->fields[idx].y = border + j*step_y; - sd->fields[idx].size = size; - } - } - } - return 1; -} - - -/** - compares the two given images and returns the average absolute difference - \param d_x shift in x direction - \param d_y shift in y direction -*/ -double compareImg(unsigned char* I1, unsigned char* I2, - int width, int height, int bytesPerPixel, int d_x, int d_y) -{ - int i, j; - unsigned char* p1 = NULL; - unsigned char* p2 = NULL; - long int sum = 0; - int effectWidth = width - abs(d_x); - int effectHeight = height - abs(d_y); - -/* DEBUGGING code to export single frames */ -/* char buffer[100]; */ -/* sprintf(buffer, "pic_%02ix%02i_1.ppm", d_x, d_y); */ -/* FILE *pic1 = fopen(buffer, "w"); */ -/* sprintf(buffer, "pic_%02ix%02i_2.ppm", d_x, d_y); */ -/* FILE *pic2 = fopen(buffer, "w"); */ -/* fprintf(pic1, "P6\n%i %i\n255\n", effectWidth, effectHeight); */ -/* fprintf(pic2, "P6\n%i %i\n255\n", effectWidth, effectHeight); */ - - for (i = 0; i < effectHeight; i++) { - p1 = I1; - p2 = I2; - if (d_y > 0 ){ - p1 += (i + d_y) * width * bytesPerPixel; - p2 += i * width * bytesPerPixel; - } else { - p1 += i * width * bytesPerPixel; - p2 += (i - d_y) * width * bytesPerPixel; - } - if (d_x > 0) { - p1 += d_x * bytesPerPixel; - } else { - p2 -= d_x * bytesPerPixel; - } -#ifdef USE_SSE2 - __m128i A,B,C,D,E; - for (j = 0; j < effectWidth * bytesPerPixel - 16; j++) { -#else - for (j = 0; j < effectWidth * bytesPerPixel; j++) { -#endif - /* fwrite(p1,1,1,pic1);fwrite(p1,1,1,pic1);fwrite(p1,1,1,pic1); - fwrite(p2,1,1,pic2);fwrite(p2,1,1,pic2);fwrite(p2,1,1,pic2); - */ -#ifdef USE_SSE2 - A= _mm_loadu_si128((__m128i*)p1); //load unaligned data - B= _mm_loadu_si128((__m128i*)p2); - C= _mm_sad_epu8(A, B);//diff per 8 bit pixel stored in 2 64 byte values - D = _mm_srli_si128(C, 8); // shift first 64 byte value to align at the same as C - E = _mm_add_epi32(C, D); // add the 2 values (sum of all diffs) - sum+= _mm_cvtsi128_si32(E); //convert _m128i to int - - p1+=16; - p2+=16; - j+=15; -#else - sum += abs((int)*p1 - (int)*p2); - p1++; - p2++; -#endif - } - } - /* fclose(pic1); - fclose(pic2); - */ - return sum/((double) effectWidth * effectHeight * bytesPerPixel); -} - -/** - compares a small part of two given images - and returns the average absolute difference. - Field center, size and shift have to be chosen, - so that no clipping is required - - \param field Field specifies position(center) and size of subimage - \param d_x shift in x direction - \param d_y shift in y direction -*/ -double compareSubImg(unsigned char* const I1, unsigned char* const I2, - const Field* field, - int width, int height, int bytesPerPixel, int d_x, int d_y) -{ - int k, j; - unsigned char* p1 = NULL; - unsigned char* p2 = NULL; - int s2 = field->size / 2; - double sum=0.0; - - p1=I1 + ((field->x - s2) + (field->y - s2)*width)*bytesPerPixel; - - p2=I2 + ((field->x - s2 + d_x) + (field->y - s2 + d_y)*width)*bytesPerPixel; - // TODO: use some mmx or sse stuff here -#ifdef USE_SSE2 - __m128i A,B,C,D,E; -#endif - for (j = 0; j < field->size; j++){ -#ifdef USE_SSE2 - for (k = 0; k < (field->size * bytesPerPixel) - 16 ; k++) { - A= _mm_loadu_si128((__m128i*)p1); //load unaligned data - B= _mm_loadu_si128((__m128i*)p2); - C= _mm_sad_epu8(A, B);//abd diff stored in 2 64 byte values - D = _mm_srli_si128(C, 8); // shift value 8 byte right - E = _mm_add_epi32(C, D); // add the 2 values (sum of all diffs) - sum+= _mm_cvtsi128_si32(E); //convert _m128i to int - - p1+=16; - p2+=16; - k+=15; -#else - for (k = 0; k < (field->size * bytesPerPixel); k++) { - sum += abs((int)*p1 - (int)*p2); - p1++; - p2++; -#endif - } - p1 += ((width - field->size) * bytesPerPixel); - p2 += ((width - field->size) * bytesPerPixel); - } - return sum/((double) field->size *field->size* bytesPerPixel); -} - -/** \see contrastSubImg called with bytesPerPixel=1*/ -double contrastSubImgYUV(StabData* sd, const Field* field){ - return contrastSubImg(sd->curr,field,sd->width,sd->height,1); -} - -/** - \see contrastSubImg three times called with bytesPerPixel=3 - for all channels - */ -double contrastSubImgRGB(StabData* sd, const Field* field){ - unsigned char* const I = sd->curr; - return ( contrastSubImg(I, field,sd->width,sd->height,3) - + contrastSubImg(I+1,field,sd->width,sd->height,3) - + contrastSubImg(I+2,field,sd->width,sd->height,3))/3; -} - -/** - calculates Michelson-contrast in the given small part of the given image - - \param I pointer to framebuffer - \param field Field specifies position(center) and size of subimage - \param width width of frame - \param height height of frame - \param bytesPerPixel calc contrast for only for first channel -*/ -double contrastSubImg(unsigned char* const I, const Field* field, - int width, int height, int bytesPerPixel) -{ -#if USE_SSE2 - int k, j; - int s2 = field->size / 2; - __m128i mini = _mm_set_epi64(_mm_set1_pi8(255), _mm_set1_pi8(255)); - __m128i maxi = _mm_set_epi64(_mm_set1_pi8(0) , _mm_set1_pi8(0)); - unsigned char* p = I + ((field->x - s2) + (field->y - s2)*width)*bytesPerPixel; - __m128i A; - for (j = 0; j < field->size; j++){ - for (k = 0; k < (field->size * bytesPerPixel)-16 ; k++) { - A= _mm_loadu_si128((__m128i*)p); //load unaligned data - - maxi = _mm_max_epu8(A,maxi); - mini = _mm_min_epu8(A,mini); - p+=16; - k+=15; - } - p += (width - field->size) * bytesPerPixel; - } - int max=0; - union { - __m128i m; - uint8_t t[16]; - } m; - m.m=maxi; - for (j=0;j<16;j++) { - if (m.t[j] >max) - max=m.t[j]; - } - int min=255; - m.m=mini; - for (j=0;j<16;j++) { - if (m.t[j] size / 2; - unsigned char mini = 255; - unsigned char maxi = 0; - p = I + ((field->x - s2) + (field->y - s2)*width)*bytesPerPixel; - // TODO: use some mmx or sse stuff here - - for (j = 0; j < field->size; j++){ - for (k = 0; k < field->size * bytesPerPixel; k++) { - mini = (mini < *p) ? mini : *p; - maxi = (maxi > *p) ? maxi : *p; - p += bytesPerPixel; - } - p += (width - field->size) * bytesPerPixel; - } - return (maxi-mini)/(maxi+mini+0.1); // +0.1 to avoid division by 0 -#endif -} - -/** tries to register current frame onto previous frame. - This is the most simple algorithm: - shift images to all possible positions and calc summed error - Shift with minimal error is selected. -*/ -Transform calcShiftRGBSimple(StabData* sd) -{ - int x = 0, y = 0; - int i, j; - double minerror = 1e20; - for (i = -sd->maxshift; i <= sd->maxshift; i++) { - for (j = -sd->maxshift; j <= sd->maxshift; j++) { - double error = compareImg(sd->curr, sd->prev, - sd->width, sd->height, 3, i, j); - if (error < minerror) { - minerror = error; - x = i; - y = j; - } - } - } - return new_transform(x, y, 0, 0, 0); -} - - -/** tries to register current frame onto previous frame. - (only the luminance is used) - This is the most simple algorithm: - shift images to all possible positions and calc summed error - Shift with minimal error is selected. -*/ -Transform calcShiftYUVSimple(StabData* sd) -{ - int x = 0, y = 0; - int i, j; - unsigned char *Y_c, *Y_p;// , *Cb, *Cr; -#ifdef STABVERBOSE - FILE *f = NULL; - char buffer[32]; - tc_snprintf(buffer, sizeof(buffer), "f%04i.dat", sd->t); - f = fopen(buffer, "w"); - fprintf(f, "# splot \"%s\"\n", buffer); -#endif - - // we only use the luminance part of the image - Y_c = sd->curr; - // Cb_c = sd->curr + sd->width*sd->height; - //Cr_c = sd->curr + 5*sd->width*sd->height/4; - Y_p = sd->prev; - //Cb_p = sd->prev + sd->width*sd->height; - //Cr_p = sd->prev + 5*sd->width*sd->height/4; - - double minerror = 1e20; - for (i = -sd->maxshift; i <= sd->maxshift; i++) { - for (j = -sd->maxshift; j <= sd->maxshift; j++) { - double error = compareImg(Y_c, Y_p, - sd->width, sd->height, 1, i, j); -#ifdef STABVERBOSE - fprintf(f, "%i %i %f\n", i, j, error); -#endif - if (error < minerror) { - minerror = error; - x = i; - y = j; - } - } - } -#ifdef STABVERBOSE - fclose(f); - tc_log_msg(MOD_NAME, "Minerror: %f\n", minerror); -#endif - return new_transform(x, y, 0, 0, 0); -} - - - -/* calculates rotation angle for the given transform and - * field with respect to the given center-point - */ -double calcAngle(StabData* sd, Field* field, Transform* t, - int center_x, int center_y) -{ - // we better ignore fields that are to close to the rotation center - if (abs(field->x - center_x) + abs(field->y - center_y) < sd->maxshift) { - return 0; - } else { - // double r = sqrt(field->x*field->x + field->y*field->y); - double a1 = atan2(field->y - center_y, field->x - center_x); - double a2 = atan2(field->y - center_y + t->y, - field->x - center_x + t->x); - double diff = a2 - a1; - return (diff>M_PI) ? diff - 2*M_PI - : ( (diff<-M_PI) ? diff + 2*M_PI : diff); - } -} - - -/* calculates the optimal transformation for one field in YUV frames - * (only luminance) - */ -Transform calcFieldTransYUV(StabData* sd, const Field* field, int fieldnum) -{ - Transform t = null_transform(); - unsigned char *Y_c = sd->curr, *Y_p = sd->prev; - // we only use the luminance part of the image - int i, j; - -/* // check contrast in sub image */ -/* double contr = contrastSubImg(Y_c, field, sd->width, sd->height, 1); */ -/* if(contr < sd->contrast_threshold) { */ -/* t.extra=-1; */ -/* return t; */ -/* } */ -#ifdef STABVERBOSE - // printf("%i %i %f\n", sd->t, fieldnum, contr); - FILE *f = NULL; - char buffer[32]; - snprintf(buffer, sizeof(buffer), "f%04i_%02i.dat", sd->t, fieldnum); - f = fopen(buffer, "w"); - fprintf(f, "# splot \"%s\"\n", buffer); -#endif - - double minerror = 1e10; - double error = 1e10; - for (i = -sd->maxshift; i <= sd->maxshift; i += sd->stepsize) { - for (j = -sd->maxshift; j <= sd->maxshift; j += sd->stepsize) { - error = compareSubImg(Y_c, Y_p, field, - sd->width, sd->height, 1, i, j); -#ifdef STABVERBOSE - fprintf(f, "%i %i %f\n", i, j, error); -#endif - if (error < minerror) { - minerror = error; - t.x = i; - t.y = j; - } - } - } - - if (sd->stepsize > 1) { // make fine grain check around the best match - int r = sd->stepsize - 1; - for (i = t.x - r; i <= t.x + r; i += 1) { - for (j = -t.y - r; j <= t.y + r; j += 1) { - if (i == t.x && j == t.y) - continue; //no need to check this since already done - error = compareSubImg(Y_c, Y_p, field, - sd->width, sd->height, 1, i, j); -#ifdef STABVERBOSE - fprintf(f, "%i %i %f\n", i, j, error); -#endif - if (error < minerror){ - minerror = error; - t.x = i; - t.y = j; - } - } - } - } -#ifdef STABVERBOSE - fclose(f); - mlt_log_debug ( "Minerror: %f\n", minerror); -#endif - - if (!sd->allowmax && fabs(t.x) == sd->maxshift) { -#ifdef STABVERBOSE - mlt_log_debug ( "maximal x shift "); -#endif - t.x = 0; - } - if (!sd->allowmax && fabs(t.y) == sd->maxshift) { -#ifdef STABVERBOSE - mlt_log_debug ("maximal y shift "); -#endif - t.y = 0; - } - return t; -} - -/* calculates the optimal transformation for one field in RGB - * slower than the YUV version because it uses all three color channels - */ -Transform calcFieldTransRGB(StabData* sd, const Field* field, int fieldnum) -{ - Transform t = null_transform(); - unsigned char *I_c = sd->curr, *I_p = sd->prev; - int i, j; - - double minerror = 1e20; - for (i = -sd->maxshift; i <= sd->maxshift; i += 2) { - for (j=-sd->maxshift; j <= sd->maxshift; j += 2) { - double error = compareSubImg(I_c, I_p, field, - sd->width, sd->height, 3, i, j); - if (error < minerror) { - minerror = error; - t.x = i; - t.y = j; - } - } - } - for (i = t.x - 1; i <= t.x + 1; i += 2) { - for (j = -t.y - 1; j <= t.y + 1; j += 2) { - double error = compareSubImg(I_c, I_p, field, - sd->width, sd->height, 3, i, j); - if (error < minerror) { - minerror = error; - t.x = i; - t.y = j; - } - } - } - if (!sd->allowmax && fabs(t.x) == sd->maxshift) { - t.x = 0; - } - if (!sd->allowmax && fabs(t.y) == sd->maxshift) { - t.y = 0; - } - return t; -} - -/* compares contrast_idx structures respect to the contrast - (for sort function) -*/ -int cmp_contrast_idx(const void *ci1, const void* ci2) -{ - double a = ((contrast_idx*)ci1)->contrast; - double b = ((contrast_idx*)ci2)->contrast; - return a < b ? 1 : ( a > b ? -1 : 0 ); -} - -/* select only the best 'maxfields' fields - first calc contrasts then select from each part of the - frame a some fields -*/ -tlist* selectfields(StabData* sd, contrastSubImgFunc contrastfunc) -{ - int i,j; - tlist* goodflds = tlist_new(0); - contrast_idx *ci = malloc(sizeof(contrast_idx) * sd->field_num); - - // we split all fields into row+1 segments and take from each segment - // the best fields - int numsegms = (sd->field_rows+1); - int segmlen = sd->field_num/(sd->field_rows+1)+1; - // split the frame list into rows+1 segments - contrast_idx *ci_segms = malloc(sizeof(contrast_idx) * sd->field_num); - int remaining = 0; - // calculate contrast for each field - for (i = 0; i < sd->field_num; i++) { - ci[i].contrast = contrastfunc(sd, &sd->fields[i]); - ci[i].index=i; - if(ci[i].contrast < sd->contrast_threshold) ci[i].contrast = 0; - // else printf("%i %lf\n", ci[i].index, ci[i].contrast); - } - - memcpy(ci_segms, ci, sizeof(contrast_idx) * sd->field_num); - // get best fields from each segment - for(i=0; i sd->field_num ? sd->field_num : endindex; - //printf("Segment: %i: %i-%i\n", i, startindex, endindex); - - // sort within segment - qsort(ci_segms+startindex, endindex-startindex, - sizeof(contrast_idx), cmp_contrast_idx); - // take maxfields/numsegms - for(j=0; jmaxfields/numsegms; j++){ - if(startindex+j >= endindex) continue; - // printf("%i %lf\n", ci_segms[startindex+j].index, - // ci_segms[startindex+j].contrast); - if(ci_segms[startindex+j].contrast > 0){ - tlist_append(goodflds, &ci[ci_segms[startindex+j].index],sizeof(contrast_idx)); - // don't consider them in the later selection process - ci_segms[startindex+j].contrast=0; - } - } - } - // check whether enough fields are selected - // printf("Phase2: %i\n", tc_list_size(goodflds)); - remaining = sd->maxfields - tlist_size(goodflds); - if(remaining > 0){ - // take the remaining from the leftovers - qsort(ci_segms, sd->field_num, - sizeof(contrast_idx), cmp_contrast_idx); - for(j=0; j < remaining; j++){ - if(ci_segms[j].contrast > 0){ - tlist_append(goodflds, &ci_segms[j], sizeof(contrast_idx)); - } - } - } - // printf("Ende: %i\n", tc_list_size(goodflds)); - free(ci); - free(ci_segms); - return goodflds; -} - - - -/* tries to register current frame onto previous frame. - * Algorithm: - * check all fields for vertical and horizontal transformation - * use minimal difference of all possible positions - * discards fields with low contrast - * select maxfields field according to their contrast - * calculate shift as cleaned mean of all remaining fields - * calculate rotation angle of each field in respect to center of fields - * after shift removal - * calculate rotation angle as cleaned mean of all angles - * compensate for possibly off-center rotation -*/ -Transform calcTransFields(StabData* sd, calcFieldTransFunc fieldfunc, - contrastSubImgFunc contrastfunc) -{ - Transform* ts = malloc(sizeof(Transform) * sd->field_num); - Field** fs = malloc(sizeof(Field*) * sd->field_num); - double *angles = malloc(sizeof(double) * sd->field_num); - int i, index=0, num_trans; - Transform t; -#ifdef STABVERBOSE - FILE *f = NULL; - char buffer[32]; - tc_snprintf(buffer, sizeof(buffer), "k%04i.dat", sd->t); - f = fopen(buffer, "w"); - fprintf(f, "# plot \"%s\" w l, \"\" every 2:1:0\n", buffer); -#endif - - - tlist* goodflds = selectfields(sd, contrastfunc); - - // use all "good" fields and calculate optimal match to previous frame - contrast_idx* f; - while((f = (contrast_idx*)tlist_pop(goodflds,0) ) != 0){ - int i = f->index; - t = fieldfunc(sd, &sd->fields[i], i); // e.g. calcFieldTransYUV -#ifdef STABVERBOSE - fprintf(f, "%i %i\n%f %f %i\n \n\n", sd->fields[i].x, sd->fields[i].y, - sd->fields[i].x + t.x, sd->fields[i].y + t.y, t.extra); -#endif - if (t.extra != -1){ // ignore if extra == -1 (unused at the moment) - ts[index] = t; - fs[index] = sd->fields+i; - index++; - } - } - tlist_fini(goodflds); - - t = null_transform(); - num_trans = index; // amount of transforms we actually have - if (num_trans < 1) { - printf( "too low contrast! No field remains.\n" - "(no translations are detected in frame %i)", sd->t); - free(ts); - free(fs); - free(angles); - return t; - } - - int center_x = 0; - int center_y = 0; - // calc center point of all remaining fields - for (i = 0; i < num_trans; i++) { - center_x += fs[i]->x; - center_y += fs[i]->y; - } - center_x /= num_trans; - center_y /= num_trans; - - if (sd->show){ // draw fields and transforms into frame. - // this has to be done one after another to handle possible overlap - if (sd->show > 1) { - for (i = 0; i < num_trans; i++) - drawFieldScanArea(sd, fs[i], &ts[i]); - } - for (i = 0; i < num_trans; i++) - drawField(sd, fs[i], &ts[i]); - for (i = 0; i < num_trans; i++) - drawFieldTrans(sd, fs[i], &ts[i]); - } - /* median over all transforms - t= median_xy_transform(ts, sd->field_num);*/ - // cleaned mean - t = cleanmean_xy_transform(ts, num_trans); - - // subtract avg - for (i = 0; i < num_trans; i++) { - ts[i] = sub_transforms(&ts[i], &t); - } - // figure out angle - if (sd->field_num < 6) { - // the angle calculation is inaccurate for 5 and less fields - t.alpha = 0; - } else { - for (i = 0; i < num_trans; i++) { - angles[i] = calcAngle(sd, fs[i], &ts[i], center_x, center_y); - } - double min,max; - t.alpha = -cleanmean(angles, num_trans, &min, &max); - if(max-min>sd->maxanglevariation){ - t.alpha=0; - printf( "too large variation in angle(%f)\n", - max-min); - } - } - - // compensate for off-center rotation - double p_x = (center_x - sd->width/2); - double p_y = (center_y - sd->height/2); - t.x += (cos(t.alpha)-1)*p_x - sin(t.alpha)*p_y; - t.y += sin(t.alpha)*p_x + (cos(t.alpha)-1)*p_y; - -#ifdef STABVERBOSE - fclose(f); -#endif - free(ts); - free(fs); - free(angles); - return t; -} - -/** draws the field scanning area */ -void drawFieldScanArea(StabData* sd, const Field* field, const Transform* t) -{ - if (sd->pixelformat != mlt_image_yuv420p) { - mlt_log_warning (NULL, "format not usable\n"); - return; - } - drawBox(sd->curr, sd->width, sd->height, 1, field->x, field->y, - field->size+2*sd->maxshift, field->size+2*sd->maxshift, 80); -} - -/** draws the field */ -void drawField(StabData* sd, const Field* field, const Transform* t) -{ - if (sd->pixelformat != mlt_image_yuv420p){ - mlt_log_warning (NULL, "format not usable\n"); - return; - } - drawBox(sd->curr, sd->width, sd->height, 1, field->x, field->y, - field->size, field->size, t->extra == -1 ? 100 : 40); -} - -/** draws the transform data of this field */ -void drawFieldTrans(StabData* sd, const Field* field, const Transform* t) -{ - if (sd->pixelformat != mlt_image_yuv420p){ - mlt_log_warning (NULL, "format not usable\n"); - return; - } - drawBox(sd->curr, sd->width, sd->height, 1, - field->x, field->y, 5, 5, 128); // draw center - drawBox(sd->curr, sd->width, sd->height, 1, - field->x + t->x, field->y + t->y, 8, 8, 250); // draw translation -} - -/** - * draws a box at the given position x,y (center) in the given color - (the same for all channels) - */ -void drawBox(unsigned char* I, int width, int height, int bytesPerPixel, - int x, int y, int sizex, int sizey, unsigned char color){ - - unsigned char* p = NULL; - int j,k; - p = I + ((x - sizex/2) + (y - sizey/2)*width)*bytesPerPixel; - for (j = 0; j < sizey; j++){ - for (k = 0; k < sizex * bytesPerPixel; k++) { - *p = color; - p++; - } - p += (width - sizex) * bytesPerPixel; - } -} - -struct iterdata { - FILE *f; - int counter; -}; - -/*************************************************************************/ - -/* Module interface routines and data. */ - -/*************************************************************************/ - -/* - * stabilize_configure: Configure this instance of the module. See - * tcmodule-data.h for function details. - */ -int stabilize_configure(StabData* instance -/*const char *options, - int pixelfmt */ - /*TCModuleExtraData *xdata[]*/) -{ - StabData *sd = instance; - /* sd->framesize = sd->vob->im_v_width * MAX_PLANES * - sizeof(char) * 2 * sd->vob->im_v_height * 2; */ - /*TODO sd->framesize = sd->vob->im_v_size; */ - sd->prev = calloc(1,sd->framesize); - sd->grayimage = calloc(1,sd->width*sd->height); - - if (!sd->prev || !sd->grayimage) { - printf( "malloc failed"); - return -1; - } - sd->currcopy = 0; - sd->hasSeenOneFrame = 0; - sd->transs = 0; - sd->allowmax = 0; - sd->field_size = MIN(sd->width, sd->height)/12; - sd->maxanglevariation = 1; - - sd->shakiness = MIN(10,MAX(1,sd->shakiness)); - sd->accuracy = MAX(sd->shakiness,MIN(15,MAX(1,sd->accuracy))); - if (1) { - mlt_log_debug (NULL, "Image Stabilization Settings:\n"); - mlt_log_debug (NULL, " shakiness = %d\n", sd->shakiness); - mlt_log_debug (NULL, " accuracy = %d\n", sd->accuracy); - mlt_log_debug (NULL, " stepsize = %d\n", sd->stepsize); - mlt_log_debug (NULL, " algo = %d\n", sd->algo); - mlt_log_debug (NULL, " mincontrast = %f\n", sd->contrast_threshold); - mlt_log_debug (NULL, " show = %d\n", sd->show); - } - -#ifndef USE_SSE2 - mlt_log_info(NULL,"No SSE2 support enabled, this will slow down a lot\n"); -#endif - // shift and size: shakiness 1: height/40; 10: height/4 - sd->maxshift = MIN(sd->width, sd->height)*sd->shakiness/40; - sd->field_size = MIN(sd->width, sd->height)*sd->shakiness/40; - - mlt_log_debug ( NULL, "Fieldsize: %i, Maximal translation: %i pixel\n", - sd->field_size, sd->maxshift); - if (sd->algo==1) { - // initialize measurement fields. field_num is set here. - if (!initFields(sd)) { - return -1; - } - sd->maxfields = (sd->accuracy) * sd->field_num / 15; - mlt_log_debug ( NULL, "Number of used measurement fields: %i out of %i\n", - sd->maxfields, sd->field_num); - } - if (sd->show){ - sd->currcopy = calloc(1,sd->framesize); - } - - /* load unsharp filter to smooth the frames. This allows larger stepsize.*/ - char unsharp_param[128]; - int masksize = MIN(13,sd->stepsize*1.8); // only works up to 13. - sprintf(unsharp_param,"luma=-1:luma_matrix=%ix%i:pre=1", - masksize, masksize); - return 0; -} - - -/** - * stabilize_filter_video: performs the analysis of subsequent frames - * See tcmodule-data.h for function details. - */ - -int stabilize_filter_video(StabData* instance, - unsigned char *frame,mlt_image_format pixelformat) -{ - StabData *sd = instance; - sd->pixelformat=pixelformat; - int l=sd->width*sd->height; - unsigned char* tmpgray=sd->grayimage; - if (pixelformat == mlt_image_yuv422){ - while(l--){ - *tmpgray++=*frame++; - frame++; - }; - } - - if(sd->show) { // save the buffer to restore at the end for prev - if (pixelformat == mlt_image_yuv420p){ - memcpy(sd->currcopy, sd->grayimage, sd->framesize); - } - } - if (sd->hasSeenOneFrame) { - sd->curr = sd->grayimage; - if (pixelformat == mlt_image_rgb24) { - if (sd->algo == 0) - addTrans(sd, calcShiftRGBSimple(sd)); - else if (sd->algo == 1) - addTrans(sd, calcTransFields(sd, calcFieldTransRGB, - contrastSubImgRGB)); - } else if (pixelformat == mlt_image_yuv420p ) { - if (sd->algo == 0) - addTrans(sd, calcShiftYUVSimple(sd)); - else if (sd->algo == 1) - addTrans(sd, calcTransFields(sd, calcFieldTransYUV, - contrastSubImgYUV)); - } else if (pixelformat == mlt_image_yuv422 ) { - if (sd->algo == 0) - addTrans(sd, calcShiftYUVSimple(sd)); - else if (sd->algo == 1) - addTrans(sd, calcTransFields(sd, calcFieldTransYUV, - contrastSubImgYUV)); - } else { - mlt_log_warning (NULL,"unsupported Codec: %i\n", - pixelformat); - return 0; - } - } else { - sd->hasSeenOneFrame = 1; - addTrans(sd, null_transform()); - } - - if(!sd->show) { // copy current frame to prev for next frame comparison - memcpy(sd->prev, sd->grayimage, sd->framesize); - } else { // use the copy because we changed the original frame - memcpy(sd->prev, sd->currcopy, sd->framesize); - } - sd->t++; - return 0; -} - -/** - * stabilize_stop: Reset this instance of the module. See tcmodule-data.h - * for function details. - */ - -int stabilize_stop(StabData* instance) -{ - StabData *sd = instance; - free(sd->prev); - sd->prev = NULL; - free(sd->grayimage); - sd->grayimage=NULL; - return 0; -} - - - diff --git a/src/modules/videostab/stabilize.h b/src/modules/videostab/stabilize.h deleted file mode 100644 index 8e7ac96c7..000000000 --- a/src/modules/videostab/stabilize.h +++ /dev/null @@ -1,186 +0,0 @@ -/* - * filter_stabilize.c - * - * Copyright (C) Georg Martius - June 2007 - * georg dot martius at web dot de - * - * This file is part of transcode, a video stream processing tool - * - * transcode 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, or (at your option) - * any later version. - * - * transcode 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 GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -/* Typical call: - * transcode -V -J stabilize=shakiness=5:show=1,preview - * -i inp.mpeg -y null,null -o dummy - * all parameters are optional -*/ - -#define MOD_NAME "filter_stabilize.so" -#define MOD_VERSION "v0.75 (2010-04-07)" -#define MOD_CAP "extracts relative transformations of \n\ - subsequent frames (used for stabilization together with the\n\ - transform filter in a second pass)" -#define MOD_AUTHOR "Georg Martius" - -/* Ideas: - - Try OpenCL/Cuda, this should work great - - use smoothing on the frames and then use gradient decent! - - stepsize could be adapted (maybe to check only one field with large - stepsize and use the maximally required for the other fields -*/ - -#define MOD_FEATURES \ - TC_MODULE_FEATURE_FILTER|TC_MODULE_FEATURE_VIDEO -#define MOD_FLAGS \ - TC_MODULE_FLAG_RECONFIGURABLE | TC_MODULE_FLAG_DELAY - - -#include "transform.h" - -#include -#include -#include -#include "tlist.h" -#include - -/* if defined we are very verbose and generate files to analyse - * this is really just for debugging and development */ -// #define STABVERBOSE - - -typedef struct _field { - int x; // middle position x - int y; // middle position y - int size; // size of field -} Field; - -// structure that contains the contrast and the index of a field -typedef struct _contrast_idx { - double contrast; - int index; -} contrast_idx; - -/* private date structure of this filter*/ -typedef struct _stab_data { - int framesize; // size of frame buffer in bytes (prev) - unsigned char* curr; // current frame buffer (only pointer) - unsigned char* currcopy; // copy of the current frame needed for drawing - unsigned char* prev; // frame buffer for last frame (copied) - unsigned char* grayimage; // frame buffer for last frame (copied) - short hasSeenOneFrame; // true if we have a valid previous frame - - int width, height; - mlt_image_format pixelformat; - - /* list of transforms*/ - //TCList* transs; - tlist* transs; - - Field* fields; - - - /* Options */ - /* maximum number of pixels we expect the shift of subsequent frames */ - int maxshift; - int stepsize; // stepsize of field transformation detection - int allowmax; // 1 if maximal shift is allowed - int algo; // algorithm to use - int field_num; // number of measurement fields - int maxfields; // maximum number of fields used (selected by contrast) - int field_size; // size = min(sd->width, sd->height)/10; - int field_rows; // number of rows - /* if 1 and 2 then the fields and transforms are shown in the frames */ - int show; - /* measurement fields with lower contrast are discarded */ - double contrast_threshold; - /* maximal difference in angles of fields */ - double maxanglevariation; - /* meta parameter for maxshift and fieldsize between 1 and 10 */ - int shakiness; - int accuracy; // meta parameter for number of fields between 1 and 10 - - int t; - - char conf_str[1024]; -} StabData; - -/* type for a function that calculates the transformation of a certain field - */ -typedef Transform (*calcFieldTransFunc)(StabData*, const Field*, int); - -/* type for a function that calculates the contrast of a certain field - */ -typedef double (*contrastSubImgFunc)(StabData* sd, const Field* field); - -static const char stabilize_help[] = "" - "Overview:\n" - " Generates a file with relative transform information\n" - " (translation, rotation) about subsequent frames." - " See also transform.\n" - "Options\n" - " 'result' path to the file used to write the transforms\n" - " (def:inputfile.stab)\n" - " 'shakiness' how shaky is the video and how quick is the camera?\n" - " 1: little (fast) 10: very strong/quick (slow) (def: 4)\n" - " 'accuracy' accuracy of detection process (>=shakiness)\n" - " 1: low (fast) 15: high (slow) (def: 4)\n" - " 'stepsize' stepsize of search process, region around minimum \n" - " is scanned with 1 pixel resolution (def: 6)\n" - " 'algo' 0: brute force (translation only);\n" - " 1: small measurement fields (def)\n" - " 'mincontrast' below this contrast a field is discarded (0-1) (def: 0.3)\n" - " 'show' 0: draw nothing (def); 1,2: show fields and transforms\n" - " in the resulting frames. Consider the 'preview' filter\n" - " 'help' print this help message\n"; - -int initFields(StabData* sd); -double compareImg(unsigned char* I1, unsigned char* I2, - int width, int height, int bytesPerPixel, int d_x, int d_y); -double compareSubImg(unsigned char* const I1, unsigned char* const I2, - const Field* field, - int width, int height, int bytesPerPixel,int d_x,int d_y); -double contrastSubImgYUV(StabData* sd, const Field* field); -double contrastSubImgRGB(StabData* sd, const Field* field); -double contrastSubImg(unsigned char* const I, const Field* field, - int width, int height, int bytesPerPixel); -int cmp_contrast_idx(const void *ci1, const void* ci2); -tlist* selectfields(StabData* sd, contrastSubImgFunc contrastfunc); - -Transform calcShiftRGBSimple(StabData* sd); -Transform calcShiftYUVSimple(StabData* sd); -double calcAngle(StabData* sd, Field* field, Transform* t, - int center_x, int center_y); -Transform calcFieldTransYUV(StabData* sd, const Field* field, - int fieldnum); -Transform calcFieldTransRGB(StabData* sd, const Field* field, - int fieldnum); -Transform calcTransFields(StabData* sd, calcFieldTransFunc fieldfunc, - contrastSubImgFunc contrastfunc); - - -void drawFieldScanArea(StabData* sd, const Field* field, const Transform* t); -void drawField(StabData* sd, const Field* field, const Transform* t); -void drawFieldTrans(StabData* sd, const Field* field, const Transform* t); -void drawBox(unsigned char* I, int width, int height, int bytesPerPixel, - int x, int y, int sizex, int sizey, unsigned char color); -void addTrans(StabData* sd, Transform sl); - -int stabilize_configure(StabData* instance); -int stabilize_stop(StabData* instance); - -int stabilize_filter_video(StabData* instance, unsigned char *frame,mlt_image_format imageformat); - - diff --git a/src/modules/videostab/tlist.c b/src/modules/videostab/tlist.c deleted file mode 100644 index 2746dc3fd..000000000 --- a/src/modules/videostab/tlist.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "tlist.h" -#include -#include - -tlist* tlist_new(int size){ - tlist* t=malloc(sizeof(tlist)); - memset(t,0,sizeof(tlist)); - return t; -} - -void tlist_append(tlist* t,void* data,int size){ - tlist* next=tlist_new(0); - tlist* pos=t; - while (pos && pos->next) { - pos=pos->next; - } - - pos->data=malloc(size); - memcpy(pos->data,data,size); - pos->next=next; -} -int tlist_size(tlist* t){ - int ret=0; - tlist* pos=t; - while (pos && pos->next && pos->data) { - pos=pos->next ; - ret++; - }; - return ret; -} -void* tlist_pop(tlist* t,int at){ - int ret=0; - tlist* pos=t; - /*if (pos && !pos->next ){ - return pos->data; - }*/ - while (pos && pos->next) { - if (ret==at){ - tlist* n=pos->next; - pos->data=n->data; - pos->next=n->next; - return pos->data; - } - pos=pos->next ; - ret++; - }; - return NULL; -} -void tlist_fini(tlist* list){ - tlist* head=list; - while (head){ - free(head->data); - tlist *del=head; - head=head->next; - free(del); - } -} diff --git a/src/modules/videostab/tlist.h b/src/modules/videostab/tlist.h deleted file mode 100644 index 3ba1b995c..000000000 --- a/src/modules/videostab/tlist.h +++ /dev/null @@ -1,18 +0,0 @@ - - -#ifndef __TLIST__ -#define __TLIST__ - -typedef struct _tlist { - void* data; - void* next; -} tlist; - - -tlist* tlist_new(int size); -void tlist_append(tlist* t,void* data,int size); -int tlist_size(tlist* t); -void* tlist_pop(tlist* t,int at); -void tlist_fini(tlist* ); - -#endif diff --git a/src/modules/videostab/transform.c b/src/modules/videostab/transform.c deleted file mode 100644 index 14d04af5a..000000000 --- a/src/modules/videostab/transform.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * transform.c - * - * Copyright (C) Georg Martius - June 2007 - * - * This file is part of transcode, a video stream processing tool - * - * transcode 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, or (at your option) - * any later version. - * - * transcode 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 GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif -#include -#include -#include -#include "transform.h" - -/*********************************************************************** - * helper functions to create and operate with transforms. - * all functions are non-destructive - */ - -/* create an initialized transform*/ -Transform new_transform(double x, double y, double alpha, - double zoom, int extra) -{ - Transform t; - t.x = x; - t.y = y; - t.alpha = alpha; - t.zoom = zoom; - t.extra = extra; - return t; -} - -/* create a zero initialized transform*/ -Transform null_transform(void) -{ - return new_transform(0, 0, 0, 0, 0); -} - -/* adds two transforms */ -Transform add_transforms(const Transform* t1, const Transform* t2) -{ - Transform t; - t.x = t1->x + t2->x; - t.y = t1->y + t2->y; - t.alpha = t1->alpha + t2->alpha; - t.zoom = t1->zoom + t2->zoom; - t.extra = 0; - return t; -} - -/* like add_transform but with non-pointer signature */ -Transform add_transforms_(const Transform t1, const Transform t2) -{ - return add_transforms(&t1, &t2); -} - -/* subtracts two transforms */ -Transform sub_transforms(const Transform* t1, const Transform* t2) -{ - Transform t; - t.x = t1->x - t2->x; - t.y = t1->y - t2->y; - t.alpha = t1->alpha - t2->alpha; - t.zoom = t1->zoom - t2->zoom; - t.extra = 0; - return t; -} - -/* multiplies a transforms with a scalar */ -Transform mult_transform(const Transform* t1, double f) -{ - Transform t; - t.x = t1->x * f; - t.y = t1->y * f; - t.alpha = t1->alpha * f; - t.zoom = t1->zoom * f; - t.extra = 0; - return t; -} - -/* like mult_transform but with non-pointer signature */ -Transform mult_transform_(const Transform t1, double f) -{ - return mult_transform(&t1,f); -} - -/* compares a transform with respect to x (for sort function) */ -int cmp_trans_x(const void *t1, const void* t2) -{ - double a = ((Transform*)t1)->x; - double b = ((Transform*)t2)->x; - return a < b ? -1 : ( a > b ? 1 : 0 ); -} - -/* compares a transform with respect to y (for sort function) */ -int cmp_trans_y(const void *t1, const void* t2) -{ - double a = ((Transform*)t1)->y; - double b = ((Transform*)t2)->y; - return a < b ? -1 : ( a > b ? 1: 0 ); -} - -/* static int cmp_trans_alpha(const void *t1, const void* t2){ */ -/* double a = ((Transform*)t1)->alpha; */ -/* double b = ((Transform*)t2)->alpha; */ -/* return a < b ? -1 : ( a > b ? 1 : 0 ); */ -/* } */ - - -/* compares two double values (for sort function)*/ -int cmp_double(const void *t1, const void* t2) -{ - double a = *((double*)t1); - double b = *((double*)t2); - return a < b ? -1 : ( a > b ? 1 : 0 ); -} - -/** - * median_xy_transform: calulcates the median of an array - * of transforms, considering only x and y - * - * Parameters: - * transforms: array of transforms. - * len: length of array - * Return value: - * A new transform with x and y being the median of - * all transforms. alpha and other fields are 0. - * Preconditions: - * len>0 - * Side effects: - * None - */ -Transform median_xy_transform(const Transform* transforms, int len) -{ - Transform* ts = malloc(sizeof(Transform) * len); - Transform t; - memcpy(ts,transforms, sizeof(Transform)*len ); - int half = len/2; - qsort(ts, len, sizeof(Transform), cmp_trans_x); - t.x = len % 2 == 0 ? ts[half].x : (ts[half].x + ts[half+1].x)/2; - qsort(ts, len, sizeof(Transform), cmp_trans_y); - t.y = len % 2 == 0 ? ts[half].y : (ts[half].y + ts[half+1].y)/2; - t.alpha = 0; - t.zoom = 0; - t.extra = 0; - free(ts); - return t; -} - -/** - * cleanmean_xy_transform: calulcates the cleaned mean of an array - * of transforms, considering only x and y - * - * Parameters: - * transforms: array of transforms. - * len: length of array - * Return value: - * A new transform with x and y being the cleaned mean - * (meaning upper and lower pentile are removed) of - * all transforms. alpha and other fields are 0. - * Preconditions: - * len>0 - * Side effects: - * None - */ -Transform cleanmean_xy_transform(const Transform* transforms, int len) -{ - Transform* ts = malloc(sizeof(Transform) * len); - Transform t = null_transform(); - int i, cut = len / 5; - memcpy(ts, transforms, sizeof(Transform) * len); - qsort(ts,len, sizeof(Transform), cmp_trans_x); - for (i = cut; i < len - cut; i++){ // all but cutted - t.x += ts[i].x; - } - qsort(ts, len, sizeof(Transform), cmp_trans_y); - for (i = cut; i < len - cut; i++){ // all but cutted - t.y += ts[i].y; - } - free(ts); - return mult_transform(&t, 1.0 / (len - (2.0 * cut))); -} - - -/** - * calulcates the cleaned maximum and minimum of an array of transforms, - * considerung only x and y - * It cuts off the upper and lower x-th percentil - * - * Parameters: - * transforms: array of transforms. - * len: length of array - * percentil: the x-th percentil to cut off - * min: pointer to min (return value) - * max: pointer to max (return value) - * Return value: - * call by reference in min and max - * Preconditions: - * len>0, 0<=percentil<50 - * Side effects: - * only on min and max - */ -void cleanmaxmin_xy_transform(const Transform* transforms, int len, - int percentil, - Transform* min, Transform* max){ - Transform* ts = malloc(sizeof(Transform) * len); - int cut = len * percentil / 100; - memcpy(ts, transforms, sizeof(Transform) * len); - qsort(ts,len, sizeof(Transform), cmp_trans_x); - min->x = ts[cut].x; - max->x = ts[len-cut-1].x; - qsort(ts, len, sizeof(Transform), cmp_trans_y); - min->y = ts[cut].y; - max->y = ts[len-cut-1].y; - free(ts); -} - - -/** - * media: median of a double array - * - * Parameters: - * ds: array of values - * len: length of array - * Return value: - * the median value of the array - * Preconditions: len>0 - * Side effects: ds will be sorted! - */ -double median(double* ds, int len) -{ - int half=len/2; - qsort(ds,len, sizeof(double), cmp_double); - return len % 2 == 0 ? ds[half] : (ds[half] + ds[half+1])/2; -} - -/** - * mean: mean of a double array - * - * Parameters: - * ds: array of values - * len: length of array - * Return value: the mean value of the array - * Preconditions: len>0 - * Side effects: None - */ -double mean(const double* ds, int len) -{ - double sum=0; - int i = 0; - for (i = 0; i < len; i++) - sum += ds[i]; - return sum / len; -} - -/** - * cleanmean: mean with cutted upper and lower pentile - * - * Parameters: - * ds: array of values - * len: length of array - * len: length of array - * minimum: minimal value (after cleaning) if not NULL - * maximum: maximal value (after cleaning) if not NULL - * Return value: - * the mean value of the array without the upper - * and lower pentile (20% each) - * and lower pentile (20% each) - * and minimum and maximum without the pentiles - * Preconditions: len>0 - * Side effects: ds will be sorted! - */ -double cleanmean(double* ds, int len, double* minimum, double* maximum) -{ - int cut = len / 5; - double sum = 0; - int i = 0; - qsort(ds, len, sizeof(double), cmp_double); - for (i = cut; i < len - cut; i++) { // all but first and last - sum += ds[i]; - } - if (minimum) - *minimum = ds[cut]; - if (maximum) - *maximum = ds[len-cut-1]; - return sum / (len - (2.0 * cut)); -} - - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/src/modules/videostab/transform.h b/src/modules/videostab/transform.h deleted file mode 100644 index 0b959389a..000000000 --- a/src/modules/videostab/transform.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * transform.h - * - * Copyright (C) Georg Martius - June 2007 - * - * This file is part of transcode, a video stream processing tool - * - * transcode 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, or (at your option) - * any later version. - * - * transcode 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 GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ -#ifndef __TRANSFORM_H -#define __TRANSFORM_H - -#define DEFAULT_TRANS_FILE_NAME "transforms.dat" - -/* structure to hold information about frame transformations - x,y are translations, alpha is a rotation around the center in RAD, - zoom is a percentage to zoom in and - extra is for additional information like scene cut (unused) - */ -typedef struct _transform { - double x; - double y; - double alpha; - double zoom; - int extra; /* -1: ignore transform (only internal use); - 0 for normal trans; 1 for inter scene cut (unused) */ -} Transform; - -/* helper functions to create and operate with transforms. - * all functions are non-destructive - * the "_" version uses non-pointer Transforms. This is slower - * but useful when cascading calculations like - * add_transforms_(mult_transform(&t1, 5.0), &t2) - */ -Transform null_transform(void); -Transform new_transform(double x, double y, double alpha, - double zoom, int extra); -Transform add_transforms(const Transform* t1, const Transform* t2); -Transform add_transforms_(const Transform t1, const Transform t2); -Transform sub_transforms(const Transform* t1, const Transform* t2); -Transform mult_transform(const Transform* t1, double f); -Transform mult_transform_(const Transform t1, double f); - -/* compares a transform with respect to x (for sort function) */ -int cmp_trans_x(const void *t1, const void* t2); -/* compares a transform with respect to y (for sort function) */ -int cmp_trans_y(const void *t1, const void* t2); -/* static int cmp_trans_alpha(const void *t1, const void* t2); */ - -/* compares two double values (for sort function)*/ -int cmp_double(const void *t1, const void* t2); - -/* calculates the median of an array of transforms, - * considering only x and y - */ -Transform median_xy_transform(const Transform* transforms, int len); -/* median of a double array */ -double median(double* ds, int len); -/* mean of a double array */ -double mean(const double* ds, int len); -/* mean with cutted upper and lower pentile - * (min and max are optionally returned) - */ -double cleanmean(double* ds, int len, double* minimum, double* maximum); -/* calculates the cleaned mean of an array of transforms, - * considering only x and y - */ -Transform cleanmean_xy_transform(const Transform* transforms, int len); - -/* calculates the cleaned (cutting of x-th percentil) - * maximum and minimum of an array of transforms, - * considerung only x and y - */ -void cleanmaxmin_xy_transform(const Transform* transforms, int len, - int percentil, - Transform* min, Transform* max); - -/* helper functions */ - -/* optimized round function */ -inline static int myround(float x) { - if(x>0) - return x + 0.5; - else - return x - 0.5; -} - - -/* optimized floor function - This does not give the correct value for negative integer values like -1.0. In this case - it will produce -2.0. -*/ -inline static int myfloor(float x) { - if(x<0) - return x - 1; - else - return x; -} - - -#endif - -/* - * Local variables: - * c-file-style: "stroustrup" - * c-file-offsets: ((case-label . *) (statement-case-intro . *)) - * indent-tabs-mode: nil - * End: - * - * vim: expandtab shiftwidth=4: - */ diff --git a/src/modules/videostab/transform_image.c b/src/modules/videostab/transform_image.c deleted file mode 100644 index ff0710baa..000000000 --- a/src/modules/videostab/transform_image.c +++ /dev/null @@ -1,714 +0,0 @@ -/* - * filter_transform.c - * - * Copyright (C) Georg Martius - June 2007 - * georg dot martius at web dot de - * - * This file is part of transcode, a video stream processing tool - * - * transcode 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, or (at your option) - * any later version. - * - * transcode 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 GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Typical call: - * transcode -J transform -i inp.mpeg -y xdiv,tcaud inp_stab.avi - */ -#include "transform_image.h" -#include -#include -#include - -#define TC_MAX(a, b) (((a) > (b)) ?(a) :(b)) -#define TC_MIN(a, b) (((a) < (b)) ?(a) :(b)) -/* clamp x between a and b */ -#define TC_CLAMP(x, a, b) TC_MIN(TC_MAX((a), (x)), (b)) - - -static const char* interpoltypes[5] = {"No (0)", "Linear (1)", "Bi-Linear (2)", - "Quadratic (3)", "Bi-Cubic (4)"}; - -void (*interpolate)(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, - unsigned char def,unsigned char N, unsigned char channel) = 0; - -/** interpolateBiLinBorder: bi-linear interpolation function that also works at the border. - This is used by many other interpolation methods at and outsize the border, see interpolate */ -void interpolateBiLinBorder(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, - unsigned char def,unsigned char N, unsigned char channel) -{ - int x_f = myfloor(x); - int x_c = x_f+1; - int y_f = myfloor(y); - int y_c = y_f+1; - short v1 = PIXELN(img, x_c, y_c, width, height, N, channel, def); - short v2 = PIXELN(img, x_c, y_f, width, height, N, channel, def); - short v3 = PIXELN(img, x_f, y_c, width, height, N, channel, def); - short v4 = PIXELN(img, x_f, y_f, width, height, N, channel, def); - float s = (v1*(x - x_f)+v3*(x_c - x))*(y - y_f) + - (v2*(x - x_f) + v4*(x_c - x))*(y_c - y); - *rv = (unsigned char)s; -} - -/* taken from http://en.wikipedia.org/wiki/Bicubic_interpolation for alpha=-0.5 - in matrix notation: - a0-a3 are the neigthboring points where the target point is between a1 and a2 - t is the point of interpolation (position between a1 and a2) value between 0 and 1 - | 0, 2, 0, 0 | |a0| - |-1, 0, 1, 0 | |a1| - (1,t,t^2,t^3) | 2,-5, 4,-1 | |a2| - |-1, 3,-3, 1 | |a3| -*/ -static short bicub_kernel(float t, short a0, short a1, short a2, short a3){ - return (2*a1 + t*((-a0+a2) + t*((2*a0-5*a1+4*a2-a3) + t*(-a0+3*a1-3*a2+a3) )) ) / 2; -} - -/** interpolateBiCub: bi-cubic interpolation function using 4x4 pixel, see interpolate */ -void interpolateBiCub(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, unsigned char def,unsigned char N, unsigned char channel) -{ - // do a simple linear interpolation at the border - if (x < 1 || x >= width-2 || y < 1 || y >= height - 2) { - interpolateBiLinBorder(rv, x,y,img,width,height,def,N,channel); - } else { - int x_f = myfloor(x); - int y_f = myfloor(y); - float tx = x-x_f; - short v1 = bicub_kernel(tx, - PIXN(img, x_f-1, y_f-1, width, height, N, channel), - PIXN(img, x_f, y_f-1, width, height, N, channel), - PIXN(img, x_f+1, y_f-1, width, height, N, channel), - PIXN(img, x_f+2, y_f-1, width, height, N, channel)); - short v2 = bicub_kernel(tx, - PIXN(img, x_f-1, y_f, width, height, N, channel), - PIXN(img, x_f, y_f, width, height, N, channel), - PIXN(img, x_f+1, y_f, width, height, N, channel), - PIXN(img, x_f+2, y_f, width, height, N, channel)); - short v3 = bicub_kernel(tx, - PIXN(img, x_f-1, y_f+1, width, height, N, channel), - PIXN(img, x_f, y_f+1, width, height, N, channel), - PIXN(img, x_f+1, y_f+1, width, height, N, channel), - PIXN(img, x_f+2, y_f+1, width, height, N, channel)); - short v4 = bicub_kernel(tx, - PIXN(img, x_f-1, y_f+2, width, height, N, channel), - PIXN(img, x_f, y_f+2, width, height, N, channel), - PIXN(img, x_f+1, y_f+2, width, height, N, channel), - PIXN(img, x_f+2, y_f+2, width, height, N, channel)); - *rv = (unsigned char)bicub_kernel(y-y_f, v1, v2, v3, v4); - } -} - -/** interpolateSqr: bi-quatratic interpolation function, see interpolate */ -void interpolateSqr(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, unsigned char def,unsigned char N, unsigned char channel) -{ - if (x < 0 || x >= width-1 || y < 0 || y >= height-1) { - interpolateBiLinBorder(rv, x, y, img, width, height, def,N,channel); - } else { - int x_f = myfloor(x); - int x_c = x_f+1; - int y_f = myfloor(y); - int y_c = y_f+1; - short v1 = PIXN(img, x_c, y_c, width, height, N, channel); - short v2 = PIXN(img, x_c, y_f, width, height, N, channel); - short v3 = PIXN(img, x_f, y_c, width, height, N, channel); - short v4 = PIXN(img, x_f, y_f, width, height, N, channel); - float f1 = 1 - sqrt((x_c - x) * (y_c - y)); - float f2 = 1 - sqrt((x_c - x) * (y - y_f)); - float f3 = 1 - sqrt((x - x_f) * (y_c - y)); - float f4 = 1 - sqrt((x - x_f) * (y - y_f)); - float s = (v1*f1 + v2*f2 + v3*f3+ v4*f4)/(f1 + f2 + f3 + f4); - *rv = (unsigned char)s; - } -} - -/** interpolateBiLin: bi-linear interpolation function, see interpolate */ -void interpolateBiLin(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, - unsigned char def,unsigned char N, unsigned char channel) -{ - if (x < 0 || x >= width-1 || y < 0 || y >= height - 1) { - interpolateBiLinBorder(rv, x, y, img, width, height, def,N,channel); - } else { - int x_f = myfloor(x); - int x_c = x_f+1; - int y_f = myfloor(y); - int y_c = y_f+1; - short v1 = PIXN(img, x_c, y_c, width, height, N, channel); - short v2 = PIXN(img, x_c, y_f, width, height, N, channel); - short v3 = PIXN(img, x_f, y_c, width, height, N, channel); - short v4 = PIXN(img, x_f, y_f, width, height, N, channel); - float s = (v1*(x - x_f)+v3*(x_c - x))*(y - y_f) + - (v2*(x - x_f) + v4*(x_c - x))*(y_c - y); - *rv = (unsigned char)s; - } -} - - -/** interpolateLin: linear (only x) interpolation function, see interpolate */ -void interpolateLin(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, - unsigned char def,unsigned char N, unsigned char channel) -{ - int x_f = myfloor(x); - int x_c = x_f+1; - int y_n = myround(y); - float v1 = PIXELN(img, x_c, y_n, width, height, N, channel,def); - float v2 = PIXELN(img, x_f, y_n, width, height, N, channel,def); - float s = v1*(x - x_f) + v2*(x_c - x); - *rv = (unsigned char)s; -} - -/** interpolateZero: nearest neighbor interpolation function, see interpolate */ -void interpolateZero(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, unsigned char def,unsigned char N, unsigned char channel) -{ - int x_n = myround(x); - int y_n = myround(y); - *rv = (unsigned char) PIXELN(img, x_n, y_n, width, height, N,channel,def); -} - - -/** - * interpolateN: Bi-linear interpolation function for N channel image. - * - * Parameters: - * rv: destination pixel (call by reference) - * x,y: the source coordinates in the image img. Note this - * are real-value coordinates, that's why we interpolate - * img: source image - * width,height: dimension of image - * N: number of channels - * channel: channel number (0..N-1) - * def: default value if coordinates are out of range - * Return value: None - */ -void interpolateN(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, - unsigned char N, unsigned char channel, - unsigned char def) -{ - if (x < - 1 || x > width || y < -1 || y > height) { - *rv = def; - } else { - int x_f = myfloor(x); - int x_c = x_f+1; - int y_f = myfloor(y); - int y_c = y_f+1; - short v1 = PIXELN(img, x_c, y_c, width, height, N, channel, def); - short v2 = PIXELN(img, x_c, y_f, width, height, N, channel, def); - short v3 = PIXELN(img, x_f, y_c, width, height, N, channel, def); - short v4 = PIXELN(img, x_f, y_f, width, height, N, channel, def); - float s = (v1*(x - x_f)+v3*(x_c - x))*(y - y_f) + - (v2*(x - x_f) + v4*(x_c - x))*(y_c - y); - *rv = (unsigned char)s; - } -} - - -/** - * transformRGB: applies current transformation to frame - * Parameters: - * td: private data structure of this filter - * Return value: - * 0 for failure, 1 for success - * Preconditions: - * The frame must be in RGB format - */ -int transformRGB(TransformData* td) -{ - Transform t; - int x = 0, y = 0, z = 0; - unsigned char *D_1, *D_2; - t = td->trans[td->current_trans]; - - D_1 = td->src; - D_2 = td->dest; - float zm = 1.0-t.zoom/100; - float zcos_a = zm*cos(-t.alpha); // scaled cos - float zsin_a = zm*sin(-t.alpha); // scaled sin - float c_s_x = td->width_src/2.0; - float c_s_y = td->height_src/2.0; - float c_d_x = td->width_dest/2.0; - float c_d_y = td->height_dest/2.0; - - /* for each pixel in the destination image we calc the source - * coordinate and make an interpolation: - * p_d = c_d + M(p_s - c_s) + t - * where p are the points, c the center coordinate, - * _s source and _d destination, - * t the translation, and M the rotation matrix - * p_s = M^{-1}(p_d - c_d - t) + c_s - */ - /* All 3 channels */ - if (fabs(t.alpha) > td->rotation_threshhold || t.zoom != 0) { - for (x = 0; x < td->width_dest; x++) { - for (y = 0; y < td->height_dest; y++) { - float x_d1 = (x - c_d_x); - float y_d1 = (y - c_d_y); - float x_s = zcos_a * x_d1 - + zsin_a * y_d1 + c_s_x -t.x; - float y_s = -zsin_a * x_d1 - + zcos_a * y_d1 + c_s_y -t.y; - for (z = 0; z < 3; z++) { // iterate over colors - unsigned char* dest = &D_2[(x + y * td->width_dest)*3+z]; - interpolate(dest, x_s, y_s, D_1, - td->width_src, td->height_src, - td->crop ? 16 : *dest,3,z); - } - } - } - }else { - /* no rotation, just translation - *(also no interpolation, since no size change (so far) - */ - int round_tx = myround(t.x); - int round_ty = myround(t.y); - for (x = 0; x < td->width_dest; x++) { - for (y = 0; y < td->height_dest; y++) { - for (z = 0; z < 3; z++) { // iterate over colors - short p = PIXELN(D_1, x - round_tx, y - round_ty, - td->width_src, td->height_src, 3, z, -1); - if (p == -1) { - if (td->crop == 1) - D_2[(x + y * td->width_dest)*3+z] = 16; - } else { - D_2[(x + y * td->width_dest)*3+z] = (unsigned char)p; - } - } - } - } - } - return 1; -} - -/** - * transformYUV: applies current transformation to frame - * - * Parameters: - * td: private data structure of this filter - * Return value: - * 0 for failure, 1 for success - * Preconditions: - * The frame must be in YUV format - */ -int transformYUV(TransformData* td) -{ - Transform t; - int x = 0, y = 0; - unsigned char *Y_1, *Y_2, *Cb_1, *Cb_2, *Cr_1, *Cr_2; - t = td->trans[td->current_trans]; - - Y_1 = td->src; - Y_2 = td->dest; - Cb_1 = td->src + td->width_src * td->height_src; - Cb_2 = td->dest + td->width_dest * td->height_dest; - Cr_1 = td->src + 5*td->width_src * td->height_src/4; - Cr_2 = td->dest + 5*td->width_dest * td->height_dest/4; - float c_s_x = td->width_src/2.0; - float c_s_y = td->height_src/2.0; - float c_d_x = td->width_dest/2.0; - float c_d_y = td->height_dest/2.0; - - float z = 1.0-t.zoom/100; - float zcos_a = z*cos(-t.alpha); // scaled cos - float zsin_a = z*sin(-t.alpha); // scaled sin - - /* for each pixel in the destination image we calc the source - * coordinate and make an interpolation: - * p_d = c_d + M(p_s - c_s) + t - * where p are the points, c the center coordinate, - * _s source and _d destination, - * t the translation, and M the rotation and scaling matrix - * p_s = M^{-1}(p_d - c_d - t) + c_s - */ - /* Luminance channel */ - if (fabs(t.alpha) > td->rotation_threshhold || t.zoom != 0) { - for (x = 0; x < td->width_dest; x++) { - for (y = 0; y < td->height_dest; y++) { - float x_d1 = (x - c_d_x); - float y_d1 = (y - c_d_y); - float x_s = zcos_a * x_d1 - + zsin_a * y_d1 + c_s_x -t.x; - float y_s = -zsin_a * x_d1 - + zcos_a * y_d1 + c_s_y -t.y; - unsigned char* dest = &Y_2[x + y * td->width_dest]; - interpolate(dest, x_s, y_s, Y_1, - td->width_src, td->height_src, - td->crop ? 16 : *dest,1,0); - } - } - }else { - /* no rotation, no zooming, just translation - *(also no interpolation, since no size change) - */ - int round_tx = myround(t.x); - int round_ty = myround(t.y); - for (x = 0; x < td->width_dest; x++) { - for (y = 0; y < td->height_dest; y++) { - short p = PIXEL(Y_1, x - round_tx, y - round_ty, - td->width_src, td->height_src, -1); - if (p == -1) { - if (td->crop == 1) - Y_2[x + y * td->width_dest] = 16; - } else { - Y_2[x + y * td->width_dest] = (unsigned char)p; - } - } - } - } - - /* Color channels */ - int ws2 = td->width_src/2; - int wd2 = td->width_dest/2; - int hs2 = td->height_src/2; - int hd2 = td->height_dest/2; - if (fabs(t.alpha) > td->rotation_threshhold || t.zoom != 0) { - for (x = 0; x < wd2; x++) { - for (y = 0; y < hd2; y++) { - float x_d1 = x - (c_d_x)/2; - float y_d1 = y - (c_d_y)/2; - float x_s = zcos_a * x_d1 - + zsin_a * y_d1 + (c_s_x -t.x)/2; - float y_s = -zsin_a * x_d1 - + zcos_a * y_d1 + (c_s_y -t.y)/2; - unsigned char* dest = &Cr_2[x + y * wd2]; - interpolate(dest, x_s, y_s, Cr_1, ws2, hs2, - td->crop ? 128 : *dest,1,0); - dest = &Cb_2[x + y * wd2]; - interpolate(dest, x_s, y_s, Cb_1, ws2, hs2, - td->crop ? 128 : *dest,1,0); - } - } - } else { // no rotation, no zoom, no interpolation, just translation - int round_tx2 = myround(t.x/2.0); - int round_ty2 = myround(t.y/2.0); - for (x = 0; x < wd2; x++) { - for (y = 0; y < hd2; y++) { - short cr = PIXEL(Cr_1, x - round_tx2, y - round_ty2, - wd2, hd2, -1); - short cb = PIXEL(Cb_1, x - round_tx2, y - round_ty2, - wd2, hd2, -1); - if (cr == -1) { - if (td->crop==1) { - Cr_2[x + y * wd2] = 128; - Cb_2[x + y * wd2] = 128; - } - } else { - Cr_2[x + y * wd2] = (unsigned char)cr; - Cb_2[x + y * wd2] = (unsigned char)cb; - } - } - } - } - return 1; -} - - -/** - * preprocess_transforms: does smoothing, relative to absolute conversion, - * and cropping of too large transforms. - * This is actually the core algorithm for canceling the jiggle in the - * movie. We perform a low-pass filter in terms of transformation size. - * This enables still camera movement, but in a smooth fashion. - * - * Parameters: - * td: transform private data structure - * Return value: - * 1 for success and 0 for failure - * Preconditions: - * None - * Side effects: - * td->trans will be modified - */ -int preprocess_transforms(TransformData* td) -{ - Transform* ts = td->trans; - int i; - - if (td->trans_len < 1) - return 0; - if (0) { - mlt_log_debug(NULL,"Preprocess transforms:"); - } - if (td->smoothing>0) { - /* smoothing */ - Transform* ts2 = malloc(sizeof(Transform) * td->trans_len); - memcpy(ts2, ts, sizeof(Transform) * td->trans_len); - - /* we will do a sliding average with minimal update - * \hat x_{n/2} = x_1+x_2 + .. + x_n - * \hat x_{n/2+1} = x_2+x_3 + .. + x_{n+1} = x_{n/2} - x_1 + x_{n+1} - * avg = \hat x / n - */ - int s = td->smoothing * 2 + 1; - Transform null = null_transform(); - /* avg is the average over [-smoothing, smoothing] transforms - around the current point */ - Transform avg; - /* avg2 is a sliding average over the filtered signal! (only to past) - * with smoothing * 10 horizont to kill offsets */ - Transform avg2 = null_transform(); - double tau = 1.0/(3 * s); - /* initialise sliding sum with hypothetic sum centered around - * -1st element. We have two choices: - * a) assume the camera is not moving at the beginning - * b) assume that the camera moves and we use the first transforms - */ - Transform s_sum = null; - for (i = 0; i < td->smoothing; i++){ - s_sum = add_transforms(&s_sum, i < td->trans_len ? &ts2[i]:&null); - } - mult_transform(&s_sum, 2); // choice b (comment out for choice a) - - for (i = 0; i < td->trans_len; i++) { - Transform* old = ((i - td->smoothing - 1) < 0) - ? &null : &ts2[(i - td->smoothing - 1)]; - Transform* new = ((i + td->smoothing) >= td->trans_len) - ? &null : &ts2[(i + td->smoothing)]; - s_sum = sub_transforms(&s_sum, old); - s_sum = add_transforms(&s_sum, new); - - avg = mult_transform(&s_sum, 1.0/s); - - /* lowpass filter: - * meaning high frequency must be transformed away - */ - ts[i] = sub_transforms(&ts2[i], &avg); - /* kill accumulating offset in the filtered signal*/ - avg2 = add_transforms_(mult_transform(&avg2, 1 - tau), - mult_transform(&ts[i], tau)); - ts[i] = sub_transforms(&ts[i], &avg2); - - if (0 /*verbose*/ ) { - mlt_log_warning(NULL,"s_sum: %5lf %5lf %5lf, ts: %5lf, %5lf, %5lf\n", - s_sum.x, s_sum.y, s_sum.alpha, - ts[i].x, ts[i].y, ts[i].alpha); - mlt_log_warning(NULL, - " avg: %5lf, %5lf, %5lf avg2: %5lf, %5lf, %5lf", - avg.x, avg.y, avg.alpha, - avg2.x, avg2.y, avg2.alpha); - } - } - free(ts2); - } - - - /* invert? */ - if (td->invert) { - for (i = 0; i < td->trans_len; i++) { - ts[i] = mult_transform(&ts[i], -1); - } - } - - /* relative to absolute */ - if (td->relative) { - Transform t = ts[0]; - for (i = 1; i < td->trans_len; i++) { - if (0/*verbose*/ ) { - mlt_log_warning(NULL, "shift: %5lf %5lf %lf \n", - t.x, t.y, t.alpha *180/M_PI); - } - ts[i] = add_transforms(&ts[i], &t); - t = ts[i]; - } - } - /* crop at maximal shift */ - if (td->maxshift != -1) - for (i = 0; i < td->trans_len; i++) { - ts[i].x = TC_CLAMP(ts[i].x, -td->maxshift, td->maxshift); - ts[i].y = TC_CLAMP(ts[i].y, -td->maxshift, td->maxshift); - } - if (td->maxangle != - 1.0) - for (i = 0; i < td->trans_len; i++) - ts[i].alpha = TC_CLAMP(ts[i].alpha, -td->maxangle, td->maxangle); - - /* Calc optimal zoom - * cheap algo is to only consider transformations - * uses cleaned max and min - */ - if (td->optzoom != 0 && td->trans_len > 1){ - Transform min_t, max_t; - cleanmaxmin_xy_transform(ts, td->trans_len, 10, &min_t, &max_t); - // the zoom value only for x - double zx = 2*TC_MAX(max_t.x,fabs(min_t.x))/td->width_src; - // the zoom value only for y - double zy = 2*TC_MAX(max_t.y,fabs(min_t.y))/td->height_src; - td->zoom += 100* TC_MAX(zx,zy); // use maximum - mlt_log_debug(NULL,"Final zoom: %lf\n", td->zoom); - } - - /* apply global zoom */ - if (td->zoom != 0){ - for (i = 0; i < td->trans_len; i++) - ts[i].zoom += td->zoom; - } - - return 1; -} - -/** - * transform_init: Initialize this instance of the module. See - * tcmodule-data.h for function details. - */ - -#if 0 - -static int transform_init(TCModuleInstance *self, uint32_t features) -{ - - TransformData* td = NULL; - TC_MODULE_SELF_CHECK(self, "init"); - TC_MODULE_INIT_CHECK(self, MOD_FEATURES, features); - - td = tc_zalloc(sizeof(TransformData)); - if (td == NULL) { - tc_log_error(MOD_NAME, "init: out of memory!"); - return TC_ERROR; - } - self->userdata = td; - if (verbose) { - tc_log_info(MOD_NAME, "%s %s", MOD_VERSION, MOD_CAP); - } - - return T; -} -#endif - -/** - * transform_configure: Configure this instance of the module. See - * tcmodule-data.h for function details. - */ -int transform_configure(TransformData *self,int width,int height, mlt_image_format pixelformat, unsigned char* image ,Transform* tx,int trans_len) -{ - TransformData *td = self; - - /**** Initialise private data structure */ - - /* td->framesize = td->vob->im_v_width * - * MAX_PLANES * sizeof(char) * 2 * td->vob->im_v_height * 2; - */ - // rgb24 = w*h*3 , yuv420p = w* h* 3/2 - td->framesize_src = width*height*(pixelformat==mlt_image_rgb24 ? 3 : (3.0/2.0)); - td->src = malloc(td->framesize_src); /* FIXME */ - if (td->src == NULL) { - mlt_log_error(NULL,"tc_malloc failed\n"); - return -1; - } - - td->width_src = width; - td->height_src = height; - - /* Todo: in case we can scale the images, calc new size later */ - td->width_dest = width; - td->height_dest = height; - td->framesize_dest = td->framesize_src; - td->dest = 0; - - td->trans = tx; - td->trans_len = trans_len; - td->current_trans = 0; - td->warned_transform_end = 0; - - /* Options */ - // set from filter td->maxshift = -1; - // set from filter td->maxangle = -1; - - - // set from filter td->crop = 0; - // set from filter td->relative = 1; - // set from filter td->invert = 0; - // set from filter td->smoothing = 10; - - td->rotation_threshhold = 0.25/(180/M_PI); - - // set from filter td->zoom = 0; - // set from filter td->optzoom = 1; - // set from filter td->interpoltype = 2; // bi-linear - // set from filter td->sharpen = 0.8; - - td->interpoltype = TC_MIN(td->interpoltype,4); - if (1) { - mlt_log_debug(NULL, "Image Transformation/Stabilization Settings:\n"); - mlt_log_debug(NULL, " smoothing = %d\n", td->smoothing); - mlt_log_debug(NULL, " maxshift = %d\n", td->maxshift); - mlt_log_debug(NULL, " maxangle = %f\n", td->maxangle); - mlt_log_debug(NULL, " crop = %s\n", - td->crop ? "Black" : "Keep"); - mlt_log_debug(NULL, " relative = %s\n", - td->relative ? "True": "False"); - mlt_log_debug(NULL, " invert = %s\n", - td->invert ? "True" : "False"); - mlt_log_debug(NULL, " zoom = %f\n", td->zoom); - mlt_log_debug(NULL, " optzoom = %s\n", - td->optzoom ? "On" : "Off"); - mlt_log_debug(NULL, " interpol = %s\n", - interpoltypes[td->interpoltype]); - mlt_log_debug(NULL, " sharpen = %f\n", td->sharpen); - } - - if (td->maxshift > td->width_dest/2 - ) td->maxshift = td->width_dest/2; - if (td->maxshift > td->height_dest/2) - td->maxshift = td->height_dest/2; - - if (!preprocess_transforms(td)) { - mlt_log_error(NULL,"error while preprocessing transforms!"); - return -1; - } - - switch(td->interpoltype){ - case 0: interpolate = &interpolateZero; break; - case 1: interpolate = &interpolateLin; break; - case 2: interpolate = &interpolateBiLin; break; - case 3: interpolate = &interpolateSqr; break; - case 4: interpolate = &interpolateBiCub; break; - default: interpolate = &interpolateBiLin; - } - - return 0; -} - - -/** - * transform_filter_video: performs the transformation of frames - * See tcmodule-data.h for function details. - */ -int transform_filter_video(TransformData *self, - unsigned char *frame,mlt_image_format pixelformat) -{ - TransformData *td = self; - - - td->dest = frame; - memcpy(td->src, frame, td->framesize_src); - if (td->current_trans >= td->trans_len) { - td->current_trans = td->trans_len-1; - if(!td->warned_transform_end) - mlt_log_warning(NULL,"not enough transforms found, use last transformation!\n"); - td->warned_transform_end = 1; - } - - if (pixelformat == mlt_image_rgb24 ) { - transformRGB(td); - } else if (pixelformat == mlt_image_yuv420p) { - transformYUV(td); - } else { - mlt_log_error(NULL,"unsupported Codec: %i\n", pixelformat); - return 1; - } - td->current_trans++; - return 0; -} - - diff --git a/src/modules/videostab/transform_image.h b/src/modules/videostab/transform_image.h deleted file mode 100644 index a907968f9..000000000 --- a/src/modules/videostab/transform_image.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * filter_transform.c - * - * Copyright (C) Georg Martius - June 2007 - * georg dot martius at web dot de - * - * This file is part of transcode, a video stream processing tool - * - * transcode 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, or (at your option) - * any later version. - * - * transcode 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 GNU Make; see the file COPYING. If not, write to - * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Typical call: - * transcode -J transform -i inp.mpeg -y xdiv,tcaud inp_stab.avi - */ - -#include "transform.h" - -#include -#include -#include "tlist.h" -#include - -#define DEFAULT_TRANS_FILE_NAME "transforms.dat" - -#define PIXEL(img, x, y, w, h, def) ((x) < 0 || (y) < 0) ? def \ - : (((x) >=w || (y) >= h) ? def : img[(x) + (y) * w]) -#define PIX(img, x, y, w, h) (img[(x) + (y) * w]) -#define PIXN(img, x, y, w, h,N,channel) (img[((x) + (y) * w)*N+channel]) -// gives Pixel in N-channel image. channel in {0..N-1} -#define PIXELN(img, x, y, w, h, N,channel , def) ((x) < 0 || (y) < 0) ? def \ - : (((x) >=w || (y) >= h) ? def : img[((x) + (y) * w)*N + channel]) - -typedef struct { - int framesize_src; // size of frame buffer in bytes (src) - int framesize_dest; // size of frame buffer in bytes (dest) - unsigned char* src; // copy of the current frame buffer - unsigned char* dest; // pointer to the current frame buffer (to overwrite) - - int pixelformat; - int width_src, height_src; - int width_dest, height_dest; - Transform* trans; // array of transformations - int current_trans; // index to current transformation - int trans_len; // length of trans array - short warned_transform_end; // whether we warned that there is no transform left - - /* Options */ - int maxshift; // maximum number of pixels we will shift - double maxangle; // maximum angle in rad - - /* whether to consider transforms as relative (to previous frame) - * or absolute transforms - */ - int relative; - /* number of frames (forward and backward) - * to use for smoothing transforms */ - int smoothing; - int crop; // 1: black bg, 0: keep border from last frame(s) - int invert; // 1: invert transforms, 0: nothing - /* constants */ - /* threshold below which no rotation is performed */ - double rotation_threshhold; - double zoom; // percentage to zoom: 0->no zooming 10:zoom in 10% - int optzoom; // 1: determine optimal zoom, 0: nothing - int interpoltype; // type of interpolation: 0->Zero,1->Lin,2->BiLin,3->Sqr - double sharpen; // amount of sharpening - - char conf_str[1024]; -} TransformData; - -/* forward declarations, please look below for documentation*/ -void interpolateBiLinBorder(unsigned char *rv, float x, float y, - unsigned char* img, int w, int h, unsigned char def,unsigned char N, unsigned char channel); -void interpolateBiCub(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, unsigned char def,unsigned char N, unsigned char channel); -void interpolateSqr(unsigned char *rv, float x, float y, - unsigned char* img, int w, int h, unsigned char def,unsigned char N, unsigned char channel); -void interpolateBiLin(unsigned char *rv, float x, float y, - unsigned char* img, int w, int h, unsigned char def,unsigned char N, unsigned char channel); -void interpolateLin(unsigned char *rv, float x, float y, - unsigned char* img, int w, int h, unsigned char def,unsigned char N, unsigned char channel); -void interpolateZero(unsigned char *rv, float x, float y, - unsigned char* img, int w, int h, unsigned char def,unsigned char N, unsigned char channel); -void interpolateN(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, - unsigned char N, unsigned char channel, unsigned char def); -int transformRGB(TransformData* td); -int transformYUV(TransformData* td); -int read_input_file(TransformData* td,tlist* list); -int preprocess_transforms(TransformData* td); - - -/** - * interpolate: general interpolation function pointer for one channel image data - * - * Parameters: - * rv: destination pixel (call by reference) - * x,y: the source coordinates in the image img. Note this - * are real-value coordinates, that's why we interpolate - * img: source image - * width,height: dimension of image - * def: default value if coordinates are out of range - * Return value: None - */ -/*void (*interpolate)(unsigned char *rv, float x, float y, - unsigned char* img, int width, int height, - unsigned char def) = 0; -*/ -/** interpolateBiLinBorder: bi-linear interpolation function that also works at the border. - This is used by many other interpolation methods at and outsize the border, see interpolate */ -int transform_configure(TransformData *self,int width,int height, mlt_image_format pixelformat, unsigned char* image,Transform* tx,int trans_len) ; - -int transform_filter_video(TransformData *self, - unsigned char *frame,mlt_image_format pixelformat); diff --git a/src/modules/xml/consumer_xml.yml b/src/modules/xml/consumer_xml.yml index c9ad925cf..1f4b0461b 100644 --- a/src/modules/xml/consumer_xml.yml +++ b/src/modules/xml/consumer_xml.yml @@ -52,7 +52,7 @@ parameters: description: > Without this option, the XML consumer does not process any frames and simply serializes the service network. However, some filters (.e.g, - videostab) require two passes where the first pass performs some + vid.stab) require two passes where the first pass performs some analysis and stores the result in a property. Therefore, set this property to 1 (true) to cause the consumer to process all frames before serializing to XML. From 1e6c82dd3be4ac70491f898f404c8ae1635d0bbd Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 8 Feb 2021 23:07:51 -0600 Subject: [PATCH 029/122] Remove lumas module --- CMakeLists.txt | 1 - docs/install.txt | 1 - src/modules/CMakeLists.txt | 4 - src/modules/lumas/CMakeLists.txt | 64 ------------- src/modules/lumas/Makefile | 41 --------- src/modules/lumas/configure | 35 -------- src/modules/lumas/create_lumas | 77 ---------------- src/modules/lumas/luma.c | 149 ------------------------------- 8 files changed, 372 deletions(-) delete mode 100644 src/modules/lumas/CMakeLists.txt delete mode 100644 src/modules/lumas/Makefile delete mode 100755 src/modules/lumas/configure delete mode 100755 src/modules/lumas/create_lumas delete mode 100644 src/modules/lumas/luma.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d6bd45134..7142146ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,6 @@ option(MOD_FREI0R "Enable frei0r module" ON) option(MOD_GDK "Enable gdk module" ON) option(MOD_JACKRACK "Enable jackrack module" ON) option(MOD_KDENLIVE "Enable kdenlive module" ON) -option(MOD_LUMAS "Enable lumas module" ON) option(MOD_MOTION_EST "Enable motion estimation module" ON) option(MOD_NORMALIZE "Enable normalize module" ON) option(MOD_OLDFILM "Enable oldfilm module" ON) diff --git a/docs/install.txt b/docs/install.txt index a5f4cec7b..c69c371ae 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -30,7 +30,6 @@ Last Revision: 2013-09-07 * gdk - GDK pango and pixbuf dependent services * jackrack - adapter for LADSPA audio plugins and JACK server * kdenlive - services contributed by Kdenlive project - * lumas - wipe file generator for core's luma transition * motion_est - motion estimation-based filters (*) * normalize - audio normalisation functions (*) * oldfilm - filters to make pristine video dirty diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index cd3f58d5a..06223f7a0 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -28,10 +28,6 @@ if(MOD_KDENLIVE) add_subdirectory(kdenlive) endif() -if(MOD_LUMAS) - add_subdirectory(lumas) -endif() - if(MOD_MOTION_EST AND GPL) add_subdirectory(motion_est) endif() diff --git a/src/modules/lumas/CMakeLists.txt b/src/modules/lumas/CMakeLists.txt deleted file mode 100644 index dbc340f7f..000000000 --- a/src/modules/lumas/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -add_executable(luma luma.c) -target_link_libraries(luma mlt) - -# luma requires libmlt to work, so we set the output directory for luma to the location of this library -set_target_properties(luma PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/src/framework") - -function(create_lumas dir w h bpp) - set(${dir} - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma01.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma02.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma03.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma04.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma05.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma06.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma07.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma08.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma09.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma10.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma11.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma12.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma13.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma14.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma15.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma16.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma17.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma18.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma19.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma20.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma21.pgm - ${CMAKE_CURRENT_BINARY_DIR}/${dir}/luma22.pgm - ) - add_custom_command(OUTPUT ${${dir}} DEPENDS luma - COMMAND ${CMAKE_COMMAND} -E make_directory ${dir} - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma01.pgm - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma02.pgm -bands ${h} - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma03.pgm -hmirror 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma04.pgm -bands ${h} -vmirror 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma05.pgm -offset 32768 -dmirror 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma06.pgm -offset 32768 -dmirror 1 -flip 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma07.pgm -offset 32768 -dmirror 1 -quart 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma08.pgm -offset 32768 -dmirror 1 -quart 1 -flip 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma09.pgm -bands 12 -rband 0 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma10.pgm -bands 12 -rband 0 -rotate 1 -flop 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma11.pgm -bands 12 -rband 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma12.pgm -bands 12 -rband 1 -vmirror 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma13.pgm -bands 12 -rband 1 -rotate 1 -flop 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma14.pgm -bands 12 -rband 1 -rotate 1 -flop 1 -vmirror 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma15.pgm -offset 32768 -dmirror 1 -hmirror 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma16.pgm -type 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma17.pgm -type 1 -bands 2 -rband 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma18.pgm -type 2 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma19.pgm -type 2 -quart 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma20.pgm -type 2 -quart 1 -flip 1 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma21.pgm -type 2 -quart 1 -bands 2 - COMMAND luma -w ${w} -h ${h} -bpp ${bpp} ${dir}/luma22.pgm -type 3) - add_custom_target(${dir} ALL DEPENDS ${${dir}}) - install(FILES ${${dir}} DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/lumas/${dir}) -endfunction() - -create_lumas(PAL 720 576 16) -create_lumas(NTSC 720 480 16) -create_lumas(16_9 1920 1080 16) -create_lumas(9_16 1080 1920 16) -create_lumas(square 1080 1080 16) diff --git a/src/modules/lumas/Makefile b/src/modules/lumas/Makefile deleted file mode 100644 index efc87a4c3..000000000 --- a/src/modules/lumas/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -include ../../../config.mak - -all: luma create_lumas - @./create_lumas - -luma: luma.o -# When cross-compiling, use the host OS compiler to build the luma -# binary because the files are generated at build time. -# Strips the CROSS prefix from the C compiler variable. -ifdef CROSS - $(subst $(CROSS),,$(CC)) -o $@ luma.o $(LDFLAGS) -else - $(CC) -o $@ luma.o $(LDFLAGS) -endif - -create_lumas: - -depend: luma.c - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: - rm -rf luma 9_16 16_9 NTSC PAL square - -clean: - rm -f luma luma.o .executed - -install: all - install -d "$(DESTDIR)$(mltdatadir)/lumas/9_16" - install -d "$(DESTDIR)$(mltdatadir)/lumas/16_9" - install -d "$(DESTDIR)$(mltdatadir)/lumas/NTSC" - install -d "$(DESTDIR)$(mltdatadir)/lumas/PAL" - install -d "$(DESTDIR)$(mltdatadir)/lumas/square" - install -m 644 9_16/* "$(DESTDIR)$(mltdatadir)/lumas/9_16" - install -m 644 16_9/* "$(DESTDIR)$(mltdatadir)/lumas/16_9" - install -m 644 NTSC/* "$(DESTDIR)$(mltdatadir)/lumas/NTSC" - install -m 644 PAL/* "$(DESTDIR)$(mltdatadir)/lumas/PAL" - install -m 644 square/* "$(DESTDIR)$(mltdatadir)/lumas/square" diff --git a/src/modules/lumas/configure b/src/modules/lumas/configure deleted file mode 100755 index 4d980d003..000000000 --- a/src/modules/lumas/configure +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -if [ "$help" = "1" ] -then - cat << EOF -Luma options: - - --enable-lumas This must be explicitly enabled since they can now - be generated dynamically. - --luma-compress - Produce compressed (png) lumas - --luma-8bpp - Produce 8 bit pgm lumas (default is 16 bit) - -EOF - -else - - rm -f .8bit .compress .executed - - for i in "$@" - do - case $i in - --enable-lumas ) lumas_enabled=1;; - --luma-compress ) touch .compress .8bit ;; - --luma-8bit ) touch .8bit ;; - esac - done - - if [ "$lumas_enabled" != "1" ]; then - echo "- not explicitly enabled: disabling" - touch ../disable-lumas - exit 0 - fi - -fi - diff --git a/src/modules/lumas/create_lumas b/src/modules/lumas/create_lumas deleted file mode 100755 index 943911b13..000000000 --- a/src/modules/lumas/create_lumas +++ /dev/null @@ -1,77 +0,0 @@ -#!/bin/sh - -[ \( -d PAL \) -a \( ! $0 -nt .executed \) ] && exit 0 - -if [ "$(uname -s)" = "Darwin" ]; then - export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../framework -elif uname -s | grep -iq mingw; then - export PATH=$PATH:../../framework -else - export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../framework -fi - -bpp=16 -[ -f .8bit ] && bpp=8 - -for i in PAL NTSC 16_9 9_16 square -do - mkdir -p $i - rm -f $i/*.pgm $i/*.png - - case $i in - NTSC) - w=720 - h=480 - ;; - PAL) - w=720 - h=576 - ;; - 16_9) - w=1920 - h=1080 - ;; - 9_16) - w=1080 - h=1920 - ;; - square) - w=1080 - h=1080 - ;; - esac - ./luma -w $w -h $h -bpp $bpp $i/luma01.pgm - ./luma -w $w -h $h -bpp $bpp -bands $h $i/luma02.pgm - ./luma -w $w -h $h -bpp $bpp -hmirror 1 $i/luma03.pgm - ./luma -w $w -h $h -bpp $bpp -bands $h -vmirror 1 $i/luma04.pgm - ./luma -w $w -h $h -bpp $bpp -offset 32768 -dmirror 1 $i/luma05.pgm - ./luma -w $w -h $h -bpp $bpp -offset 32768 -dmirror 1 -flip 1 $i/luma06.pgm - ./luma -w $w -h $h -bpp $bpp -offset 32768 -dmirror 1 -quart 1 $i/luma07.pgm - ./luma -w $w -h $h -bpp $bpp -offset 32768 -dmirror 1 -quart 1 -flip 1 $i/luma08.pgm - ./luma -w $w -h $h -bpp $bpp -bands 12 -rband 0 $i/luma09.pgm - ./luma -w $w -h $h -bpp $bpp -bands 12 -rband 0 -rotate 1 -flop 1 $i/luma10.pgm - ./luma -w $w -h $h -bpp $bpp -bands 12 -rband 1 $i/luma11.pgm - ./luma -w $w -h $h -bpp $bpp -bands 12 -rband 1 -vmirror 1 $i/luma12.pgm - ./luma -w $w -h $h -bpp $bpp -bands 12 -rband 1 -rotate 1 -flop 1 $i/luma13.pgm - ./luma -w $w -h $h -bpp $bpp -bands 12 -rband 1 -rotate 1 -vmirror 1 $i/luma14.pgm - ./luma -w $w -h $h -bpp $bpp -offset 32768 -dmirror 1 -hmirror 1 $i/luma15.pgm - ./luma -w $w -h $h -bpp $bpp -type 1 $i/luma16.pgm - ./luma -w $w -h $h -bpp $bpp -type 1 -bands 2 -rband 1 $i/luma17.pgm - ./luma -w $w -h $h -bpp $bpp -type 2 $i/luma18.pgm - ./luma -w $w -h $h -bpp $bpp -type 2 -quart 1 $i/luma19.pgm - ./luma -w $w -h $h -bpp $bpp -type 2 -quart 1 -flip 1 $i/luma20.pgm - ./luma -w $w -h $h -bpp $bpp -type 2 -quart 1 -bands 2 $i/luma21.pgm - ./luma -w $w -h $h -bpp $bpp -type 3 $i/luma22.pgm - - if [ -f .compress ] - then - for f in $i/*.pgm - do - convert $f $f.png - rm -f $f - done - fi -done - -touch .executed - diff --git a/src/modules/lumas/luma.c b/src/modules/lumas/luma.c deleted file mode 100644 index a4fbfafde..000000000 --- a/src/modules/lumas/luma.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * luma.c -- image generator for transition_luma - * Copyright (C) 2003-2019 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include - -#include -#include -#include -#include - -int main( int argc, char **argv ) -{ - int arg = 1; - int bpp = 8; - - struct mlt_luma_map_s self; - uint16_t *image = NULL; - const char *filename = NULL; - - mlt_luma_map_init( &self ); - - for ( arg = 1; arg < argc; arg ++ ) - { - if ( !strcmp( argv[ arg ], "-bpp" ) ) - bpp = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-type" ) ) - self.type = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-w" ) ) - { - int tmp = atoi( argv[ ++ arg ] ); - // TODO: is there an upper bound? - if ( tmp ) - self.w = tmp; - else - return 1; - } - else if ( !strcmp( argv[ arg ], "-h" ) ) - { - int tmp = atoi( argv[ ++ arg ] ); - // TODO: is there an upper bound? - if ( tmp ) - self.h = tmp; - else return 1; - } - else if ( !strcmp( argv[ arg ], "-bands" ) ) - { - int tmp = atoi( argv[ ++ arg ] ); - // TODO: is there an upper bound? - if ( tmp >= 0 ) - self.bands = tmp; - else - return 1; - } - else if ( !strcmp( argv[ arg ], "-rband" ) ) - self.rband = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-hmirror" ) ) - self.hmirror = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-vmirror" ) ) - self.vmirror = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-dmirror" ) ) - self.dmirror = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-offset" ) ) - self.offset = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-invert" ) ) - self.invert = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-flip" ) ) - self.flip = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-flop" ) ) - self.flop = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-pflip" ) ) - self.pflip = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-pflop" ) ) - self.pflop = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-quart" ) ) - self.quart = atoi( argv[ ++ arg ] ); - else if ( !strcmp( argv[ arg ], "-rotate" ) ) - self.rotate = atoi( argv[ ++ arg ] ); - else - filename = argv[arg]; - } - - if ( bpp != 8 && bpp != 16 ) - { - fprintf( stderr, "Invalid bpp %d\n", bpp ); - return 1; - } - - mlt_pool_init(); - image = mlt_luma_map_render( &self ); - - if ( bpp == 16 ) - { - uint16_t *end = image + self.w * self.h; - uint16_t *p = image; - uint8_t *q = ( uint8_t * )image; - while ( p < end ) - { - *p ++ = ( *q << 8 ) + *( q + 1 ); - q += 2; - } - if (filename) { - FILE *f = fopen(filename, "wb"); - if (f) { - fprintf(f, "P5\x0a" ); - fprintf(f, "%d %d\x0a", self.w, self.h ); - fprintf(f, "65535\x0a" ); - fwrite( image, self.w * self.h * sizeof( uint16_t ), 1, f ); - fclose(f); - } - } else { - printf( "P5\n" ); - printf( "%d %d\n", self.w, self.h ); - printf( "65535\n" ); - fwrite( image, self.w * self.h * sizeof( uint16_t ), 1, stdout ); - } - } - else - { - uint16_t *end = image + self.w * self.h; - uint16_t *p = image; - uint8_t *q = ( uint8_t * )image; - while ( p < end ) - *q ++ = ( uint8_t )( *p ++ >> 8 ); - printf( "P5\n" ); - printf( "%d %d\n", self.w, self.h ); - printf( "255\n" ); - fwrite( image, self.w * self.h, 1, stdout ); - } - - return 0; -} - From 0f8a0f1723ed18ef779097e7b8997758f9a28a24 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Wed, 10 Feb 2021 21:10:12 -0800 Subject: [PATCH 030/122] remove legacy mcdv and mcmpeg from loader.dict --- src/modules/core/loader.dict | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/modules/core/loader.dict b/src/modules/core/loader.dict index 6c14f77ad..d6606f96e 100644 --- a/src/modules/core/loader.dict +++ b/src/modules/core/loader.dict @@ -8,12 +8,8 @@ plain:https://*=webvfx:plain: *.kdenlive=xml *.melt=melt_file *.inigo=melt_file -*.asf=avformat -*.avi=mcdv,avformat *.bmp=qimage,pixbuf *.dds=qimage,avformat -*.dv=mcdv,avformat -*.dif=mcdv,avformat *.exr=qimage *.gif=qimage,pixbuf *.graphics=xml @@ -27,10 +23,6 @@ plain:https://*=webvfx:plain: *.kdenlivetitle=kdenlivetitle *.kino=xml *.kra=qimage -*.mp3=avformat -*.mov=mcdv,avformat -*.mpg=mcmpeg,avformat -*.mpeg=mcmpeg,avformat *.mpl=pango *.ogg=avformat,vorbis *.pcx=qimage,pixbuf @@ -40,15 +32,11 @@ plain:https://*=webvfx:plain: *.qml=webvfx:plain: *.story=xml *.svg=qimage,pixbuf -*.swf=avformat *.tga=qimage,pixbuf *.tif=qimage,pixbuf *.tiff=qimage,pixbuf *.txt=qtext,pango -*.vob=mcmpeg,avformat -*.wav=avformat *.webp=qimage,avformat -*.wmv=avformat *.xcf=qimage *.xml=xml *=avformat From a95f683c36a1c1b800eeb42c0b9896a16eeea952 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Mon, 15 Feb 2021 09:45:25 +0100 Subject: [PATCH 031/122] cmake: add NDI module --- CMakeLists.txt | 5 ++++ cmake/FindNDI.cmake | 53 ++++++++++++++++++++++++++++++++++ src/modules/CMakeLists.txt | 4 +++ src/modules/ndi/CMakeLists.txt | 13 +++++++++ 4 files changed, 75 insertions(+) create mode 100644 cmake/FindNDI.cmake create mode 100644 src/modules/ndi/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 7142146ac..f03664df6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,7 @@ option(MOD_GDK "Enable gdk module" ON) option(MOD_JACKRACK "Enable jackrack module" ON) option(MOD_KDENLIVE "Enable kdenlive module" ON) option(MOD_MOTION_EST "Enable motion estimation module" ON) +option(MOD_NDI "Enable NDI module" OFF) option(MOD_NORMALIZE "Enable normalize module" ON) option(MOD_OLDFILM "Enable oldfilm module" ON) option(MOD_OPENCV "Enable OpenCV module" ON) @@ -149,6 +150,10 @@ if(MOD_JACKRACK) check_include_file(ladspa.h ladspa_h_FOUND) endif() +if(MOD_NDI) + find_package(NDI REQUIRED) +endif() + if(MOD_OPENCV) find_package(OpenCV QUIET OPTIONAL_COMPONENTS tracking) endif() diff --git a/cmake/FindNDI.cmake b/cmake/FindNDI.cmake new file mode 100644 index 000000000..8711f161b --- /dev/null +++ b/cmake/FindNDI.cmake @@ -0,0 +1,53 @@ +set(NDI_SDK_INCLUDE_PATH "" CACHE PATH "NDI SDK include path") +set(NDI_SDK_LIBRARY_PATH "" CACHE PATH "NDI SDK library path") + +if(NOT (NDI_SDK_INCLUDE_PATH AND NDI_SDK_LIBRARY_PATH)) + message(FATAL_ERROR "NDI SDK: Please povide NDI_SDK_INCLUDE_PATH and NDI_SDK_LIBRARY_PATH!") +endif() + +find_path(NDI_INCLUDE_DIR + NAMES + Processing.NDI.compat.h + Processing.NDI.deprecated.h + Processing.NDI.DynamicLoad.h + Processing.NDI.Find.h + Processing.NDI.FrameSync.h + Processing.NDI.Lib.cplusplus.h + Processing.NDI.Lib.h + Processing.NDI.Recv.ex.h + Processing.NDI.Recv.h + Processing.NDI.Routing.h + Processing.NDI.Send.h + Processing.NDI.structs.h + Processing.NDI.utilities.h + PATHS "${NDI_SDK_INCLUDE_PATH}" +) + +find_library(NDI_LIBRARY + NAMES ndi + PATHS "${NDI_SDK_LIBRARY_PATH}" +) +if(NOT NDI_LIBRARY) + message(FATAL_ERROR "NDI SDK: libndi.so / ndi.dll not found in:\n${NDI_SDK_LIBRARY_PATH}\nMaybe you have to create a symlink or rename the file.") +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(NDI + FOUND_VAR NDI_FOUND + REQUIRED_VARS + NDI_LIBRARY + NDI_INCLUDE_DIR +) + +if(NDI_FOUND AND NOT TARGET NDI::NDI) + add_library(NDI::NDI SHARED IMPORTED) + set_target_properties(NDI::NDI PROPERTIES + IMPORTED_LOCATION "${NDI_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${NDI_INCLUDE_DIR}" + ) +endif() + +mark_as_advanced( + NDI_INCLUDE_DIR + NDI_LIBRARY +) \ No newline at end of file diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 06223f7a0..adc8eb394 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -32,6 +32,10 @@ if(MOD_MOTION_EST AND GPL) add_subdirectory(motion_est) endif() +if(MOD_NDI) + add_subdirectory(ndi) +endif() + if(MOD_NORMALIZE AND GPL) add_subdirectory(normalize) endif() diff --git a/src/modules/ndi/CMakeLists.txt b/src/modules/ndi/CMakeLists.txt new file mode 100644 index 000000000..862782393 --- /dev/null +++ b/src/modules/ndi/CMakeLists.txt @@ -0,0 +1,13 @@ +add_library(mltndi MODULE + consumer_ndi.c + factory.c + producer_ndi.c +) + +target_link_libraries(mltndi PRIVATE mlt NDI::NDI) + +# Create module in parent directory, for the benefit of "source setenv". +set_target_properties(mltndi PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) + +install(TARGETS mltndi LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(FILES consumer_ndi.yml producer_ndi.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/ndi) From a45cf161649563dc3c16f1094877a63cf14bfac5 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 16 Feb 2021 08:15:10 +0100 Subject: [PATCH 032/122] cmake: fix fnmatch include dir --- src/modules/core/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/core/CMakeLists.txt b/src/modules/core/CMakeLists.txt index ad7a8fc37..291ce077c 100644 --- a/src/modules/core/CMakeLists.txt +++ b/src/modules/core/CMakeLists.txt @@ -48,6 +48,7 @@ target_link_libraries(mltcore mlt Threads::Threads) if(WIN32) target_sources(mltcore PRIVATE ../../win32/fnmatch.c) + target_include_directories(mltcore PRIVATE ../../win32) endif() if(X86_64) From f06a7f5a70c0c851c8efae2d9c0fe4e5b657ea2c Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 16 Feb 2021 08:15:36 +0100 Subject: [PATCH 033/122] cmake: fix internal RtAudio build --- src/modules/rtaudio/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/rtaudio/CMakeLists.txt b/src/modules/rtaudio/CMakeLists.txt index ee2c85f65..f11112c3d 100644 --- a/src/modules/rtaudio/CMakeLists.txt +++ b/src/modules/rtaudio/CMakeLists.txt @@ -5,6 +5,7 @@ if(TARGET PkgConfig::rtaudio) target_link_libraries(mltrtaudio PkgConfig::rtaudio) else() target_sources(mltrtaudio PRIVATE RtAudio.cpp) + target_include_directories(mltrtaudio PRIVATE .) if(APPLE) target_link_libraries(mltrtaudio CoreAudio CoreFoundation) target_compile_definitions(mltrtaudio PRIVATE __MACOSX_CORE__) From 9275f6b8c87efccae6b3646d1190bd1ecc2518b9 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 16 Feb 2021 08:15:54 +0100 Subject: [PATCH 034/122] cmake: disable OpenCV by default --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f03664df6..62dc1a74f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ option(MOD_MOTION_EST "Enable motion estimation module" ON) option(MOD_NDI "Enable NDI module" OFF) option(MOD_NORMALIZE "Enable normalize module" ON) option(MOD_OLDFILM "Enable oldfilm module" ON) -option(MOD_OPENCV "Enable OpenCV module" ON) +option(MOD_OPENCV "Enable OpenCV module" OFF) option(MOD_OPENGL "Enable OpenGL module" ON) option(MOD_PLUS "Enable plus module" ON) option(MOD_PLUSGPL "Enable plus GPL module" ON) From 46b2a481699b883fe64bb97fdfefd7b89e183644 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 16 Feb 2021 10:47:15 +0100 Subject: [PATCH 035/122] cmake: melt: add -mconsole --- src/melt/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/melt/CMakeLists.txt b/src/melt/CMakeLists.txt index 760e9ad16..40f171de3 100644 --- a/src/melt/CMakeLists.txt +++ b/src/melt/CMakeLists.txt @@ -11,4 +11,8 @@ if(TARGET PkgConfig::sdl2) endif() endif() +if(MINGW) + target_link_options(melt PRIVATE -mconsole) +endif() + install(TARGETS melt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) From 8056bff258c7e7e5cadaa3ecdc3514793e053292 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Wed, 17 Feb 2021 20:41:51 +0100 Subject: [PATCH 036/122] cmake: rename option(NODEPLOY) --- CMakeLists.txt | 6 +++++- src/framework/CMakeLists.txt | 2 +- src/modules/qt/CMakeLists.txt | 4 ++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 62dc1a74f..c91363ba2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,13 +51,17 @@ option(SWIG_RUBY "Enable SWIG Ruby bindings" OFF) option(SWIG_TCL "Enable SWIG Tcl bindings" OFF) if(WIN32) - option(NODEPLOY "Keep bin/ lib/ layout on Windows" ON) + option(WINDOWS_DEPLOY "Install exes/libs directly to prefix (no subdir /bin)" ON) endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include(GNUInstallDirs) +if(WINDOWS_DEPLOY) + set(CMAKE_INSTALL_BINDIR .) +endif() + set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 04469c432..95a3a9f62 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -44,7 +44,7 @@ if(WIN32) set_target_properties(mlt PROPERTIES OUTPUT_NAME "mlt-${MLT_VERSION_MAJOR}") target_sources(mlt PRIVATE ../win32/win32.c ../win32/strptime.c) target_link_libraries(mlt Iconv::Iconv) - if(NODEPLOY) + if(NOT WINDOWS_DEPLOY) target_compile_definitions(mlt PRIVATE NODEPLOY) endif() endif() diff --git a/src/modules/qt/CMakeLists.txt b/src/modules/qt/CMakeLists.txt index 47eabcfa3..b862e3eba 100644 --- a/src/modules/qt/CMakeLists.txt +++ b/src/modules/qt/CMakeLists.txt @@ -32,6 +32,10 @@ target_link_libraries(mltqt target_compile_definitions(mltqt PRIVATE USE_QT_OPENGL) +if(NOT WINDOWS_DEPLOY) + target_compile_definitions(mltqt PRIVATE NODEPLOY) +endif() + if(GPL3) target_sources(mltqt PRIVATE transition_vqm.cpp) target_compile_definitions(mltqt PRIVATE GPL3) From a5b2126d6c68a52c0de4537e17f391b50942223d Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Wed, 17 Feb 2021 20:46:29 +0100 Subject: [PATCH 037/122] cmake: use a common output dir --- CMakeLists.txt | 22 ++++++++++++++++++++++ src/framework/CMakeLists.txt | 5 +++-- src/modules/avformat/CMakeLists.txt | 3 +-- src/modules/core/CMakeLists.txt | 3 +-- src/modules/decklink/CMakeLists.txt | 3 +-- src/modules/frei0r/CMakeLists.txt | 3 +-- src/modules/gdk/CMakeLists.txt | 3 +-- src/modules/jackrack/CMakeLists.txt | 3 +-- src/modules/kdenlive/CMakeLists.txt | 3 +-- src/modules/motion_est/CMakeLists.txt | 3 +-- src/modules/ndi/CMakeLists.txt | 3 +-- src/modules/normalize/CMakeLists.txt | 3 +-- src/modules/oldfilm/CMakeLists.txt | 3 +-- src/modules/opencv/CMakeLists.txt | 3 +-- src/modules/opengl/CMakeLists.txt | 3 +-- src/modules/plus/CMakeLists.txt | 3 +-- src/modules/plusgpl/CMakeLists.txt | 3 +-- src/modules/qt/CMakeLists.txt | 3 +-- src/modules/resample/CMakeLists.txt | 3 +-- src/modules/rtaudio/CMakeLists.txt | 3 +-- src/modules/rubberband/CMakeLists.txt | 3 +-- src/modules/sdl/CMakeLists.txt | 3 +-- src/modules/sdl2/CMakeLists.txt | 3 +-- src/modules/sox/CMakeLists.txt | 3 +-- src/modules/vid.stab/CMakeLists.txt | 3 +-- src/modules/vmfx/CMakeLists.txt | 3 +-- src/modules/vorbis/CMakeLists.txt | 3 +-- src/modules/xine/CMakeLists.txt | 3 +-- src/modules/xml/CMakeLists.txt | 3 +-- src/tests/CMakeLists.txt | 5 +++-- 30 files changed, 55 insertions(+), 58 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c91363ba2..f7b7b3278 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,28 @@ if(WINDOWS_DEPLOY) set(CMAKE_INSTALL_BINDIR .) endif() +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out/${CMAKE_INSTALL_BINDIR}") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out/lib") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out/lib") +set(MLT_MODULE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out/lib/mlt") +set(MLT_DATA_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out/share/mlt") + +if(WIN32) # symlinks require admin rights on Windows + file(COPY "${CMAKE_SOURCE_DIR}/src/modules" DESTINATION "${CMAKE_BINARY_DIR}/out/share" FILES_MATCHING REGEX yml|txt) + file(RENAME "${CMAKE_BINARY_DIR}/out/share/modules" "${MLT_DATA_OUTPUT_DIRECTORY}") + file(COPY "${CMAKE_SOURCE_DIR}/presets" DESTINATION "${MLT_DATA_OUTPUT_DIRECTORY}") + file(COPY "${CMAKE_SOURCE_DIR}/profiles" DESTINATION "${MLT_DATA_OUTPUT_DIRECTORY}") +else() + file(MAKE_DIRECTORY "${MLT_DATA_OUTPUT_DIRECTORY}") + file(GLOB MOD_SUBDIRS "${CMAKE_SOURCE_DIR}/src/modules/*") + foreach(MOD_SUBDIR ${MOD_SUBDIRS}) + file(RELATIVE_PATH MOD_NAME "${CMAKE_SOURCE_DIR}/src/modules" ${MOD_SUBDIR}) + file(CREATE_LINK "${CMAKE_SOURCE_DIR}/src/modules/${MOD_NAME}" "${MLT_DATA_OUTPUT_DIRECTORY}/${MOD_NAME}" SYMBOLIC) + endforeach() + file(CREATE_LINK "${CMAKE_SOURCE_DIR}/presets" "${MLT_DATA_OUTPUT_DIRECTORY}/presets" SYMBOLIC) + file(CREATE_LINK "${CMAKE_SOURCE_DIR}/profiles" "${MLT_DATA_OUTPUT_DIRECTORY}/profiles" SYMBOLIC) +endif() + set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 95a3a9f62..91b556372 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -51,8 +51,9 @@ endif() if(NOT (WIN32 OR APPLE)) target_compile_definitions(mlt PRIVATE - PREFIX_DATA="${CMAKE_INSTALL_FULL_DATADIR}/mlt" - PREFIX_LIB="${CMAKE_INSTALL_FULL_LIBDIR}/mlt") + $ + $ + ) endif() set(MLT_PUPLIC_HEADERS diff --git a/src/modules/avformat/CMakeLists.txt b/src/modules/avformat/CMakeLists.txt index 32a5898f4..426a086c0 100644 --- a/src/modules/avformat/CMakeLists.txt +++ b/src/modules/avformat/CMakeLists.txt @@ -44,8 +44,7 @@ if(TARGET PkgConfig::libswresample) target_compile_definitions(mltavformat PRIVATE SWRESAMPLE) endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltavformat PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltavformat PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltavformat LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/core/CMakeLists.txt b/src/modules/core/CMakeLists.txt index 291ce077c..34424d8c0 100644 --- a/src/modules/core/CMakeLists.txt +++ b/src/modules/core/CMakeLists.txt @@ -55,8 +55,7 @@ if(X86_64) target_sources(mltcore PRIVATE composite_line_yuv_sse2_simple.c) endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltcore PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltcore PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltcore LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/decklink/CMakeLists.txt b/src/modules/decklink/CMakeLists.txt index f40f4b589..af23ac05e 100644 --- a/src/modules/decklink/CMakeLists.txt +++ b/src/modules/decklink/CMakeLists.txt @@ -17,8 +17,7 @@ else() target_include_directories(mltdecklink PRIVATE linux) endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltdecklink PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltdecklink PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltdecklink LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/frei0r/CMakeLists.txt b/src/modules/frei0r/CMakeLists.txt index 97919d7d7..ff545e775 100644 --- a/src/modules/frei0r/CMakeLists.txt +++ b/src/modules/frei0r/CMakeLists.txt @@ -9,8 +9,7 @@ add_library(mltfrei0r MODULE target_link_libraries(mltfrei0r mlt m ${CMAKE_DL_LIBS}) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltfrei0r PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltfrei0r PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltfrei0r LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/gdk/CMakeLists.txt b/src/modules/gdk/CMakeLists.txt index 884a2bd51..dbbe60113 100644 --- a/src/modules/gdk/CMakeLists.txt +++ b/src/modules/gdk/CMakeLists.txt @@ -24,8 +24,7 @@ endif() # Only for MMX but not x86_64: deprecated # target_sources(mltgdk PRIVATE have_mmx.S scale_line_22_yuv_mmx.S) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltgdk PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltgdk PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltgdk LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/jackrack/CMakeLists.txt b/src/modules/jackrack/CMakeLists.txt index f119a9b26..a09649994 100644 --- a/src/modules/jackrack/CMakeLists.txt +++ b/src/modules/jackrack/CMakeLists.txt @@ -25,8 +25,7 @@ if(GPL AND TARGET PkgConfig::xml AND TARGET PkgConfig::glib AND ladspa_h_FOUND) ) endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltjack PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltjack PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltjack LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/kdenlive/CMakeLists.txt b/src/modules/kdenlive/CMakeLists.txt index 527e7b243..113ee082b 100644 --- a/src/modules/kdenlive/CMakeLists.txt +++ b/src/modules/kdenlive/CMakeLists.txt @@ -8,8 +8,7 @@ add_library(mltkdenlive MODULE target_link_libraries(mltkdenlive mlt m) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltkdenlive PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltkdenlive PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltkdenlive LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/motion_est/CMakeLists.txt b/src/modules/motion_est/CMakeLists.txt index 89d16ad4c..66ab03195 100644 --- a/src/modules/motion_est/CMakeLists.txt +++ b/src/modules/motion_est/CMakeLists.txt @@ -10,8 +10,7 @@ add_library(mltmotion_est MODULE target_link_libraries(mltmotion_est mlt m) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltmotion_est PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltmotion_est PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltmotion_est LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/ndi/CMakeLists.txt b/src/modules/ndi/CMakeLists.txt index 862782393..bcc1dd86a 100644 --- a/src/modules/ndi/CMakeLists.txt +++ b/src/modules/ndi/CMakeLists.txt @@ -6,8 +6,7 @@ add_library(mltndi MODULE target_link_libraries(mltndi PRIVATE mlt NDI::NDI) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltndi PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltndi PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltndi LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) install(FILES consumer_ndi.yml producer_ndi.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/ndi) diff --git a/src/modules/normalize/CMakeLists.txt b/src/modules/normalize/CMakeLists.txt index cce6b8926..b44640f0e 100644 --- a/src/modules/normalize/CMakeLists.txt +++ b/src/modules/normalize/CMakeLists.txt @@ -6,8 +6,7 @@ add_library(mltnormalize MODULE target_link_libraries(mltnormalize mlt m) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltnormalize PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltnormalize PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltnormalize LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/oldfilm/CMakeLists.txt b/src/modules/oldfilm/CMakeLists.txt index 8b3db2c11..f434bc731 100644 --- a/src/modules/oldfilm/CMakeLists.txt +++ b/src/modules/oldfilm/CMakeLists.txt @@ -10,8 +10,7 @@ add_library(mltoldfilm MODULE target_link_libraries(mltoldfilm mlt m) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltoldfilm PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltoldfilm PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltoldfilm LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/opencv/CMakeLists.txt b/src/modules/opencv/CMakeLists.txt index 518f3f073..7b195a509 100644 --- a/src/modules/opencv/CMakeLists.txt +++ b/src/modules/opencv/CMakeLists.txt @@ -1,8 +1,7 @@ add_library(mltopencv MODULE factory.c filter_opencv_tracker.cpp) target_link_libraries(mltopencv mlt ${OpenCV_LIBS}) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltopencv PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltopencv PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltopencv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) install(FILES filter_opencv_tracker.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/opencv) diff --git a/src/modules/opengl/CMakeLists.txt b/src/modules/opengl/CMakeLists.txt index e81b3194b..a2533c79c 100644 --- a/src/modules/opengl/CMakeLists.txt +++ b/src/modules/opengl/CMakeLists.txt @@ -33,8 +33,7 @@ endif() pkg_get_variable(SHADERDIR movit shaderdir) target_compile_definitions(mltopengl PRIVATE SHADERDIR="${SHADERDIR}") -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltopengl PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltopengl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltopengl LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/plus/CMakeLists.txt b/src/modules/plus/CMakeLists.txt index 05e04867c..4c9eadd40 100644 --- a/src/modules/plus/CMakeLists.txt +++ b/src/modules/plus/CMakeLists.txt @@ -39,8 +39,7 @@ else() target_compile_definitions(mltplus PRIVATE USE_INTERNAL_LIBEBUR128) endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltplus PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltplus PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltplus LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/plusgpl/CMakeLists.txt b/src/modules/plusgpl/CMakeLists.txt index cb8c5887f..fa3fd3111 100644 --- a/src/modules/plusgpl/CMakeLists.txt +++ b/src/modules/plusgpl/CMakeLists.txt @@ -18,8 +18,7 @@ elseif(UNIX) target_link_libraries(mltplusgpl rt) endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltplusgpl PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltplusgpl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltplusgpl LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/qt/CMakeLists.txt b/src/modules/qt/CMakeLists.txt index b862e3eba..a5f46b654 100644 --- a/src/modules/qt/CMakeLists.txt +++ b/src/modules/qt/CMakeLists.txt @@ -54,8 +54,7 @@ if(TARGET PkgConfig::libexif) target_compile_definitions(mltqt PRIVATE USE_EXIF) endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltqt PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltqt PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltqt LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/resample/CMakeLists.txt b/src/modules/resample/CMakeLists.txt index 997cfbbe3..7ae0ee9d2 100644 --- a/src/modules/resample/CMakeLists.txt +++ b/src/modules/resample/CMakeLists.txt @@ -1,8 +1,7 @@ add_library(mltresample MODULE factory.c filter_resample.c) target_link_libraries(mltresample mlt PkgConfig::samplerate) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltresample PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltresample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltresample LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/rtaudio/CMakeLists.txt b/src/modules/rtaudio/CMakeLists.txt index f11112c3d..c9b5d2612 100644 --- a/src/modules/rtaudio/CMakeLists.txt +++ b/src/modules/rtaudio/CMakeLists.txt @@ -28,8 +28,7 @@ else() endif() endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltrtaudio PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltrtaudio PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltrtaudio LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/rubberband/CMakeLists.txt b/src/modules/rubberband/CMakeLists.txt index 25e9c7cf2..8902382d1 100644 --- a/src/modules/rubberband/CMakeLists.txt +++ b/src/modules/rubberband/CMakeLists.txt @@ -1,8 +1,7 @@ add_library(mltrubberband MODULE factory.c filter_rbpitch.cpp) target_link_libraries(mltrubberband mlt PkgConfig::rubberband) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltrubberband PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltrubberband PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltrubberband LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/sdl/CMakeLists.txt b/src/modules/sdl/CMakeLists.txt index f8b20e15a..4103c954a 100644 --- a/src/modules/sdl/CMakeLists.txt +++ b/src/modules/sdl/CMakeLists.txt @@ -15,8 +15,7 @@ if(TARGET PkgConfig::sdl_image) install(FILES producer_sdl_image.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/sdl) endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltsdl PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltsdl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltsdl LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/sdl2/CMakeLists.txt b/src/modules/sdl2/CMakeLists.txt index 4d1b5bd92..4912b0c50 100644 --- a/src/modules/sdl2/CMakeLists.txt +++ b/src/modules/sdl2/CMakeLists.txt @@ -7,8 +7,7 @@ add_library(mltsdl2 MODULE target_link_libraries(mltsdl2 mlt m Threads::Threads sdl2) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltsdl2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltsdl2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltsdl2 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/sox/CMakeLists.txt b/src/modules/sox/CMakeLists.txt index 8377a38e9..1b122a057 100644 --- a/src/modules/sox/CMakeLists.txt +++ b/src/modules/sox/CMakeLists.txt @@ -5,8 +5,7 @@ if(${sox_VERSION} GREATER 13) target_compile_definitions(mltsox PRIVATE SOX14) endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltsox PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltsox PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltsox LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/vid.stab/CMakeLists.txt b/src/modules/vid.stab/CMakeLists.txt index f3f2fec8a..90bde8dcc 100644 --- a/src/modules/vid.stab/CMakeLists.txt +++ b/src/modules/vid.stab/CMakeLists.txt @@ -7,8 +7,7 @@ add_library(mltvidstab MODULE target_link_libraries(mltvidstab mlt m mlt++ PkgConfig::vidstab) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltvidstab PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltvidstab PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltvidstab LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/vmfx/CMakeLists.txt b/src/modules/vmfx/CMakeLists.txt index f3a8b5241..22700641a 100644 --- a/src/modules/vmfx/CMakeLists.txt +++ b/src/modules/vmfx/CMakeLists.txt @@ -9,8 +9,7 @@ add_library(mltvmfx MODULE target_link_libraries(mltvmfx mlt) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltvmfx PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltvmfx PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltvmfx LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/vorbis/CMakeLists.txt b/src/modules/vorbis/CMakeLists.txt index 806383069..1c25c1fb0 100644 --- a/src/modules/vorbis/CMakeLists.txt +++ b/src/modules/vorbis/CMakeLists.txt @@ -1,8 +1,7 @@ add_library(mltvorbis MODULE factory.c producer_vorbis.c) target_link_libraries(mltvorbis mlt PkgConfig::vorbis PkgConfig::vorbisfile) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltvorbis PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltvorbis PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltvorbis LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/xine/CMakeLists.txt b/src/modules/xine/CMakeLists.txt index 92a439940..34f06e528 100644 --- a/src/modules/xine/CMakeLists.txt +++ b/src/modules/xine/CMakeLists.txt @@ -19,7 +19,6 @@ if(X86_64) endif() endif() -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltxine PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltxine PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltxine LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/xml/CMakeLists.txt b/src/modules/xml/CMakeLists.txt index c8153edca..6540fa740 100644 --- a/src/modules/xml/CMakeLists.txt +++ b/src/modules/xml/CMakeLists.txt @@ -7,8 +7,7 @@ add_library(mltxml MODULE target_link_libraries(mltxml mlt Threads::Threads PkgConfig::xml) -# Create module in parent directory, for the benefit of "source setenv". -set_target_properties(mltxml PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..) +set_target_properties(mltxml PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltxml LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index d8fd9f330..f3ce0543b 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -4,8 +4,9 @@ foreach(QT_TEST_NAME animation audio events filter frame playlist properties rep add_executable(test_${QT_TEST_NAME} test_${QT_TEST_NAME}/test_${QT_TEST_NAME}.cpp) target_link_libraries(test_${QT_TEST_NAME} PRIVATE Qt5::Core Qt5::Test mlt++) add_test(NAME "QtTest:${QT_TEST_NAME}" COMMAND test_${QT_TEST_NAME}) - set_tests_properties("QtTest:${QT_TEST_NAME}" PROPERTIES - ENVIRONMENT "LANG=en_US;MLT_REPOSITORY=${CMAKE_BINARY_DIR}/src/modules;MLT_DATA=${CMAKE_SOURCE_DIR}/src/modules;MLT_PROFILES_PATH=${CMAKE_SOURCE_DIR}/profiles;MLT_PRESETS_PATH=${CMAKE_SOURCE_DIR}/presets") + if(NOT WIN32) + set_tests_properties("QtTest:${QT_TEST_NAME}" PROPERTIES ENVIRONMENT "LANG=en_US") + endif() endforeach() file(GLOB YML_FILES "${CMAKE_SOURCE_DIR}/src/modules/*/*.yml") From 779b7b6b3f05286075be18c9c98ae16498630c7a Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Thu, 18 Feb 2021 02:10:32 +0100 Subject: [PATCH 038/122] cmake: add --version-script --- src/framework/CMakeLists.txt | 2 ++ src/mlt++/CMakeLists.txt | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 91b556372..3bf0723dd 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -54,6 +54,8 @@ if(NOT (WIN32 OR APPLE)) $ $ ) + target_link_options(mlt PRIVATE -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/mlt.vers) + set_target_properties(mlt PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mlt.vers) endif() set(MLT_PUPLIC_HEADERS diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index 456eeff51..f1cdbac5f 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -41,6 +41,11 @@ if(WIN32) target_compile_definitions(mlt++ PUBLIC MLTPP_EXPORTS) endif() +if(NOT (WIN32 OR APPLE)) + target_link_options(mlt++ PRIVATE -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/mlt++.vers) + set_target_properties(mlt++ PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mlt++.vers) +endif() + set(MLTPP_PUPLIC_HEADERS Mlt.h MltAnimation.h From 8ba5235dbded55d5f4e04bb9803f07bede14c9b8 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Thu, 18 Feb 2021 12:16:46 +0100 Subject: [PATCH 039/122] cmake: MinGW: install unversioned DLLs --- src/framework/CMakeLists.txt | 6 ++++++ src/mlt++/CMakeLists.txt | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 3bf0723dd..b6fa3e15a 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -42,6 +42,12 @@ set_target_properties(mlt PROPERTIES SOVERSION ${MLT_VERSION_MAJOR} VERSION ${ML if(WIN32) set_target_properties(mlt PROPERTIES OUTPUT_NAME "mlt-${MLT_VERSION_MAJOR}") + if(MINGW) + install(FILES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libmlt-${MLT_VERSION_MAJOR}.dll" + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RENAME libmlt.dll + ) + endif() target_sources(mlt PRIVATE ../win32/win32.c ../win32/strptime.c) target_link_libraries(mlt Iconv::Iconv) if(NOT WINDOWS_DEPLOY) diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index f1cdbac5f..cdacd87ea 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -38,6 +38,12 @@ set_target_properties(mlt++ PROPERTIES SOVERSION ${MLT_VERSION_MAJOR} VERSION ${ if(WIN32) set_target_properties(mlt++ PROPERTIES OUTPUT_NAME "mlt++-${MLT_VERSION_MAJOR}") + if(MINGW) + install(FILES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libmlt++-${MLT_VERSION_MAJOR}.dll" + DESTINATION ${CMAKE_INSTALL_LIBDIR} + RENAME libmlt++.dll + ) + endif() target_compile_definitions(mlt++ PUBLIC MLTPP_EXPORTS) endif() From 45bff15028cd42d6da5af33ab653f4d39016c455 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Thu, 18 Feb 2021 22:00:08 -0600 Subject: [PATCH 040/122] Fix loading link in/out points from XML --- src/modules/xml/producer_xml.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/xml/producer_xml.c b/src/modules/xml/producer_xml.c index dd605924f..0da55e05a 100644 --- a/src/modules/xml/producer_xml.c +++ b/src/modules/xml/producer_xml.c @@ -691,7 +691,11 @@ static void on_start_link( deserialise_context context, const xmlChar *name, con // Store properties until the service type is known mlt_service service = calloc( 1, sizeof( struct mlt_service_s ) ); mlt_service_init( service, NULL ); + mlt_properties properties = MLT_SERVICE_PROPERTIES( service ); context_push_service( context, service, mlt_link_type ); + + for ( ; atts != NULL && *atts != NULL; atts += 2 ) + mlt_properties_set_string( properties, (const char*) atts[0], atts[1] == NULL ? "" : (const char*) atts[1] ); } static void on_end_link( deserialise_context context, const xmlChar *name ) From d6f480a2067c14bd3d38ce141c26c5e44662048a Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Fri, 19 Feb 2021 21:11:23 -0600 Subject: [PATCH 041/122] Fix chain/link related compiler warnings --- src/framework/mlt_link.c | 2 +- src/framework/mlt_parser.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/framework/mlt_link.c b/src/framework/mlt_link.c index b02fba391..13f340b58 100644 --- a/src/framework/mlt_link.c +++ b/src/framework/mlt_link.c @@ -158,7 +158,7 @@ int producer_set_in_and_out( mlt_producer parent, mlt_position in, mlt_position if ( parent && parent->child ) { mlt_link self = parent->child; - mlt_properties properties = MLT_PRODUCER_PROPERTIES( self ); + mlt_properties properties = MLT_LINK_PROPERTIES( self ); mlt_events_block( properties, properties ); mlt_properties_set_position( properties, "in", in ); mlt_events_unblock( properties, properties ); diff --git a/src/framework/mlt_parser.c b/src/framework/mlt_parser.c index 09a0f2549..0acbec50c 100644 --- a/src/framework/mlt_parser.c +++ b/src/framework/mlt_parser.c @@ -258,11 +258,11 @@ int mlt_parser_start( mlt_parser self, mlt_service object ) if ( error == 0 ) { int i = 0; - while ( error == 0 && i < mlt_chain_link( ( mlt_chain )object, i ) != NULL ) + while ( error == 0 && mlt_chain_link( ( mlt_chain )object, i ) != NULL ) mlt_parser_start( self, ( mlt_service )mlt_chain_link( ( mlt_chain )object, i ++ ) ); i = 0; - while ( error == 0 && mlt_producer_filter( MLT_CHAIN_PRODUCER(object), i ) != NULL ) - error = mlt_parser_start( self, ( mlt_service )mlt_producer_filter( MLT_CHAIN_PRODUCER(object), i ++ ) ); + while ( error == 0 && mlt_producer_filter( ( mlt_producer )object, i ) != NULL ) + error = mlt_parser_start( self, ( mlt_service )mlt_producer_filter( ( mlt_producer )object, i ++ ) ); } error = self->on_end_chain( self, ( mlt_chain )object ); break; From 3de7b3e8d1b5a1229d95142ad2a5e4f8164726b7 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Fri, 19 Feb 2021 21:30:33 -0600 Subject: [PATCH 042/122] Fix compile warning in rb_pitch --- src/modules/rubberband/filter_rbpitch.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/rubberband/filter_rbpitch.cpp b/src/modules/rubberband/filter_rbpitch.cpp index 03db48893..20a8a9cf9 100644 --- a/src/modules/rubberband/filter_rbpitch.cpp +++ b/src/modules/rubberband/filter_rbpitch.cpp @@ -171,7 +171,7 @@ static int rbpitch_get_audio( mlt_frame frame, void **buffer, mlt_audio_format * mlt_service_unlock( MLT_FILTER_SERVICE(filter) ); - mlt_log_debug( MLT_FILTER_SERVICE(filter), "Requested: %d\tReceived: %d\tSent: %d\tLatency: %d(%fms)\n", requested_samples, in.samples, out.samples, (pdata->in_samples - pdata->out_samples), latency ); + mlt_log_debug( MLT_FILTER_SERVICE(filter), "Requested: %d\tReceived: %d\tSent: %d\tLatency: %d(%fms)\n", requested_samples, in.samples, out.samples, (int)(pdata->in_samples - pdata->out_samples), latency ); return error; } From 4013f16556ac1535d6721546c7478d68654e44c1 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Sat, 20 Feb 2021 16:50:33 -0800 Subject: [PATCH 043/122] fix metadata schema version error --- src/framework/metaschema.yaml | 2 +- src/modules/core/link_timeremap.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/framework/metaschema.yaml b/src/framework/metaschema.yaml index 1c5fd8fba..5d9820273 100644 --- a/src/framework/metaschema.yaml +++ b/src/framework/metaschema.yaml @@ -1,5 +1,5 @@ --- # A metadata schema in Kwalify: http://www.kuwata-lab.com/kwalify/ -# Version: 7 +# Version: 7.0 type: map mapping: "schema_version": # This should match the version comment above diff --git a/src/modules/core/link_timeremap.yml b/src/modules/core/link_timeremap.yml index 4b087f2c6..b72ffbff6 100644 --- a/src/modules/core/link_timeremap.yml +++ b/src/modules/core/link_timeremap.yml @@ -1,4 +1,4 @@ -schema_version: 7 +schema_version: 7.0 type: link identifier: timeremap title: Time Remap From bb41369c10ddc749042f6f570293431a3e2594de Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 15 Feb 2021 09:49:20 -0600 Subject: [PATCH 044/122] Convert spaces to tabs in animation test --- src/tests/test_animation/test_animation.cpp | 36 ++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/tests/test_animation/test_animation.cpp b/src/tests/test_animation/test_animation.cpp index 101e55ac4..6937c7761 100644 --- a/src/tests/test_animation/test_animation.cpp +++ b/src/tests/test_animation/test_animation.cpp @@ -297,8 +297,8 @@ private Q_SLOTS: void SerializesInTimeFormat() { Profile profile; - Properties p; - p.set("_profile", profile.get_profile(), 0); + Properties p; + p.set("_profile", profile.get_profile(), 0); p.set("foo", "50=100; 60=60; 100=0"); // Cause the string to be interpreted as animated value. p.anim_get("foo", 0); @@ -311,8 +311,8 @@ private Q_SLOTS: void GetPropertyInTimeFormat() { Profile profile; - Properties p; - p.set("_profile", profile.get_profile(), 0); + Properties p; + p.set("_profile", profile.get_profile(), 0); p.set("foo", "50=100; 60=60; 100=0"); // Cause the string to be interpreted as animated value. p.anim_get_int("foo", 0); @@ -338,21 +338,21 @@ private Q_SLOTS: p.clear("foo"); QCOMPARE(p.get_animation("foo"), mlt_animation(0)); } - - void CanBeEscapedWithQuotes() - { - Properties p; - p.set("foo", "\"50=100; 60=60; 100=0\""); - // Quotes are retained when using the non-anim getter. - QCOMPARE(p.get("foo"), "\"50=100; 60=60; 100=0\""); - // Quotes are removed when using the anim getter. + + void CanBeEscapedWithQuotes() + { + Properties p; + p.set("foo", "\"50=100; 60=60; 100=0\""); + // Quotes are retained when using the non-anim getter. + QCOMPARE(p.get("foo"), "\"50=100; 60=60; 100=0\""); + // Quotes are removed when using the anim getter. QCOMPARE(p.anim_get("foo", 0), "50=100; 60=60; 100=0"); - // Anim strings may contain delimiters and equal signs if quoted. - p.set("foo", "50=100; 60=\"60; 100=0\";\"hello=world\""); - QCOMPARE(p.anim_get("foo", 0), "hello=world"); - QCOMPARE(p.anim_get("foo", 50), "100"); - QCOMPARE(p.anim_get("foo", 60), "60; 100=0"); - } + // Anim strings may contain delimiters and equal signs if quoted. + p.set("foo", "50=100; 60=\"60; 100=0\";\"hello=world\""); + QCOMPARE(p.anim_get("foo", 0), "hello=world"); + QCOMPARE(p.anim_get("foo", 50), "100"); + QCOMPARE(p.anim_get("foo", 60), "60; 100=0"); + } }; QTEST_APPLESS_MAIN(TestAnimation) From 4336c61ca26949fad42ec98b1e6c4c77700655ca Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 15 Feb 2021 11:56:32 -0600 Subject: [PATCH 045/122] Add frame shift to Animations --- src/framework/mlt.vers | 1 + src/framework/mlt_animation.c | 17 ++++++++++++ src/framework/mlt_animation.h | 1 + src/mlt++/MltAnimation.cpp | 5 ++++ src/mlt++/MltAnimation.h | 2 +- src/mlt++/mlt++.vers | 1 + src/tests/test_animation/test_animation.cpp | 30 +++++++++++++++++++++ 7 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index 9af69a788..0456bffef 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -593,4 +593,5 @@ MLT_7.0.0 { mlt_link_connect_next; mlt_link_close; mlt_repository_links; + mlt_animation_shift_frames; } MLT_6.22.0; diff --git a/src/framework/mlt_animation.c b/src/framework/mlt_animation.c index 18604761a..670d1ace8 100644 --- a/src/framework/mlt_animation.c +++ b/src/framework/mlt_animation.c @@ -934,3 +934,20 @@ int mlt_animation_key_set_frame(mlt_animation self, int index, int frame) return error; } + +/** Shift the frame value for all nodes. + * + * \public \memberof mlt_animation_s + * \param self an animation + * \param shift the value to add to all frame values + */ + +void mlt_animation_shift_frames( mlt_animation self, int shift ) +{ + animation_node node = self->nodes; + while ( node ) { + node->item.frame += shift; + node = node->next; + } + mlt_animation_interpolate(self); +} diff --git a/src/framework/mlt_animation.h b/src/framework/mlt_animation.h index 48d478ce6..ad5f3b3e6 100644 --- a/src/framework/mlt_animation.h +++ b/src/framework/mlt_animation.h @@ -69,6 +69,7 @@ extern int mlt_animation_key_get( mlt_animation self, mlt_animation_item item, i extern void mlt_animation_close( mlt_animation self ); extern int mlt_animation_key_set_type( mlt_animation self, int index, mlt_keyframe_type type ); extern int mlt_animation_key_set_frame( mlt_animation self, int index, int frame ); +extern void mlt_animation_shift_frames( mlt_animation self, int shift ); #endif diff --git a/src/mlt++/MltAnimation.cpp b/src/mlt++/MltAnimation.cpp index d11e97e67..099f6d5a6 100644 --- a/src/mlt++/MltAnimation.cpp +++ b/src/mlt++/MltAnimation.cpp @@ -174,6 +174,11 @@ int Animation::key_set_frame(int index, int frame) return mlt_animation_key_set_frame(instance, index, frame); } +void Animation::shift_frames( int shift ) +{ + return mlt_animation_shift_frames(instance, shift); +} + void Animation::set_length( int length ) { return mlt_animation_set_length( instance, length ); diff --git a/src/mlt++/MltAnimation.h b/src/mlt++/MltAnimation.h index e989ceaba..02d173d54 100644 --- a/src/mlt++/MltAnimation.h +++ b/src/mlt++/MltAnimation.h @@ -52,7 +52,7 @@ namespace Mlt mlt_keyframe_type key_get_type( int index ); int key_set_type( int index, mlt_keyframe_type type ); int key_set_frame( int index, int frame ); - + void shift_frames( int shift ); void set_length( int length ); int remove( int position ); void interpolate(); diff --git a/src/mlt++/mlt++.vers b/src/mlt++/mlt++.vers index debe6c841..a2da7e218 100644 --- a/src/mlt++/mlt++.vers +++ b/src/mlt++/mlt++.vers @@ -654,5 +654,6 @@ MLTPP_7.0.0 { "Mlt::Parser::on_end_chain(Mlt::Chain*)"; "Mlt::Parser::on_start_link(Mlt::Link*)"; "Mlt::Parser::on_end_link(Mlt::Link*)"; + "Mlt::Animation::shift_frames(int)"; }; } MLTPP_6.22.0; diff --git a/src/tests/test_animation/test_animation.cpp b/src/tests/test_animation/test_animation.cpp index 6937c7761..6d412fdd9 100644 --- a/src/tests/test_animation/test_animation.cpp +++ b/src/tests/test_animation/test_animation.cpp @@ -353,6 +353,36 @@ private Q_SLOTS: QCOMPARE(p.anim_get("foo", 50), "100"); QCOMPARE(p.anim_get("foo", 60), "60; 100=0"); } + + void ShiftFramesPositive() + { + Properties p; + p.set("foo", "50=100; 60=60; 100=0"); + // Cause the string to be interpreted as animated value. + p.anim_get_int("foo", 0); + Animation a = p.get_animation("foo"); + QVERIFY(a.is_valid()); + a.shift_frames( 60 ); + QCOMPARE(a.key_get_frame(0), 110); + QCOMPARE(a.key_get_frame(1), 120); + QCOMPARE(a.key_get_frame(2), 160); + QCOMPARE(a.key_get_frame(3), -1); + } + + void ShiftFramesNegative() + { + Properties p; + p.set("foo", "50=100; 60=60; 100=0"); + // Cause the string to be interpreted as animated value. + p.anim_get_int("foo", 0); + Animation a = p.get_animation("foo"); + QVERIFY(a.is_valid()); + a.shift_frames( -60 ); + QCOMPARE(a.key_get_frame(0), -10); + QCOMPARE(a.key_get_frame(1), 0); + QCOMPARE(a.key_get_frame(2), 40); + QCOMPARE(a.key_get_frame(3), -1); + } }; QTEST_APPLESS_MAIN(TestAnimation) From a602977e535b395167ff6b79a277f5e503262c50 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 28 Feb 2021 22:09:21 -0600 Subject: [PATCH 046/122] Do not use stale cached animation string A property now detects that an animation has been changed and does not use the stale cached property string. --- src/framework/mlt.vers | 1 + src/framework/mlt_animation.c | 40 ++++++++++++- src/framework/mlt_animation.h | 1 + src/framework/mlt_property.c | 47 ++++++++++++--- src/tests/test_properties/test_properties.cpp | 59 +++++++++++++++++++ 5 files changed, 138 insertions(+), 10 deletions(-) diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index 0456bffef..6c8648e66 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -594,4 +594,5 @@ MLT_7.0.0 { mlt_link_close; mlt_repository_links; mlt_animation_shift_frames; + mlt_animation_get_string; } MLT_6.22.0; diff --git a/src/framework/mlt_animation.c b/src/framework/mlt_animation.c index 670d1ace8..d3fb9af71 100644 --- a/src/framework/mlt_animation.c +++ b/src/framework/mlt_animation.c @@ -54,6 +54,8 @@ struct mlt_animation_s animation_node nodes; /**< a linked list of keyframes (and possibly non-keyframe values) */ }; +static void mlt_animation_clear_string( mlt_animation self ); + /** Create a new animation object. * * \public \memberof mlt_animation_s @@ -301,8 +303,10 @@ int mlt_animation_get_length( mlt_animation self ) void mlt_animation_set_length( mlt_animation self, int length ) { - if ( self ) + if ( self ) { self->length = length; + mlt_animation_clear_string( self ); + } } /** Parse a string representing an animation keyframe=value. @@ -519,6 +523,7 @@ int mlt_animation_insert( mlt_animation self, mlt_animation_item item ) // Set the first item self->nodes = node; } + mlt_animation_clear_string( self ); return error; } @@ -544,6 +549,8 @@ int mlt_animation_remove( mlt_animation self, int position ) if ( node && position == node->item.frame ) error = mlt_animation_drop( self, node ); + mlt_animation_clear_string( self ); + return error; } @@ -897,6 +904,7 @@ int mlt_animation_key_set_type(mlt_animation self, int index, mlt_keyframe_type if ( node ) { node->item.keyframe_type = type; mlt_animation_interpolate(self); + mlt_animation_clear_string( self ); } else { error = 1; } @@ -928,6 +936,7 @@ int mlt_animation_key_set_frame(mlt_animation self, int index, int frame) if ( node ) { node->item.frame = frame; mlt_animation_interpolate(self); + mlt_animation_clear_string( self ); } else { error = 1; } @@ -949,5 +958,34 @@ void mlt_animation_shift_frames( mlt_animation self, int shift ) node->item.frame += shift; node = node->next; } + mlt_animation_clear_string( self ); mlt_animation_interpolate(self); } + +/** Get the cached serialization string. + * + * This can be used to determine if the animation has been modified because the + * string is cleared whenever the animation is changed. + * \public \memberof mlt_animation_s + * \param self an animation + * \return the cached serialization string + */ + +const char* mlt_animation_get_string( mlt_animation self ) +{ + if (!self) return NULL; + return self->data; +} + +/** Clear the cached serialization string. + * + * \private \memberof mlt_animation_s + * \param self an animation + */ + +void mlt_animation_clear_string( mlt_animation self ) +{ + if (!self) return; + free( self->data ); + self->data = NULL; +} diff --git a/src/framework/mlt_animation.h b/src/framework/mlt_animation.h index ad5f3b3e6..107f63d04 100644 --- a/src/framework/mlt_animation.h +++ b/src/framework/mlt_animation.h @@ -70,6 +70,7 @@ extern void mlt_animation_close( mlt_animation self ); extern int mlt_animation_key_set_type( mlt_animation self, int index, mlt_keyframe_type type ); extern int mlt_animation_key_set_frame( mlt_animation self, int index, int frame ); extern void mlt_animation_shift_frames( mlt_animation self, int shift ); +extern const char* mlt_animation_get_string( mlt_animation self ); #endif diff --git a/src/framework/mlt_property.c b/src/framework/mlt_property.c index b480bf018..bcc8909a8 100644 --- a/src/framework/mlt_property.c +++ b/src/framework/mlt_property.c @@ -494,8 +494,13 @@ int mlt_property_get_int( mlt_property self, double fps, locale_t locale ) result = ( int )self->prop_int64; else if ( self->types & mlt_prop_rect && self->data ) result = ( int ) ( (mlt_rect*) self->data )->x; - else if ( ( self->types & mlt_prop_string ) && self->prop_string ) - result = mlt_property_atoi( self, fps, locale ); + else + { + if ( self->animation && !mlt_animation_get_string(self->animation) ) + mlt_property_get_string( self ); + if ( ( self->types & mlt_prop_string ) && self->prop_string ) + result = mlt_property_atoi( self, fps, locale ); + } pthread_mutex_unlock( &self->mutex ); return result; } @@ -517,7 +522,7 @@ static double mlt_property_atof( mlt_property self, double fps, locale_t locale { const char *value = self->prop_string; - if ( fps > 0 && strchr( value, ':' ) ) + if ( fps > 0 && strchr( value, ':' ) ) { if ( strchr( value, '.' ) || strchr( value, ',' ) ) return time_clock_to_frames( self, value, fps, locale ); @@ -587,8 +592,13 @@ double mlt_property_get_double( mlt_property self, double fps, locale_t locale ) result = ( double )self->prop_int64; else if ( self->types & mlt_prop_rect && self->data ) result = ( (mlt_rect*) self->data )->x; - else if ( ( self->types & mlt_prop_string ) && self->prop_string ) - result = mlt_property_atof( self, fps, locale ); + else + { + if ( self->animation && !mlt_animation_get_string(self->animation) ) + mlt_property_get_string( self ); + if ( ( self->types & mlt_prop_string ) && self->prop_string ) + result = mlt_property_atof( self, fps, locale ); + } pthread_mutex_unlock( &self->mutex ); return result; } @@ -617,8 +627,13 @@ mlt_position mlt_property_get_position( mlt_property self, double fps, locale_t result = ( mlt_position )self->prop_int64; else if ( self->types & mlt_prop_rect && self->data ) result = ( mlt_position ) ( (mlt_rect*) self->data )->x; - else if ( ( self->types & mlt_prop_string ) && self->prop_string ) - result = ( mlt_position )mlt_property_atoi( self, fps, locale ); + else + { + if ( self->animation && !mlt_animation_get_string(self->animation) ) + mlt_property_get_string( self ); + if ( ( self->types & mlt_prop_string ) && self->prop_string ) + result = ( mlt_position )mlt_property_atoi( self, fps, locale ); + } pthread_mutex_unlock( &self->mutex ); return result; } @@ -662,8 +677,13 @@ int64_t mlt_property_get_int64( mlt_property self ) result = ( int64_t )self->prop_position; else if ( self->types & mlt_prop_rect && self->data ) result = ( int64_t ) ( (mlt_rect*) self->data )->x; - else if ( ( self->types & mlt_prop_string ) && self->prop_string ) - result = mlt_property_atoll( self->prop_string ); + else + { + if ( self->animation && !mlt_animation_get_string(self->animation) ) + mlt_property_get_string( self ); + if ( ( self->types & mlt_prop_string ) && self->prop_string ) + result = mlt_property_atoll( self->prop_string ); + } pthread_mutex_unlock( &self->mutex ); return result; } @@ -1323,6 +1343,15 @@ static void refresh_animation( mlt_property self, double fps, locale_t locale, i self->serialiser = (mlt_serialiser) mlt_animation_serialize_tf; mlt_animation_parse( self->animation, self->prop_string, length, fps, locale ); } + else if ( !mlt_animation_get_string( self->animation ) ) + { + // The animation clears its string if it is modified. + // Do not use a property string that is out of sync. + self->types &= ~mlt_prop_string; + if ( self->prop_string ) + free( self->prop_string ); + self->prop_string = NULL; + } else if ( ( self->types & mlt_prop_string ) && self->prop_string ) { mlt_animation_refresh( self->animation, self->prop_string, length ); diff --git a/src/tests/test_properties/test_properties.cpp b/src/tests/test_properties/test_properties.cpp index f13c347b9..ed7b1e9ca 100644 --- a/src/tests/test_properties/test_properties.cpp +++ b/src/tests/test_properties/test_properties.cpp @@ -919,6 +919,65 @@ private Q_SLOTS: QCOMPARE(p.anim_get("key", 45), "hello world"); } + + void PropertyRefreshOnAnimationChange() + { + // Create an animation property from string and see that it works. + // Get the animation and modify the first position. + // Ensure that change affects other get() functions + + { + Properties p; + p.set("foo", "10=100; 20=200"); + QCOMPARE(p.get_double("foo"), 10.0); + // Call anim_get_double() to create the animation + QCOMPARE(p.anim_get_double("foo", 15, 20 ), 150.0); + Mlt::Animation animation = p.get_animation("foo"); + animation.key_set_frame(0, 15); + QCOMPARE(p.get_double("foo"), 15.0); + } + + { + Properties p; + p.set("foo", "10=100;20=200"); + QCOMPARE(p.anim_get_double("foo", 15, 20 ), 150.0); + Mlt::Animation animation = p.get_animation("foo"); + animation.key_set_frame(0, 15); + QCOMPARE(p.anim_get_double("foo", 15, 0 ), 100.0); + } + + { + Properties p; + p.set("foo", "10=100; 20=200"); + QCOMPARE(p.get_int("foo"), 10); + // Call anim_get_int() to create the animation + QCOMPARE(p.anim_get_int("foo", 15, 20 ), 150); + Mlt::Animation animation = p.get_animation("foo"); + animation.key_set_frame(0, 15); + QCOMPARE(p.get_int("foo"), 15); + } + + { + Properties p; + p.set("foo", "10=100; 20=200"); + QCOMPARE(p.anim_get_int("foo", 15, 20 ), 150); + Mlt::Animation animation = p.get_animation("foo"); + animation.key_set_frame(0, 15); + QCOMPARE(p.anim_get_int("foo", 15, 0 ), 100); + } + + { + Properties p; + p.set("foo", "10=100;20=200"); + // Call anim_get_int() to create the animation + QCOMPARE(p.anim_get_int("foo", 15, 20 ), 150); + Mlt::Animation animation = p.get_animation("foo"); + QCOMPARE(p.get("foo"), "10=100;20=200"); + animation.key_set_frame(0, 15); + QCOMPARE(p.get("foo"), "15=100;20=200"); + } + } + void test_mlt_rect() { mlt_property p = mlt_property_init(); From 1b08724f23bbd62ce3001677af0f28ff542a664d Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 7 Feb 2021 21:52:43 -0600 Subject: [PATCH 047/122] Add new MLT Image class --- src/framework/CMakeLists.txt | 2 + src/framework/Makefile | 2 + src/framework/mlt.h | 1 + src/framework/mlt.vers | 7 + src/framework/mlt_frame.c | 218 ++------------------ src/framework/mlt_frame.h | 4 - src/framework/mlt_image.c | 374 +++++++++++++++++++++++++++++++++++ src/framework/mlt_image.h | 60 ++++++ src/framework/mlt_types.h | 1 + 9 files changed, 463 insertions(+), 206 deletions(-) create mode 100644 src/framework/mlt_image.c create mode 100644 src/framework/mlt_image.h diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index b6fa3e15a..7753c5676 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -11,6 +11,7 @@ add_library(mlt SHARED mlt_filter.c mlt_frame.c mlt_geometry.c + mlt_image.c mlt_link.c mlt_log.c mlt_luma_map.c @@ -78,6 +79,7 @@ set(MLT_PUPLIC_HEADERS mlt_filter.h mlt_frame.h mlt_geometry.h + mlt_image.h mlt_link.h mlt_log.h mlt_luma_map.h diff --git a/src/framework/Makefile b/src/framework/Makefile index d083728c1..89c37d2a3 100644 --- a/src/framework/Makefile +++ b/src/framework/Makefile @@ -25,6 +25,7 @@ SHFLAGS += -Wl,--version-script=mlt.vers endif OBJS = mlt_audio.o \ + mlt_image.o \ mlt_frame.o \ mlt_version.o \ mlt_geometry.o \ @@ -56,6 +57,7 @@ OBJS = mlt_audio.o \ mlt_chain.o INCS = mlt_audio.h \ + mlt_image.h \ mlt_consumer.h \ mlt_version.h \ mlt_factory.h \ diff --git a/src/framework/mlt.h b/src/framework/mlt.h index 5f18feff7..b9bff3f93 100644 --- a/src/framework/mlt.h +++ b/src/framework/mlt.h @@ -40,6 +40,7 @@ extern "C" #include "mlt_audio.h" #include "mlt_factory.h" #include "mlt_frame.h" +#include "mlt_image.h" #include "mlt_deque.h" #include "mlt_multitrack.h" #include "mlt_producer.h" diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index 6c8648e66..b943968e5 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -595,4 +595,11 @@ MLT_7.0.0 { mlt_repository_links; mlt_animation_shift_frames; mlt_animation_get_string; + mlt_image_new; + mlt_image_close; + mlt_image_set_values; + mlt_image_get_values; + mlt_image_alloc_data; + mlt_image_calculate_size; + mlt_image_fill_black; } MLT_6.22.0; diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 8f395479a..54698a5a6 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -21,6 +21,7 @@ */ #include "mlt_frame.h" +#include "mlt_image.h" #include "mlt_producer.h" #include "mlt_factory.h" #include "mlt_profile.h" @@ -391,93 +392,6 @@ void mlt_frame_replace_image( mlt_frame self, uint8_t *image, mlt_image_format f self->get_alpha_mask = NULL; } -/** Get the short name for an image format. - * - * \public \memberof mlt_frame_s - * \param format the image format - * \return a string - */ - -const char * mlt_image_format_name( mlt_image_format format ) -{ - switch ( format ) - { - case mlt_image_none: return "none"; - case mlt_image_rgb24: return "rgb24"; - case mlt_image_rgb24a: return "rgb24a"; - case mlt_image_yuv422: return "yuv422"; - case mlt_image_yuv420p: return "yuv420p"; - case mlt_image_opengl: return "opengl"; - case mlt_image_glsl: return "glsl"; - case mlt_image_glsl_texture: return "glsl_texture"; - case mlt_image_yuv422p16: return "yuv422p16"; - case mlt_image_invalid: return "invalid"; - } - return "invalid"; -} - -/** Get the id of image format from short name. - * - * \public \memberof mlt_frame_s - * \param name the image format short name - * \return a image format - */ - -mlt_image_format mlt_image_format_id( const char * name ) -{ - mlt_image_format f; - - for( f = mlt_image_none; name && f < mlt_image_invalid; f++ ) - { - const char * v = mlt_image_format_name( f ); - if( !strcmp( v, name ) ) - return f; - } - - return mlt_image_invalid; -} - -/** Get the number of bytes needed for an image. - * - * \public \memberof mlt_frame_s - * \param format the image format - * \param width width of the image in pixels - * \param height height of the image in pixels - * \param[out] bpp the number of bytes per pixel (optional) - * \return the number of bytes - */ -int mlt_image_format_size( mlt_image_format format, int width, int height, int *bpp ) -{ - height += 1; - switch ( format ) - { - case mlt_image_rgb24: - if ( bpp ) *bpp = 3; - return width * height * 3; - case mlt_image_opengl: - case mlt_image_rgb24a: - if ( bpp ) *bpp = 4; - return width * height * 4; - case mlt_image_yuv422: - if ( bpp ) *bpp = 2; - return width * height * 2; - case mlt_image_yuv420p: - if ( bpp ) *bpp = 3 / 2; - return width * height * 3 / 2; - case mlt_image_glsl: - case mlt_image_glsl_texture: - if ( bpp ) *bpp = 0; - return 4; - case mlt_image_yuv422p16: - if ( bpp ) *bpp = 0; - return 4 * height * width ; - default: - if ( bpp ) *bpp = 0; - return 0; - } - return 0; -} - static int generate_test_image( mlt_properties properties, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) { mlt_producer producer = mlt_properties_get_data( properties, "test_card_producer", NULL ); @@ -511,75 +425,35 @@ static int generate_test_image( mlt_properties properties, uint8_t **buffer, ml } if ( error && buffer ) { - int size = 0; - *width = *width == 0 ? 720 : *width; *height = *height == 0 ? 576 : *height; - size = *width * *height; - - mlt_properties_set_int( properties, "format", *format ); - mlt_properties_set_int( properties, "width", *width ); - mlt_properties_set_int( properties, "height", *height ); - mlt_properties_set_double( properties, "aspect_ratio", 1.0 ); - switch( *format ) { case mlt_image_rgb24: - size *= 3; - size += *width * 3; - *buffer = mlt_pool_alloc( size ); - if ( *buffer ) - memset( *buffer, 255, size ); - break; case mlt_image_rgb24a: case mlt_image_opengl: - size *= 4; - size += *width * 4; - *buffer = mlt_pool_alloc( size ); - if ( *buffer ) - memset( *buffer, 255, size ); + case mlt_image_yuv422: + case mlt_image_yuv422p16: + case mlt_image_yuv420p: break; case mlt_image_none: case mlt_image_glsl: case mlt_image_glsl_texture: *format = mlt_image_yuv422; - case mlt_image_yuv422: - size *= 2; - size += *width * 2; - *buffer = mlt_pool_alloc( size ); - if ( *buffer ) - { - register uint8_t *p = *buffer; - register uint8_t *q = p + size; - while ( p != NULL && p != q ) - { - *p ++ = 235; - *p ++ = 128; - } - } - break; - case mlt_image_yuv422p16: - case mlt_image_yuv420p: - size = mlt_image_format_size( *format, *width, *height, NULL ); - *buffer = mlt_pool_alloc( size ); - if ( *buffer ) - { - int strides[4]; - uint8_t* planes[4]; - int h = *height; - mlt_image_format_planes( *format, *width, *height, *buffer, planes, strides ); - memset(planes[0], 235, h * strides[0]); - if ( *format == mlt_image_yuv420p ) - h /= 2; - memset(planes[1], 128, h * strides[1]); - memset(planes[2], 128, h * strides[2]); - } - break; - default: - size = 0; break; } - mlt_properties_set_data( properties, "image", *buffer, size, ( mlt_destructor )mlt_pool_release, NULL ); + + struct mlt_image_s img; + mlt_image_set_values( &img, NULL, *format, *width, *height ); + mlt_image_alloc_data( &img ); + mlt_image_fill_black( &img ); + + *buffer = img.data; + mlt_properties_set_int( properties, "format", *format ); + mlt_properties_set_int( properties, "width", *width ); + mlt_properties_set_int( properties, "height", *height ); + mlt_properties_set_double( properties, "aspect_ratio", 1.0 ); + mlt_properties_set_data( properties, "image", *buffer, 0, img.release_data, NULL ); mlt_properties_set_int( properties, "test_image", 1 ); error = 0; } @@ -1095,63 +969,3 @@ mlt_frame mlt_frame_clone( mlt_frame self, int is_deep ) return new_frame; } - -/** Build a planes pointers of image mapping - * - * For proper and unified planar image processing, planes sizes and planes pointers should - * be provides to processing code. - * - * \public \memberof mlt_frame_s - * \param format the image format - * \param width width of the image in pixels - * \param height height of the image in pixels - * \param[in] data pointer to allocated image - * \param[out] planes pointers to plane's pointers will be set - * \param[out] strides pointers to plane's strides will be set - * \return the number of bytes - */ -int mlt_image_format_planes( mlt_image_format format, int width, int height, void* data, unsigned char *planes[4], int strides[4]) -{ - if ( mlt_image_yuv422p16 == format ) - { - strides[0] = width * 2; - strides[1] = width; - strides[2] = width; - strides[3] = 0; - - planes[0] = (unsigned char*)data; - planes[1] = planes[0] + height * strides[0]; - planes[2] = planes[1] + height * strides[1]; - planes[3] = 0; - } - else if ( mlt_image_yuv420p == format ) - { - strides[0] = width; - strides[1] = width >> 1; - strides[2] = width >> 1; - strides[3] = 0; - - planes[0] = (unsigned char*)data; - planes[1] = (unsigned char*)data + width * height; - planes[2] = (unsigned char*)data + ( 5 * width * height ) / 4; - planes[3] = 0; - } - else - { - int bpp; - - mlt_image_format_size( format, width, height, &bpp ); - - planes[0] = data; - planes[1] = 0; - planes[2] = 0; - planes[3] = 0; - - strides[0] = bpp * width; - strides[1] = 0; - strides[2] = 0; - strides[3] = 0; - }; - - return 0; -} diff --git a/src/framework/mlt_frame.h b/src/framework/mlt_frame.h index 235e3532a..90d3af5ba 100644 --- a/src/framework/mlt_frame.h +++ b/src/framework/mlt_frame.h @@ -145,11 +145,7 @@ extern mlt_properties mlt_frame_get_unique_properties( mlt_frame self, mlt_servi extern mlt_frame mlt_frame_clone( mlt_frame self, int is_deep ); /* convenience functions */ -extern const char * mlt_image_format_name( mlt_image_format format ); -extern int mlt_image_format_size( mlt_image_format format, int width, int height, int *bpp ); extern void mlt_frame_write_ppm( mlt_frame frame ); -extern int mlt_image_format_planes( mlt_image_format format, int width, int height, void* data, unsigned char *planes[4], int strides[4]); -extern mlt_image_format mlt_image_format_id( const char * name ); /** This macro scales RGB into the YUV gamut - y is scaled by 219/255 and uv by 224/255. */ #define RGB2YUV_601_SCALED(r, g, b, y, u, v)\ diff --git a/src/framework/mlt_image.c b/src/framework/mlt_image.c new file mode 100644 index 000000000..a9a07e2d1 --- /dev/null +++ b/src/framework/mlt_image.c @@ -0,0 +1,374 @@ +/** + * \file mlt_image.c + * \brief Image class + * \see mlt_mlt_image_s + * + * Copyright (C) 2020 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "mlt_image.h" + +#include "mlt_log.h" + +#include +#include + +/** Allocate a new Image object. + * + * \return a new image object with default values set + */ + +mlt_image mlt_image_new() +{ + mlt_image self = calloc( 1, sizeof(struct mlt_image_s) ); + self->close = free; + return self; +} + +/** Destroy an image object created by mlt_image_new(). + * + * \public \memberof mlt_image_s + * \param self the Image object + */ + +void mlt_image_close( mlt_image self ) +{ + if ( self) + { + if ( self->release_data ) + { + self->release_data( self->data ); + } + if ( self->close ) + { + self->close( self ); + } + } +} + +/** Set the most common values for the image. + * + * Less common values will be set to reasonable defaults. + * + * \public \memberof mlt_image_s + * \param self the Image object + * \param data the buffer that contains the image data + * \param format the image format + * \param width the width of the image + * \param height the height of the image + */ + +void mlt_image_set_values( mlt_image self, void* data, mlt_image_format format, int width, int height ) +{ + self->data = data; + self->format = format; + self->width = width; + self->height = height; + self->release_data = NULL; + self->close = NULL; + mlt_image_format_planes( self->format, self->width, self->height, self->data, self->planes, self->strides ); +} + +/** Get the most common values for the image. + * + * \public \memberof mlt_image_s + * \param self the Image object + * \param[out] data the buffer that contains the image data + * \param[out] format the image format + * \param[out] width the width of the image + * \param[out] height the height of the image + */ + +void mlt_image_get_values( mlt_image self, void** data, mlt_image_format* format, int* width, int* height ) +{ + *data = self->data; + *format = self->format; + *width = self->width; + *height = self->height; +} + +/** Allocate the data field based on the other properties of the Image. + * + * If the data field is already set, and a destructor function exists, the data + * will be released. Else, the data pointer will be overwritten without being + * released. + * + * After this function call, the release_data field will be set and can be used + * to release the data when necessary. + * + * \public \memberof mlt_image_s + * \param self the Image object + */ + +void mlt_image_alloc_data( mlt_image self ) +{ + if ( !self ) return; + + if ( self->release_data ) + { + self->release_data( self->data ); + } + + int size = mlt_image_calculate_size( self ); + self->data = mlt_pool_alloc( size ); + self->release_data = mlt_pool_release; + mlt_image_format_planes( self->format, self->width, self->height, self->data, self->planes, self->strides ); +} + +/** Calculate the number of bytes needed for the Image data. + * + * \public \memberof mlt_image_s + * \param self the Image object + * \return the number of bytes + */ + +int mlt_image_calculate_size( mlt_image self ) +{ + int height = self->height + 1; // Legacy bug workaround + switch ( self->format ) + { + case mlt_image_rgb24: + return self->width * height * 3; + case mlt_image_opengl: + case mlt_image_rgb24a: + return self->width * height * 4; + case mlt_image_yuv422: + return self->width * height * 2; + case mlt_image_yuv420p: + return self->width * height * 3 / 2; + case mlt_image_glsl: + case mlt_image_glsl_texture: + return 4; + case mlt_image_yuv422p16: + return 4 * self->width * height; + } + return 0; +} + + +/** Get the short name for an image format. + * + * \public \memberof mlt_image_s + * \param format the image format + * \return a string + */ + +const char * mlt_image_format_name( mlt_image_format format ) +{ + switch ( format ) + { + case mlt_image_none: return "none"; + case mlt_image_rgb24: return "rgb24"; + case mlt_image_rgb24a: return "rgb24a"; + case mlt_image_yuv422: return "yuv422"; + case mlt_image_yuv420p: return "yuv420p"; + case mlt_image_opengl: return "opengl"; + case mlt_image_glsl: return "glsl"; + case mlt_image_glsl_texture: return "glsl_texture"; + case mlt_image_yuv422p16: return "yuv422p16"; + case mlt_image_invalid: return "invalid"; + } + return "invalid"; +} + +/** Get the id of image format from short name. + * + * \public \memberof mlt_image_s + * \param name the image format short name + * \return a image format + */ + +mlt_image_format mlt_image_format_id( const char * name ) +{ + mlt_image_format f; + + for ( f = mlt_image_none; name && f < mlt_image_invalid; f++ ) + { + const char * v = mlt_image_format_name( f ); + if ( !strcmp( v, name ) ) + return f; + } + + return mlt_image_invalid; +} + +/** Fill an image with black. + * + * \public \memberof mlt_image_s + */ +void mlt_image_fill_black( mlt_image self ) +{ + if ( !self->data) return; + + switch( self->format ) + { + case mlt_image_none: + case mlt_image_glsl: + case mlt_image_glsl_texture: + return; + case mlt_image_rgb24: + case mlt_image_rgb24a: + case mlt_image_opengl: + { + int size = mlt_image_calculate_size( self ); + memset( self->planes[0], 255, size ); + break; + } + case mlt_image_yuv422: + { + int size = mlt_image_calculate_size( self ); + register uint8_t *p = self->planes[0]; + register uint8_t *q = p + size; + while ( p != NULL && p != q ) + { + *p ++ = 235; + *p ++ = 128; + } + } + break; + case mlt_image_yuv422p16: + { + for ( int plane = 0; plane < 3; plane++ ) + { + uint16_t value = 235 << 8; + size_t width = self->width; + if ( plane > 0 ) + { + value = 128 << 8; + width = self->width / 2; + } + uint16_t* pRow = (uint16_t*)self->planes[plane]; + for ( int i = 0; i < self->height; i++ ) + { + uint16_t* p = pRow; + for ( int j = 0; j < width; j++ ) + { + *p++ = value; + } + pRow += self->strides[plane]; + } + } + } + break; + case mlt_image_yuv420p: + { + memset(self->planes[0], 235, self->height * self->strides[0]); + memset(self->planes[1], 128, self->height * self->strides[1] / 2); + memset(self->planes[2], 128, self->height * self->strides[2] / 2); + } + break; + } + + } + +/** Get the number of bytes needed for an image. + * + * \public \memberof mlt_image_s + * \param format the image format + * \param width width of the image in pixels + * \param height height of the image in pixels + * \param[out] bpp the number of bytes per pixel (optional) + * \return the number of bytes + */ +int mlt_image_format_size( mlt_image_format format, int width, int height, int *bpp ) +{ + height += 1; + switch ( format ) + { + case mlt_image_rgb24: + if ( bpp ) *bpp = 3; + return width * height * 3; + case mlt_image_opengl: + case mlt_image_rgb24a: + if ( bpp ) *bpp = 4; + return width * height * 4; + case mlt_image_yuv422: + if ( bpp ) *bpp = 2; + return width * height * 2; + case mlt_image_yuv420p: + if ( bpp ) *bpp = 3 / 2; + return width * height * 3 / 2; + case mlt_image_glsl: + case mlt_image_glsl_texture: + if ( bpp ) *bpp = 0; + return 4; + case mlt_image_yuv422p16: + if ( bpp ) *bpp = 0; + return 4 * height * width ; + default: + if ( bpp ) *bpp = 0; + return 0; + } + return 0; +} + +/** Build a planes pointers of image mapping + * + * For proper and unified planar image processing, planes sizes and planes pointers should + * be provides to processing code. + * + * \public \memberof mlt_image_s + * \param format the image format + * \param width width of the image in pixels + * \param height height of the image in pixels + * \param[in] data pointer to allocated image + * \param[out] planes pointers to plane's pointers will be set + * \param[out] strides pointers to plane's strides will be set + */ +void mlt_image_format_planes( mlt_image_format format, int width, int height, void* data, uint8_t* planes[4], int strides[4]) +{ + if ( mlt_image_yuv422p16 == format ) + { + strides[0] = width * 2; + strides[1] = width; + strides[2] = width; + strides[3] = 0; + + planes[0] = (unsigned char*)data; + planes[1] = planes[0] + height * strides[0]; + planes[2] = planes[1] + height * strides[1]; + planes[3] = 0; + } + else if ( mlt_image_yuv420p == format ) + { + strides[0] = width; + strides[1] = width >> 1; + strides[2] = width >> 1; + strides[3] = 0; + + planes[0] = (unsigned char*)data; + planes[1] = (unsigned char*)data + width * height; + planes[2] = (unsigned char*)data + ( 5 * width * height ) / 4; + planes[3] = 0; + } + else + { + int bpp; + + mlt_image_format_size( format, width, height, &bpp ); + + planes[0] = data; + planes[1] = 0; + planes[2] = 0; + planes[3] = 0; + + strides[0] = bpp * width; + strides[1] = 0; + strides[2] = 0; + strides[3] = 0; + }; +} diff --git a/src/framework/mlt_image.h b/src/framework/mlt_image.h new file mode 100644 index 000000000..df31e8609 --- /dev/null +++ b/src/framework/mlt_image.h @@ -0,0 +1,60 @@ +/** + * \file mlt_image.h + * \brief Image class + * \see mlt_image_s + * + * Copyright (C) 2021 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MLT_IMAGE_H +#define MLT_IMAGE_H + +#include "mlt_types.h" + +/** \brief Image class + * + * Image is the data object that represents image for a period of time. + */ +#define MLT_IMAGE_MAX_PLANES 4 + +struct mlt_image_s +{ + mlt_image_format format; + int width; + int height; + uint8_t* planes[MLT_IMAGE_MAX_PLANES]; + int strides[MLT_IMAGE_MAX_PLANES]; + void* data; + mlt_destructor release_data; + mlt_destructor close; +}; + +extern mlt_image mlt_image_new(); +extern void mlt_image_close( mlt_image self ); +extern void mlt_image_set_values( mlt_image self, void* data, mlt_image_format format, int width, int height ); +extern void mlt_image_get_values( mlt_image self, void** data, mlt_image_format* format, int* width, int* height ); +extern void mlt_image_alloc_data( mlt_image self ); +extern int mlt_image_calculate_size( mlt_image self ); +extern void mlt_image_fill_black( mlt_image self ); +extern const char * mlt_image_format_name( mlt_image_format format ); +extern mlt_image_format mlt_image_format_id( const char * name ); + +// Deprecated functions +extern int mlt_image_format_size( mlt_image_format format, int width, int height, int *bpp ); +extern void mlt_image_format_planes( mlt_image_format format, int width, int height, void* data, uint8_t* planes[4], int strides[4]); + +#endif diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index 5c9df5417..926ca8dc3 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -187,6 +187,7 @@ typedef struct { mlt_color; typedef struct mlt_audio_s *mlt_audio; /**< pointer to Audio object */ +typedef struct mlt_image_s *mlt_image; /**< pointer to Image object */ typedef struct mlt_frame_s *mlt_frame, **mlt_frame_ptr; /**< pointer to Frame object */ typedef struct mlt_property_s *mlt_property; /**< pointer to Property object */ typedef struct mlt_properties_s *mlt_properties; /**< pointer to Properties object */ From 0562625dc4a866c9d6a74f50028b759439e53e80 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 7 Feb 2021 21:52:58 -0600 Subject: [PATCH 048/122] Convert spot remover to use new image class --- src/modules/plus/filter_spot_remover.c | 27 ++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/modules/plus/filter_spot_remover.c b/src/modules/plus/filter_spot_remover.c index dedb63d20..c266bbc97 100644 --- a/src/modules/plus/filter_spot_remover.c +++ b/src/modules/plus/filter_spot_remover.c @@ -168,40 +168,43 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format error = mlt_frame_get_image( frame, image, format, width, height, 1 ); if (error) return error; + struct mlt_image_s img; + mlt_image_set_values( &img, *image, *format, *width, *height ); + int i; switch( *format ) { case mlt_image_rgb24a: for ( i = 0; i < 4; i++ ) { - remove_spot_channel( *image + i, *width, 4, rect ); + remove_spot_channel( img.planes[0] + i, img.width, 4, rect ); } break; case mlt_image_rgb24: for ( i = 0; i < 3; i++ ) { - remove_spot_channel( *image + i, *width, 3, rect ); + remove_spot_channel( img.planes[0] + i, img.width, 3, rect ); } break; case mlt_image_yuv422: // Y - remove_spot_channel( *image, *width, 2, rect ); + remove_spot_channel( img.planes[0], img.width, 2, rect ); // U - remove_spot_channel( *image + 1, *width / 2, 4, - constrain_rect( scale_rect( rect, 2, 1 ), *width / 2, *height ) ); + remove_spot_channel( img.planes[0] + 1, img.width / 2, 4, + constrain_rect( scale_rect( rect, 2, 1 ), img.width / 2, img.height ) ); // V - remove_spot_channel( *image + 3, *width / 2, 4, - constrain_rect( scale_rect( rect, 2, 1 ), *width / 2, *height ) ); + remove_spot_channel( img.planes[0] + 3, img.width / 2, 4, + constrain_rect( scale_rect( rect, 2, 1 ), img.width / 2, img.height ) ); break; case mlt_image_yuv420p: // Y - remove_spot_channel( *image, *width, 1, rect ); + remove_spot_channel( img.planes[0], img.width, 1, rect ); // U - remove_spot_channel( *image + (*width * *height), *width / 2, 1, - constrain_rect( scale_rect( rect, 2, 2 ), *width / 2, *height / 2 ) ); + remove_spot_channel( img.planes[1], img.width / 2, 1, + constrain_rect( scale_rect( rect, 2, 2 ), img.width / 2, img.height / 2 ) ); // V - remove_spot_channel( *image + (*width * *height * 5 / 4), *width / 2, 1, - constrain_rect( scale_rect( rect, 2, 2 ), *width / 2, *height / 2 ) ); + remove_spot_channel( img.planes[2], img.width / 2, 1, + constrain_rect( scale_rect( rect, 2, 2 ), img.width / 2, img.height / 2 ) ); break; default: return 1; From cdd714b591b50eac53d89ddcee38d4878f9feead Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Tue, 23 Feb 2021 19:46:05 -0600 Subject: [PATCH 049/122] Add c++ wrappers for mlt_image Also add unit tests --- src/mlt++/CMakeLists.txt | 2 + src/mlt++/Makefile | 1 + src/mlt++/Mlt.h | 1 + src/mlt++/MltImage.cpp | 76 +++++++++++++++++ src/mlt++/MltImage.h | 47 +++++++++++ src/mlt++/mlt++.vers | 15 +++- src/tests/CMakeLists.txt | 2 +- src/tests/test_image/test_image.cpp | 125 ++++++++++++++++++++++++++++ src/tests/test_image/test_image.pro | 3 + src/tests/tests.pro | 1 + 10 files changed, 271 insertions(+), 2 deletions(-) create mode 100644 src/mlt++/MltImage.cpp create mode 100644 src/mlt++/MltImage.h create mode 100644 src/tests/test_image/test_image.cpp create mode 100644 src/tests/test_image/test_image.pro diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index cdacd87ea..83fd905b6 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(mlt++ SHARED MltFilteredProducer.cpp MltFrame.cpp MltGeometry.cpp + MltImage.cpp MltLink.cpp MltMultitrack.cpp MltParser.cpp @@ -68,6 +69,7 @@ set(MLTPP_PUPLIC_HEADERS MltFilteredProducer.h MltFrame.h MltGeometry.h + MltImage.h MltLink.h MltMultitrack.h MltParser.h diff --git a/src/mlt++/Makefile b/src/mlt++/Makefile index f3839d2ee..f66f39da7 100644 --- a/src/mlt++/Makefile +++ b/src/mlt++/Makefile @@ -39,6 +39,7 @@ OBJS = MltAudio.o \ MltFilteredProducer.o \ MltFrame.o \ MltGeometry.o \ + MltImage.o \ MltLink.o \ MltMultitrack.o \ MltParser.o \ diff --git a/src/mlt++/Mlt.h b/src/mlt++/Mlt.h index 93d7f8377..68ebf3798 100644 --- a/src/mlt++/Mlt.h +++ b/src/mlt++/Mlt.h @@ -33,6 +33,7 @@ #include "MltFilteredConsumer.h" #include "MltFrame.h" #include "MltGeometry.h" +#include "MltImage.h" #include "MltMultitrack.h" #include "MltParser.h" #include "MltPlaylist.h" diff --git a/src/mlt++/MltImage.cpp b/src/mlt++/MltImage.cpp new file mode 100644 index 000000000..71d570a66 --- /dev/null +++ b/src/mlt++/MltImage.cpp @@ -0,0 +1,76 @@ +/** + * MltImage.cpp - MLT Wrapper + * Copyright (C) 2021 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "MltImage.h" + +using namespace Mlt; + +Image::Image( ) +{ + instance = mlt_image_new(); +} + +Image::Image( mlt_image image ) + : instance( image ) +{ +} + +Image::Image( int width, int height, mlt_image_format format ) +{ + instance = mlt_image_new(); + alloc( width, height, format ); +} + +Image::~Image( ) +{ + mlt_image_close( instance ); +} + +mlt_image_format Image::format() +{ + return instance->format; +} + +int Image::width() +{ + return instance->width; +} + +int Image::height() +{ + return instance->height; +} + +void Image::alloc( int width, int height, mlt_image_format format ) +{ + instance->width = width; + instance->height = height; + instance->format = format; + mlt_image_alloc_data( instance ); +} + +uint8_t* Image::plane( int plane ) +{ + return instance->planes[plane]; +} + +int Image::stride( int plane ) +{ + return instance->strides[plane]; +} diff --git a/src/mlt++/MltImage.h b/src/mlt++/MltImage.h new file mode 100644 index 000000000..6bf6c22fb --- /dev/null +++ b/src/mlt++/MltImage.h @@ -0,0 +1,47 @@ +/** + * MltImage.h - MLT Wrapper + * Copyright (C) 2021 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MLTPP_IMAGE_H +#define MLTPP_IMAGE_H + +#include "MltConfig.h" + +#include + +namespace Mlt +{ + class MLTPP_DECLSPEC Image + { + private: + mlt_image instance; + public: + Image(); + Image( mlt_image image ); + Image( int width, int height, mlt_image_format format ); + virtual ~Image( ); + mlt_image_format format(); + int width(); + int height(); + void alloc( int width, int height, mlt_image_format format ); + uint8_t* plane( int plane ); + int stride( int plane ); + }; +} + +#endif diff --git a/src/mlt++/mlt++.vers b/src/mlt++/mlt++.vers index a2da7e218..049600a58 100644 --- a/src/mlt++/mlt++.vers +++ b/src/mlt++/mlt++.vers @@ -619,6 +619,9 @@ MLTPP_7.0.0 { "typeinfo for Mlt::Audio"; "typeinfo name for Mlt::Audio"; "vtable for Mlt::Audio"; + "typeinfo for Mlt::Image"; + "typeinfo name for Mlt::Image"; + "vtable for Mlt::Image"; "typeinfo for Mlt::Link"; "typeinfo name for Mlt::Link"; "vtable for Mlt::Link"; @@ -626,7 +629,7 @@ MLTPP_7.0.0 { "typeinfo name for Mlt::Chain"; "vtable for Mlt::Chain"; "Mlt::Link::Link()"; - "Mlt::Link::Link(mlt_link)"; + "Mlt::Link::Link(mlt_link_s*)"; "Mlt::Link::Link(char const*, char const*)"; "Mlt::Link::~Link()"; "Mlt::Link::get_link()"; @@ -655,5 +658,15 @@ MLTPP_7.0.0 { "Mlt::Parser::on_start_link(Mlt::Link*)"; "Mlt::Parser::on_end_link(Mlt::Link*)"; "Mlt::Animation::shift_frames(int)"; + "Mlt::Image::Image()"; + "Mlt::Image::Image(mlt_image_s*)"; + "Mlt::Image::Image(int, int, mlt_image_format)"; + "Mlt::Image::~Image()"; + "Mlt::Image::format()"; + "Mlt::Image::width()"; + "Mlt::Image::height()"; + "Mlt::Image::alloc(int, int, mlt_image_format)"; + "Mlt::Image::plane(int)"; + "Mlt::Image::stride(int)"; }; } MLTPP_6.22.0; diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index f3ce0543b..39a99d798 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -1,6 +1,6 @@ set(CMAKE_AUTOMOC ON) -foreach(QT_TEST_NAME animation audio events filter frame playlist properties repository service tractor) +foreach(QT_TEST_NAME animation audio events filter frame image playlist properties repository service tractor) add_executable(test_${QT_TEST_NAME} test_${QT_TEST_NAME}/test_${QT_TEST_NAME}.cpp) target_link_libraries(test_${QT_TEST_NAME} PRIVATE Qt5::Core Qt5::Test mlt++) add_test(NAME "QtTest:${QT_TEST_NAME}" COMMAND test_${QT_TEST_NAME}) diff --git a/src/tests/test_image/test_image.cpp b/src/tests/test_image/test_image.cpp new file mode 100644 index 000000000..5be21a17e --- /dev/null +++ b/src/tests/test_image/test_image.cpp @@ -0,0 +1,125 @@ +/* + * Copyright (C) 2021 Meltytech, LLC + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with consumer library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#include +using namespace Mlt; + +class TestImage : public QObject +{ + Q_OBJECT + +public: + TestImage() + { + Factory::init(); + } + +private Q_SLOTS: + + void DefaultConstructor() + { + Image i; + QVERIFY(i.width() == 0); + } + + void ConstructFromImage() + { + mlt_image image = mlt_image_new(); + image->width = 500; + Image i(image); + QCOMPARE(i.width(), 500); + } + + void ConstructAndAlloc() + { + Image i(1920, 1080, mlt_image_rgb24 ); + QVERIFY(i.plane(0) != nullptr); + } + + void PlaneAndStrideRgb24() + { + Image i(1920, 1080, mlt_image_rgb24 ); + QVERIFY(i.plane(0) != nullptr); + QCOMPARE(i.stride(0), 1920 * 3); + QVERIFY(i.plane(1) == nullptr); + QCOMPARE(i.stride(1), 0); + QVERIFY(i.plane(2) == nullptr); + QCOMPARE(i.stride(2), 0); + QVERIFY(i.plane(3) == nullptr); + QCOMPARE(i.stride(3), 0); + } + + void PlaneAndStrideRgb24a() + { + Image i(1920, 1080, mlt_image_rgb24a ); + QVERIFY(i.plane(0) != nullptr); + QCOMPARE(i.stride(0), 1920 * 4); + QVERIFY(i.plane(1) == nullptr); + QCOMPARE(i.stride(1), 0); + QVERIFY(i.plane(2) == nullptr); + QCOMPARE(i.stride(2), 0); + QVERIFY(i.plane(3) == nullptr); + QCOMPARE(i.stride(3), 0); + } + + void PlaneAndStrideYuv422() + { + Image i(1920, 1080, mlt_image_yuv422 ); + QVERIFY(i.plane(0) != nullptr); + QCOMPARE(i.stride(0), 1920 * 2); + QVERIFY(i.plane(1) == nullptr); + QCOMPARE(i.stride(1), 0); + QVERIFY(i.plane(2) == nullptr); + QCOMPARE(i.stride(2), 0); + QVERIFY(i.plane(3) == nullptr); + QCOMPARE(i.stride(3), 0); + } + + void PlaneAndStrideYuv420p() + { + Image i(1920, 1080, mlt_image_yuv420p ); + QVERIFY(i.plane(0) != nullptr); + QCOMPARE(i.stride(0), 1920); + QVERIFY(i.plane(1) != nullptr); + QCOMPARE(i.stride(1), 1920 / 2); + QVERIFY(i.plane(2) != nullptr); + QCOMPARE(i.stride(2), 1920 / 2); + QVERIFY(i.plane(3) == nullptr); + QCOMPARE(i.stride(3), 0); + } + + void PlaneAndStrideYuv422p16() + { + Image i(1920, 1080, mlt_image_yuv420p ); + QVERIFY(i.plane(0) != nullptr); + QCOMPARE(i.stride(0), 1920); + QVERIFY(i.plane(1) != nullptr); + QCOMPARE(i.stride(1), 1920 / 2); + QVERIFY(i.plane(2) != nullptr); + QCOMPARE(i.stride(2), 1920 / 2); + QVERIFY(i.plane(3) == nullptr); + QCOMPARE(i.stride(3), 0); + } +}; + +QTEST_APPLESS_MAIN(TestImage) + +#include "test_image.moc" diff --git a/src/tests/test_image/test_image.pro b/src/tests/test_image/test_image.pro new file mode 100644 index 000000000..b9a59d7cc --- /dev/null +++ b/src/tests/test_image/test_image.pro @@ -0,0 +1,3 @@ +include(../common.pri) +TARGET = test_image +SOURCES += test_image.cpp diff --git a/src/tests/tests.pro b/src/tests/tests.pro index 593d5b030..f7d9d324e 100644 --- a/src/tests/tests.pro +++ b/src/tests/tests.pro @@ -3,6 +3,7 @@ SUBDIRS = test_audio \ test_filter \ test_events \ test_frame \ + test_image \ test_playlist \ test_properties \ test_repository \ From ae9b7de516627ab660756a8de1c58df5a8e38c54 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 28 Feb 2021 08:48:14 -0600 Subject: [PATCH 050/122] Remove legacy "height + 1" workaround. The reason for the workaround is unknown. --- src/framework/mlt_image.c | 12 +++++------- src/modules/gdk/producer_pixbuf.c | 8 ++------ src/modules/opengl/filter_movit_convert.cpp | 4 +--- src/modules/plusgpl/filter_rotoscoping.c | 2 +- src/modules/qt/producer_kdenlivetitle.c | 4 +--- src/modules/sdl/consumer_sdl.c | 4 +--- src/modules/sdl2/consumer_sdl2.c | 4 +--- 7 files changed, 12 insertions(+), 26 deletions(-) diff --git a/src/framework/mlt_image.c b/src/framework/mlt_image.c index a9a07e2d1..9800a7a5e 100644 --- a/src/framework/mlt_image.c +++ b/src/framework/mlt_image.c @@ -138,23 +138,22 @@ void mlt_image_alloc_data( mlt_image self ) int mlt_image_calculate_size( mlt_image self ) { - int height = self->height + 1; // Legacy bug workaround switch ( self->format ) { case mlt_image_rgb24: - return self->width * height * 3; + return self->width * self->height * 3; case mlt_image_opengl: case mlt_image_rgb24a: - return self->width * height * 4; + return self->width * self->height * 4; case mlt_image_yuv422: - return self->width * height * 2; + return self->width * self->height * 2; case mlt_image_yuv420p: - return self->width * height * 3 / 2; + return self->width * self->height * 3 / 2; case mlt_image_glsl: case mlt_image_glsl_texture: return 4; case mlt_image_yuv422p16: - return 4 * self->width * height; + return 4 * self->width * self->height; } return 0; } @@ -286,7 +285,6 @@ void mlt_image_fill_black( mlt_image self ) */ int mlt_image_format_size( mlt_image_format format, int width, int height, int *bpp ) { - height += 1; switch ( format ) { case mlt_image_rgb24: diff --git a/src/modules/gdk/producer_pixbuf.c b/src/modules/gdk/producer_pixbuf.c index d06614f17..1ff7ca48c 100644 --- a/src/modules/gdk/producer_pixbuf.c +++ b/src/modules/gdk/producer_pixbuf.c @@ -645,9 +645,7 @@ static void refresh_image( producer_pixbuf self, mlt_frame frame, mlt_image_form buffer = self->image; image_size = mlt_image_format_size( self->format, self->width, self->height, NULL ); self->image = mlt_pool_alloc( image_size ); - // We use height-1 because mlt_image_format_size() uses height + 1. - // XXX Remove -1 when mlt_image_format_size() is changed. - memcpy( self->image, buffer, mlt_image_format_size( self->format, self->width, self->height - 1, NULL ) ); + memcpy( self->image, buffer, mlt_image_format_size( self->format, self->width, self->height, NULL ) ); } } if ( ( buffer = mlt_frame_get_alpha( frame ) ) ) @@ -718,10 +716,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form // Clone the image int image_size = mlt_image_format_size( self->format, self->width, self->height, NULL ); uint8_t *image_copy = mlt_pool_alloc( image_size ); - // We use height-1 because mlt_image_format_size() uses height + 1. - // XXX Remove -1 when mlt_image_format_size() is changed. memcpy( image_copy, self->image, - mlt_image_format_size( self->format, self->width, self->height - 1, NULL ) ); + mlt_image_format_size( self->format, self->width, self->height, NULL ) ); // Now update properties so we free the copy after mlt_frame_set_image( frame, image_copy, image_size, mlt_pool_release ); // We're going to pass the copy on diff --git a/src/modules/opengl/filter_movit_convert.cpp b/src/modules/opengl/filter_movit_convert.cpp index 3d06d6184..13ea14449 100644 --- a/src/modules/opengl/filter_movit_convert.cpp +++ b/src/modules/opengl/filter_movit_convert.cpp @@ -512,9 +512,7 @@ static uint8_t* make_input_copy( mlt_image_format format, uint8_t *image, int wi return NULL; } - // We use height-1 because mlt_image_format_size() uses height + 1. - // XXX Remove -1 when mlt_image_format_size() is changed. - int img_size = mlt_image_format_size( format, width, height - 1, NULL ); + int img_size = mlt_image_format_size( format, width, height, NULL ); uint8_t* img_copy = (uint8_t*) mlt_pool_alloc( img_size ); if ( format == mlt_image_yuv422 ) { yuv422_to_yuv422p( image, img_copy, width, height ); diff --git a/src/modules/plusgpl/filter_rotoscoping.c b/src/modules/plusgpl/filter_rotoscoping.c index 6463449ac..436287d6c 100644 --- a/src/modules/plusgpl/filter_rotoscoping.c +++ b/src/modules/plusgpl/filter_rotoscoping.c @@ -376,7 +376,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format } int bpp; - size = mlt_image_format_size( *format, *width, *height - 1, &bpp ); // mlt_image_format_size increments height! + size = mlt_image_format_size( *format, *width, *height, &bpp ); uint8_t *p = *image; uint8_t *q = *image + size; diff --git a/src/modules/qt/producer_kdenlivetitle.c b/src/modules/qt/producer_kdenlivetitle.c index 4dc5d9c6b..352d26b3d 100644 --- a/src/modules/qt/producer_kdenlivetitle.c +++ b/src/modules/qt/producer_kdenlivetitle.c @@ -98,10 +98,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form // Clone the image and the alpha int image_size = mlt_image_format_size( self->format, self->current_width, self->current_height, NULL ); uint8_t *image_copy = mlt_pool_alloc( image_size ); - // We use height-1 because mlt_image_format_size() uses height + 1. - // XXX Remove -1 when mlt_image_format_size() is changed. memcpy( image_copy, self->current_image, - mlt_image_format_size( self->format, self->current_width, self->current_height - 1, NULL ) ); + mlt_image_format_size( self->format, self->current_width, self->current_height, NULL ) ); // Now update properties so we free the copy after mlt_frame_set_image( frame, image_copy, image_size, mlt_pool_release ); // We're going to pass the copy on diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index dd7610037..c24bc2116 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -682,9 +682,7 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) self->buffer = self->sdl_overlay->pixels[ 0 ]; if ( SDL_LockYUVOverlay( self->sdl_overlay ) >= 0 ) { - // We use height-1 because mlt_image_format_size() uses height + 1. - // XXX Remove -1 when mlt_image_format_size() is changed. - int size = mlt_image_format_size( vfmt, width, height - 1, NULL ); + int size = mlt_image_format_size( vfmt, width, height, NULL ); if ( image != NULL ) memcpy( self->buffer, image, size ); SDL_UnlockYUVOverlay( self->sdl_overlay ); diff --git a/src/modules/sdl2/consumer_sdl2.c b/src/modules/sdl2/consumer_sdl2.c index 9edc767fd..82b614685 100644 --- a/src/modules/sdl2/consumer_sdl2.c +++ b/src/modules/sdl2/consumer_sdl2.c @@ -668,9 +668,7 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) unsigned char* planes[4]; int strides[4]; - // We use height-1 because mlt_image_format_size() uses height + 1. - // XXX Remove -1 when mlt_image_format_size() is changed. - mlt_image_format_planes( vfmt, width, height - 1, image, planes, strides ); + mlt_image_format_planes( vfmt, width, height, image, planes, strides ); if ( strides[1] ) { SDL_UpdateYUVTexture( self->sdl_texture, NULL, planes[0], strides[0], From 39ca91f8e2576a94cb58d47736f5d16ef94f15a6 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 28 Feb 2021 23:08:49 -0600 Subject: [PATCH 051/122] Add colorspace parameter to image class --- src/framework/mlt_image.h | 1 + src/framework/mlt_types.h | 19 +++++++++++++++++++ src/mlt++/MltImage.cpp | 10 ++++++++++ src/mlt++/MltImage.h | 2 ++ src/mlt++/mlt++.vers | 2 ++ src/tests/test_image/test_image.cpp | 7 +++++++ 6 files changed, 41 insertions(+) diff --git a/src/framework/mlt_image.h b/src/framework/mlt_image.h index df31e8609..cc8dad430 100644 --- a/src/framework/mlt_image.h +++ b/src/framework/mlt_image.h @@ -36,6 +36,7 @@ struct mlt_image_s mlt_image_format format; int width; int height; + int colorspace; uint8_t* planes[MLT_IMAGE_MAX_PLANES]; int strides[MLT_IMAGE_MAX_PLANES]; void* data; diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index 926ca8dc3..8d28aed5c 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -104,6 +104,25 @@ typedef enum } mlt_channel_layout; +/** Colorspace definitions */ + +typedef enum +{ + mlt_colorspace_rgb = 0, ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB) + mlt_colorspace_bt709 = 1, ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B + mlt_colorspace_unspecified = 2, + mlt_colorspace_reserved = 3, + mlt_colorspace_fcc = 4, ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20) + mlt_colorspace_bt470bg = 5, ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601 + mlt_colorspace_smpte170m = 6, ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC + mlt_colorspace_smpte240m = 7, ///< functionally identical to above + mlt_colorspace_ycgco = 8, ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16 + mlt_colorspace_bt2020_ncl = 9, ///< ITU-R BT2020 non-constant luminance system + mlt_colorspace_bt2020_cl = 10, ///< ITU-R BT2020 constant luminance system + mlt_colorspace_smpte2085 = 11, ///< SMPTE 2085, Y'D'zD'x +} +mlt_colorspace; + /** The time string formats */ typedef enum diff --git a/src/mlt++/MltImage.cpp b/src/mlt++/MltImage.cpp index 71d570a66..a95f7c77c 100644 --- a/src/mlt++/MltImage.cpp +++ b/src/mlt++/MltImage.cpp @@ -57,6 +57,16 @@ int Image::height() return instance->height; } +void Image::set_colorspace( int colorspace ) +{ + instance->colorspace = colorspace; +} + +int Image::colorspace() +{ + return instance->colorspace; +} + void Image::alloc( int width, int height, mlt_image_format format ) { instance->width = width; diff --git a/src/mlt++/MltImage.h b/src/mlt++/MltImage.h index 6bf6c22fb..9046610ba 100644 --- a/src/mlt++/MltImage.h +++ b/src/mlt++/MltImage.h @@ -38,6 +38,8 @@ namespace Mlt mlt_image_format format(); int width(); int height(); + void set_colorspace( int colorspace ); + int colorspace(); void alloc( int width, int height, mlt_image_format format ); uint8_t* plane( int plane ); int stride( int plane ); diff --git a/src/mlt++/mlt++.vers b/src/mlt++/mlt++.vers index 049600a58..7ef96921e 100644 --- a/src/mlt++/mlt++.vers +++ b/src/mlt++/mlt++.vers @@ -665,6 +665,8 @@ MLTPP_7.0.0 { "Mlt::Image::format()"; "Mlt::Image::width()"; "Mlt::Image::height()"; + "Mlt::Image::set_colorspace(int)"; + "Mlt::Image::colorspace()"; "Mlt::Image::alloc(int, int, mlt_image_format)"; "Mlt::Image::plane(int)"; "Mlt::Image::stride(int)"; diff --git a/src/tests/test_image/test_image.cpp b/src/tests/test_image/test_image.cpp index 5be21a17e..77fc0a599 100644 --- a/src/tests/test_image/test_image.cpp +++ b/src/tests/test_image/test_image.cpp @@ -118,6 +118,13 @@ private Q_SLOTS: QVERIFY(i.plane(3) == nullptr); QCOMPARE(i.stride(3), 0); } + + void GetSetColorspace() + { + Image i(1920, 1080, mlt_image_rgb24 ); + i.set_colorspace(mlt_colorspace_bt709); + QCOMPARE(i.colorspace(), mlt_colorspace_bt709); + } }; QTEST_APPLESS_MAIN(TestImage) From d7bf7c2b105102ffb2258fd40d7676661a57f9a7 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 28 Feb 2021 23:32:42 -0600 Subject: [PATCH 052/122] Add alpha parameter to image class --- src/framework/mlt.vers | 1 + src/framework/mlt_image.c | 34 +++++++++++++++++++++++++++++ src/framework/mlt_image.h | 3 +++ src/mlt++/MltImage.cpp | 9 +++++++- src/mlt++/MltImage.h | 3 ++- src/mlt++/mlt++.vers | 3 ++- src/tests/test_image/test_image.cpp | 7 ++++++ 7 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index b943968e5..b4c42fcae 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -600,6 +600,7 @@ MLT_7.0.0 { mlt_image_set_values; mlt_image_get_values; mlt_image_alloc_data; + mlt_image_alloc_alpha; mlt_image_calculate_size; mlt_image_fill_black; } MLT_6.22.0; diff --git a/src/framework/mlt_image.c b/src/framework/mlt_image.c index 9800a7a5e..82477643b 100644 --- a/src/framework/mlt_image.c +++ b/src/framework/mlt_image.c @@ -53,6 +53,10 @@ void mlt_image_close( mlt_image self ) { self->release_data( self->data ); } + if ( self->release_alpha ) + { + self->release_alpha( self->alpha ); + } if ( self->close ) { self->close( self ); @@ -78,7 +82,9 @@ void mlt_image_set_values( mlt_image self, void* data, mlt_image_format format, self->format = format; self->width = width; self->height = height; + self->colorspace = mlt_colorspace_unspecified; self->release_data = NULL; + self->release_alpha = NULL; self->close = NULL; mlt_image_format_planes( self->format, self->width, self->height, self->data, self->planes, self->strides ); } @@ -129,6 +135,34 @@ void mlt_image_alloc_data( mlt_image self ) mlt_image_format_planes( self->format, self->width, self->height, self->data, self->planes, self->strides ); } +/** Allocate the alpha field based on the other properties of the Image. + * + * If the alpha field is already set, and a destructor function exists, the data + * will be released. Else, the data pointer will be overwritten without being + * released. + * + * After this function call, the release_data field will be set and can be used + * to release the data when necessary. + * + * \public \memberof mlt_image_s + * \param self the Image object + */ + +void mlt_image_alloc_alpha( mlt_image self ) +{ + if ( !self ) return; + + if ( self->release_alpha ) + { + self->release_alpha( self->alpha ); + } + + self->alpha = mlt_pool_alloc( self->width * self->height ); + self->release_alpha = mlt_pool_release; + self->strides[3] = self->width; + self->planes[3] = self->alpha; +} + /** Calculate the number of bytes needed for the Image data. * * \public \memberof mlt_image_s diff --git a/src/framework/mlt_image.h b/src/framework/mlt_image.h index cc8dad430..9cb6ece01 100644 --- a/src/framework/mlt_image.h +++ b/src/framework/mlt_image.h @@ -41,6 +41,8 @@ struct mlt_image_s int strides[MLT_IMAGE_MAX_PLANES]; void* data; mlt_destructor release_data; + void* alpha; + mlt_destructor release_alpha; mlt_destructor close; }; @@ -49,6 +51,7 @@ extern void mlt_image_close( mlt_image self ); extern void mlt_image_set_values( mlt_image self, void* data, mlt_image_format format, int width, int height ); extern void mlt_image_get_values( mlt_image self, void** data, mlt_image_format* format, int* width, int* height ); extern void mlt_image_alloc_data( mlt_image self ); +extern void mlt_image_alloc_alpha( mlt_image self ); extern int mlt_image_calculate_size( mlt_image self ); extern void mlt_image_fill_black( mlt_image self ); extern const char * mlt_image_format_name( mlt_image_format format ); diff --git a/src/mlt++/MltImage.cpp b/src/mlt++/MltImage.cpp index a95f7c77c..7d05ea5c3 100644 --- a/src/mlt++/MltImage.cpp +++ b/src/mlt++/MltImage.cpp @@ -67,12 +67,19 @@ int Image::colorspace() return instance->colorspace; } -void Image::alloc( int width, int height, mlt_image_format format ) +void Image::alloc( int width, int height, mlt_image_format format, bool alpha ) { instance->width = width; instance->height = height; instance->format = format; mlt_image_alloc_data( instance ); + if ( alpha ) + mlt_image_alloc_alpha( instance ); +} + +void Image::init_alpha() +{ + mlt_image_alloc_alpha( instance ); } uint8_t* Image::plane( int plane ) diff --git a/src/mlt++/MltImage.h b/src/mlt++/MltImage.h index 9046610ba..c148d0030 100644 --- a/src/mlt++/MltImage.h +++ b/src/mlt++/MltImage.h @@ -40,7 +40,8 @@ namespace Mlt int height(); void set_colorspace( int colorspace ); int colorspace(); - void alloc( int width, int height, mlt_image_format format ); + void alloc( int width, int height, mlt_image_format format, bool alpha = false ); + void init_alpha(); uint8_t* plane( int plane ); int stride( int plane ); }; diff --git a/src/mlt++/mlt++.vers b/src/mlt++/mlt++.vers index 7ef96921e..5c8be125a 100644 --- a/src/mlt++/mlt++.vers +++ b/src/mlt++/mlt++.vers @@ -667,7 +667,8 @@ MLTPP_7.0.0 { "Mlt::Image::height()"; "Mlt::Image::set_colorspace(int)"; "Mlt::Image::colorspace()"; - "Mlt::Image::alloc(int, int, mlt_image_format)"; + "Mlt::Image::alloc(int, int, mlt_image_format, bool)"; + "Mlt::Image::init_alpha()"; "Mlt::Image::plane(int)"; "Mlt::Image::stride(int)"; }; diff --git a/src/tests/test_image/test_image.cpp b/src/tests/test_image/test_image.cpp index 77fc0a599..d6c8b755f 100644 --- a/src/tests/test_image/test_image.cpp +++ b/src/tests/test_image/test_image.cpp @@ -125,6 +125,13 @@ private Q_SLOTS: i.set_colorspace(mlt_colorspace_bt709); QCOMPARE(i.colorspace(), mlt_colorspace_bt709); } + + void InitAlpha() + { + Image i(1920, 1080, mlt_image_rgb24 ); + i.init_alpha(); + QVERIFY(i.plane(3) != nullptr); + } }; QTEST_APPLESS_MAIN(TestImage) From 296de64cc2cd2d494570d295a918c71abf3f8da8 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 1 Mar 2021 21:43:56 -0600 Subject: [PATCH 053/122] Deprecate the audiowave filter Use audiowaveform instead --- src/modules/core/filter_audiowave.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/core/filter_audiowave.yml b/src/modules/core/filter_audiowave.yml index b3f3dd9e7..8aa9e3c41 100644 --- a/src/modules/core/filter_audiowave.yml +++ b/src/modules/core/filter_audiowave.yml @@ -1,13 +1,15 @@ schema_version: 0.1 type: filter identifier: audiowave -title: Audio Waveform +title: Audio Waveform (*deprecated*) version: 1 copyright: Meltytech, LLC creator: Dan Dennedy license: LGPLv2.1 language: en description: Generate audio waveforms. +notes: > + This filter is deprecated and will eventually be removed. Use the audiowaveform filter instead. tags: - Video bugs: From 7c9daf0fdd54c6b31a500f2c11ed9b704a5c91d9 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 1 Mar 2021 19:52:11 -0600 Subject: [PATCH 054/122] Remove data_feed data_show and feeds --- CMakeLists.txt | 1 - demo/mlt_attributes | 7 - src/framework/mlt_tractor.c | 59 ---- src/framework/mlt_tractor.h | 3 - src/modules/CMakeLists.txt | 4 - src/modules/core/CMakeLists.txt | 4 - src/modules/core/Makefile | 3 - src/modules/core/data_fx.properties | 259 ---------------- src/modules/core/factory.c | 5 - src/modules/core/filter_data_feed.c | 176 ----------- src/modules/core/filter_data_show.c | 360 ---------------------- src/modules/core/filter_data_show.yml | 50 --- src/modules/core/loader.ini | 3 - src/modules/feeds/CMakeLists.txt | 15 - src/modules/feeds/Makefile | 15 - src/modules/feeds/NTSC/data_fx.properties | 82 ----- src/modules/feeds/NTSC/etv.properties | 186 ----------- src/modules/feeds/NTSC/obscure.properties | 26 -- src/modules/feeds/PAL/border.properties | 22 -- src/modules/feeds/PAL/data_fx.properties | 80 ----- src/modules/feeds/PAL/etv.properties | 186 ----------- src/modules/feeds/PAL/example.properties | 12 - src/modules/feeds/PAL/obscure.properties | 35 --- src/modules/xml/consumer_xml.c | 3 - src/modules/xml/mlt-xml.dtd | 3 +- src/modules/xml/producer_xml.c | 2 - 26 files changed, 1 insertion(+), 1600 deletions(-) delete mode 100644 demo/mlt_attributes delete mode 100644 src/modules/core/data_fx.properties delete mode 100644 src/modules/core/filter_data_feed.c delete mode 100644 src/modules/core/filter_data_show.c delete mode 100644 src/modules/core/filter_data_show.yml delete mode 100644 src/modules/feeds/CMakeLists.txt delete mode 100644 src/modules/feeds/Makefile delete mode 100644 src/modules/feeds/NTSC/data_fx.properties delete mode 100644 src/modules/feeds/NTSC/etv.properties delete mode 100644 src/modules/feeds/NTSC/obscure.properties delete mode 100644 src/modules/feeds/PAL/border.properties delete mode 100644 src/modules/feeds/PAL/data_fx.properties delete mode 100644 src/modules/feeds/PAL/etv.properties delete mode 100644 src/modules/feeds/PAL/example.properties delete mode 100644 src/modules/feeds/PAL/obscure.properties diff --git a/CMakeLists.txt b/CMakeLists.txt index f7b7b3278..f89e7cbae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,6 @@ option(BUILD_DOCS "Enable Doxygen documentation" OFF) option(MOD_AVFORMAT "Enable avformat module" ON) option(MOD_DECKLINK "Enable decklink module" ON) -option(MOD_FEEDS "Enable feeds module" ON) option(MOD_FREI0R "Enable frei0r module" ON) option(MOD_GDK "Enable gdk module" ON) option(MOD_JACKRACK "Enable jackrack module" ON) diff --git a/demo/mlt_attributes b/demo/mlt_attributes deleted file mode 100644 index 570b194a5..000000000 --- a/demo/mlt_attributes +++ /dev/null @@ -1,7 +0,0 @@ -melt clip1.dv \ -meta.attr.location=1 meta.attr.location.markup="Location" \ -meta.attr.exclusive=1 meta.attr.exclusive.markup="Exclusive" \ -meta.attr.special=1 meta.attr.special.markup="Special" \ -meta.attr.super=1 meta.attr.super.0="Line 1" meta.attr.super.1="Line 2" \ --filter data_show:%etv.properties \ -$* diff --git a/src/framework/mlt_tractor.c b/src/framework/mlt_tractor.c index b466b343c..b55323614 100644 --- a/src/framework/mlt_tractor.c +++ b/src/framework/mlt_tractor.c @@ -425,22 +425,6 @@ static int producer_get_audio( mlt_frame self, void **buffer, mlt_audio_format * return 0; } -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 ); - } -} - /** Get the next frame. * * \private \memberof mlt_tractor_s @@ -472,15 +456,9 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra // Or a specific producer mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); - // Determine whether this tractor feeds to the consumer or stops here - int global_feed = mlt_properties_get_int( properties, "global_feed" ); - // If we don't have one, we're in trouble... if ( multitrack != NULL ) { - // The output frame will hold the 'global' data feeds (ie: those which are targeted for the final frame) - mlt_deque data_queue = mlt_deque_init( ); - // Used to garbage collect all frames char label[64]; @@ -554,36 +532,6 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra snprintf( label, sizeof(label), "mlt_tractor %s_%d", id, count ++ ); mlt_properties_set_data( frame_properties, label, temp, 0, ( mlt_destructor )mlt_frame_close, NULL ); - // We want to append all 'final' feeds to the global queue - if ( !done && mlt_properties_get_data( temp_properties, "data_queue", NULL ) != NULL ) - { - // Move the contents of this queue on to the output frames data queue - mlt_deque sub_queue = mlt_properties_get_data( MLT_FRAME_PROPERTIES( temp ), "data_queue", NULL ); - mlt_deque temp = mlt_deque_init( ); - while ( global_feed && mlt_deque_count( sub_queue ) ) - { - mlt_properties p = mlt_deque_pop_back( sub_queue ); - if ( mlt_properties_get_int( p, "final" ) ) - mlt_deque_push_back( data_queue, p ); - else - mlt_deque_push_back( temp, p ); - } - while( mlt_deque_count( temp ) ) - mlt_deque_push_front( sub_queue, mlt_deque_pop_back( temp ) ); - mlt_deque_close( temp ); - } - - // Now do the same with the global queue but without the conditional behaviour - if ( mlt_properties_get_data( temp_properties, "global_queue", NULL ) != NULL ) - { - mlt_deque sub_queue = mlt_properties_get_data( MLT_FRAME_PROPERTIES( temp ), "global_queue", NULL ); - while ( mlt_deque_count( sub_queue ) ) - { - mlt_properties p = mlt_deque_pop_back( sub_queue ); - mlt_deque_push_back( data_queue, p ); - } - } - // Pick up first video and audio frames if ( !done && !mlt_frame_is_test_audio( temp ) && !( mlt_properties_get_int( temp_properties, "hide" ) & 2 ) ) { @@ -623,9 +571,6 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra mlt_properties video_properties = MLT_FRAME_PROPERTIES( first_video ); mlt_frame_push_service( *frame, video ); mlt_frame_push_service( *frame, producer_get_image ); - if ( global_feed ) - mlt_properties_set_data( frame_properties, "data_queue", data_queue, 0, NULL, NULL ); - mlt_properties_set_data( video_properties, "global_queue", data_queue, 0, destroy_data_queue, NULL ); mlt_properties_set_int( frame_properties, "width", mlt_properties_get_int( video_properties, "width" ) ); mlt_properties_set_int( frame_properties, "height", mlt_properties_get_int( video_properties, "height" ) ); mlt_properties_pass_list( frame_properties, video_properties, "meta.media.width, meta.media.height" ); @@ -634,10 +579,6 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra mlt_properties_set_int( frame_properties, "image_count", image_count ); mlt_properties_set_data( frame_properties, "_producer", mlt_frame_get_original_producer( first_video ), 0, NULL, NULL ); } - else - { - destroy_data_queue( data_queue ); - } mlt_frame_set_position( *frame, mlt_producer_frame( parent ) ); mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_audio", audio == NULL ); diff --git a/src/framework/mlt_tractor.h b/src/framework/mlt_tractor.h index 8b23418e1..0188adeed 100644 --- a/src/framework/mlt_tractor.h +++ b/src/framework/mlt_tractor.h @@ -34,9 +34,6 @@ * \properties \em multitrack holds a reference to the mulitrack object that a tractor manages * \properties \em field holds a reference to the field object that a tractor manages * \properties \em producer holds a reference to an encapsulated producer - * \properties \em global_feed a flag to indicate whether this tractor feeds to the consumer or stops here - * \properties \em global_queue is something for the data_feed functionality in the core module - * \properties \em data_queue is something for the data_feed functionality in the core module */ struct mlt_tractor_s diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index adc8eb394..d1ebe2d03 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -8,10 +8,6 @@ if(MOD_DECKLINK) add_subdirectory(decklink) endif() -if(MOD_FEEDS) - add_subdirectory(feeds) -endif() - if(MOD_FREI0R AND FREI0R_FOUND) add_subdirectory(frei0r) endif() diff --git a/src/modules/core/CMakeLists.txt b/src/modules/core/CMakeLists.txt index 34424d8c0..4877d1155 100644 --- a/src/modules/core/CMakeLists.txt +++ b/src/modules/core/CMakeLists.txt @@ -10,8 +10,6 @@ add_library(mltcore MODULE filter_channelcopy.c filter_choppy.c filter_crop.c - filter_data_feed.c - filter_data_show.c filter_fieldorder.c filter_gamma.c filter_greyscale.c @@ -67,7 +65,6 @@ install(FILES filter_channelcopy.yml filter_choppy.yml filter_crop.yml - filter_data_show.yml filter_fieldorder.yml filter_gamma.yml filter_greyscale.yml @@ -98,7 +95,6 @@ install(FILES transition_matte.yml transition_mix.yml transition_region.yml - data_fx.properties loader.dict loader.ini DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/core diff --git a/src/modules/core/Makefile b/src/modules/core/Makefile index 390b66bdc..b7e8dc304 100644 --- a/src/modules/core/Makefile +++ b/src/modules/core/Makefile @@ -23,8 +23,6 @@ OBJS = factory.o \ filter_channelcopy.o \ filter_choppy.o \ filter_crop.o \ - filter_data_feed.o \ - filter_data_show.o \ filter_fieldorder.o \ filter_gamma.o \ filter_greyscale.o \ @@ -86,7 +84,6 @@ clean: install: all install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" install -d "$(DESTDIR)$(mltdatadir)/core" - install -m 644 data_fx.properties "$(DESTDIR)$(mltdatadir)/core" install -m 644 loader.dict "$(DESTDIR)$(mltdatadir)/core" install -m 644 loader.ini "$(DESTDIR)$(mltdatadir)/core" install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/core" diff --git a/src/modules/core/data_fx.properties b/src/modules/core/data_fx.properties deleted file mode 100644 index 2a4c1bc4e..000000000 --- a/src/modules/core/data_fx.properties +++ /dev/null @@ -1,259 +0,0 @@ -# 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 -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%,70%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:0;5=0%,0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%,0%:100%x100%:0;8=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 - -# -# The top titles filter definition -# - -top-titles=region -.description=Top Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%,5%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:0;5=0%,0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%,0%:100%x100%:0;8=0%,0%:100%x100%:100 -.filter[1].composite.halign=centre -.filter[1].composite.titles=1 - -# -# OK - Silly example... -# - -tickertape=region -.description=Tickertape -.properties.markup=filter[1].producer.markup -.type.markup=text -.properties.length[0]=filter[1].composite.out -.composite.geometry=0%,93%:100%x7% -.filter[0]=watermark -.filter[0].resource=colour:0x000000 -.filter[0].composite.geometry=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=100%,0%:300%x100%:100;-1=-300%,0%:300%x100%:100 -.filter[1].producer.family=San -.filter[1].producer.size=32 -.filter[1].composite.titles=1 - -# -# ETV Location -# - -location=region -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=0,80:230x30 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=-100%,0%:100%x100%:100;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup= -.filter[1].producer.family=San -.filter[1].producer.size=24 -.filter[1].composite.geometry=0%,0%:100%x100%:0;24=0%,0%:100%x100%:0;49=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=center - -courtesy=region -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=0,115:230x30 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=-100%,0%:100%x100%:0;12=-100%,0%:100%x100%:0;37=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=ETV Exclusive -.filter[1].producer.family=San -.filter[1].producer.size=24 -.filter[1].composite.geometry=0%,0%:100%x100%:0;37=0%,0%:100%x100%:0;61=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=right - -exclusive=region -.description=Exclusive -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=0,115:230x30 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=ETV Exclusive -.filter[1].producer.family=San -.filter[1].producer.size=24 -.filter[1].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=right - -file_shot=region -.description=Titles -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=590,160:80x25 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=File Shot -.filter[1].producer.family=San -.filter[1].producer.size=18 -.filter[1].composite.geometry=0%,0%:100%x100%:15;25=0%,0%:100%x100%:100 -.filter[1].composite.titles=0 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -special=region -.description=Titles -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=465,375:255x35 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=100%,0%:100%x100%:0;49=100%,0%:100%x100%:0;74=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Special -.filter[1].producer.family=San -.filter[1].producer.size=24 -.filter[1].composite.geometry=100%,0%:100%x100%:0;49=100%,0%:100%x100%:0;74=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -ticker=region -.description=Tickertape -.properties.markup=filter[1].producer.markup -.type.markup=text -.properties.length[0]=filter[1].composite.out -.composite.geometry=0,500:722x75 -.filter[0]=watermark -.filter[0].resource=colour:0x6c010100 -.filter[0].composite.geometry=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Ticker - provided for reference -.filter[1].composite.geometry=0%,0%:100%x100%:100 -.filter[1].composite.titles=0 -.filter[1].producer.family=San -.filter[1].producer.size=24 -.filter[1].composite.halign=centre -.filter[1].composite.titles=1 -.filter[1].composite.valign=centre - -super=region -.description=Transcription -.properties.0=filter[1].producer.markup -.properties.1=filter[2].producer.markup -.properties.align=filter[1].composite.valign -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.properties.length[2]=filter[2].composite.out -.period=2 -.composite.geometry=0,410:720x90 -.filter[0]=watermark -.filter[0].resource=colour:0xbbbbbb00 -.filter[0].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[0].composite.luma=%luma18.pgm -.filter[0].composite.out=25 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup= -.filter[1].producer.family=San -.filter[1].producer.size=32 -.filter[1].producer.fgcolour=0x6c0101ff -.filter[1].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=top -.filter[2]=watermark -.filter[2].resource=pango: -.filter[2].producer.markup= -.filter[1].producer.family=San -.filter[1].producer.size=32 -.filter[2].producer.fgcolour=0x6c0101ff -.filter[2].composite.geometry=0%,0%:100%x100%:10;25=0%,0%:100%x100%:100 -.filter[2].composite.titles=1 -.filter[2].composite.halign=centre -.filter[2].composite.valign=bottom - -obscure=region -.description=Obscure -.properties.geometry=composite.geometry -.properties.resource=resource -.properties.length[0]=composite.out -.composite.geometry= -.resource=rectangle -.composite.refresh=1 -.filter[0]=obscure -.filter[0].start=0,0:100%x100% - diff --git a/src/modules/core/factory.c b/src/modules/core/factory.c index 6c0bff5e8..8305d033f 100644 --- a/src/modules/core/factory.c +++ b/src/modules/core/factory.c @@ -31,8 +31,6 @@ extern mlt_filter filter_brightness_init( mlt_profile profile, mlt_service_type extern mlt_filter filter_channelcopy_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_choppy_init(mlt_profile profile, mlt_service_type type, const char *id, char *arg); extern mlt_filter filter_crop_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_data_feed_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_data_show_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_fieldorder_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_gamma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_greyscale_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); @@ -85,8 +83,6 @@ MLT_REPOSITORY MLT_REGISTER( mlt_service_filter_type, "channelswap", filter_channelcopy_init ); MLT_REGISTER( mlt_service_filter_type, "choppy", filter_choppy_init ); MLT_REGISTER( mlt_service_filter_type, "crop", filter_crop_init ); - MLT_REGISTER( mlt_service_filter_type, "data_feed", filter_data_feed_init ); - MLT_REGISTER( mlt_service_filter_type, "data_show", filter_data_show_init ); MLT_REGISTER( mlt_service_filter_type, "fieldorder", filter_fieldorder_init ); MLT_REGISTER( mlt_service_filter_type, "gamma", filter_gamma_init ); MLT_REGISTER( mlt_service_filter_type, "greyscale", filter_greyscale_init ); @@ -130,7 +126,6 @@ MLT_REPOSITORY MLT_REGISTER_METADATA( mlt_service_filter_type, "channelswap", metadata, "filter_channelcopy.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "choppy", metadata, "filter_choppy.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "crop", metadata, "filter_crop.yml" ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "data_show", metadata, "filter_data_show.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "fieldorder", metadata, "filter_fieldorder.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "gamma", metadata, "filter_gamma.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "greyscale", metadata, "filter_greyscale.yml" ); diff --git a/src/modules/core/filter_data_feed.c b/src/modules/core/filter_data_feed.c deleted file mode 100644 index aab144a21..000000000 --- a/src/modules/core/filter_data_feed.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * filter_data_feed.c -- data feed filter - * Copyright (C) 2004-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -/** This filter should be used in conjunction 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 filter, mlt_frame frame ) -{ - // Get the filter properties - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - // 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 ); - - // Get the type of the data feed - char *type = mlt_properties_get( filter_properties, "type" ); - - // Get the in and out points of this filter - int in = mlt_filter_get_in( filter ); - int out = mlt_filter_get_out( filter ); - - // 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 && type != NULL && !strcmp( type, "attr_check" ) ) - { - int i = 0; - int count = mlt_properties_count( frame_properties ); - - for ( i = 0; i < count; i ++ ) - { - char *name = mlt_properties_get_name( frame_properties, i ); - - // Only deal with meta.attr.name values here - these should have a value of 1 to be considered - // Additional properties of the form are meta.attr.name.property are passed down on the feed - if ( !strncmp( name, "meta.attr.", 10 ) && strchr( name + 10, '.' ) == NULL && mlt_properties_get_int( frame_properties, name ) == 1 ) - { - // Temp var to hold name + '.' for pass method - char temp[ 132 ]; - - // Create a new data feed - mlt_properties feed = mlt_properties_new( ); - - // Assign it the base properties - mlt_properties_set( feed, "id", mlt_properties_get( filter_properties, "_unique_id" ) ); - mlt_properties_set( feed, "type", strrchr( name, '.' ) + 1 ); - 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" ) ); - - // Pass all meta properties - sprintf( temp, "%s.", name ); - mlt_properties_pass( feed, frame_properties, temp ); - - // Push it on to the queue - mlt_deque_push_back( data_queue, feed ); - - // Make sure this attribute only gets processed once - mlt_properties_set_int( frame_properties, name, 0 ); - } - } - } - else if ( data_queue != NULL ) - { - // Create a new data feed - mlt_properties feed = mlt_properties_new( ); - - // 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( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create the filter - mlt_filter filter = mlt_filter_new( ); - - // Initialise it - if ( filter != NULL ) - { - // Get the properties - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - - // Assign the argument (default to titles) - mlt_properties_set( properties, "type", arg == NULL ? "titles" : arg ); - - // Specify the processing method - filter->process = filter_process; - } - - return filter; -} - diff --git a/src/modules/core/filter_data_show.c b/src/modules/core/filter_data_show.c deleted file mode 100644 index e0282d626..000000000 --- a/src/modules/core/filter_data_show.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * filter_data_show.c -- data feed filter - * Copyright (C) 2004-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include - -/** Handle the profile. -*/ - -static mlt_filter obtain_filter( mlt_filter filter, char *type ) -{ - // Result to return - mlt_filter result = NULL; - - // Miscellaneous 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 ) - { - char temp[ 512 ]; - - // Get the profile requested - char *profile = mlt_properties_get( filter_properties, "resource" ); - - // If none is specified, pick up the default for this normalisation - if ( profile == NULL ) - sprintf( temp, "%s/feeds/%s/data_fx.properties", mlt_environment( "MLT_DATA" ), mlt_environment( "MLT_NORMALISATION" ) ); - else if ( strchr( profile, '%' ) ) - sprintf( temp, "%s/feeds/%s/%s", mlt_environment( "MLT_DATA" ), mlt_environment( "MLT_NORMALISATION" ), strchr( profile, '%' ) + 1 ); - else - { - strncpy( temp, profile, sizeof( temp ) ); - temp[ sizeof( temp ) - 1 ] = '\0'; - } - - // Load the specified profile or use the default - profile_properties = mlt_properties_load( 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( mlt_service_profile( MLT_FILTER_SERVICE( 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; -} - -/** Retrieve medatata value -*/ - -char* metadata_value(mlt_properties properties, char* name) -{ - if (name == NULL) return NULL; - char *meta = malloc( strlen(name) + 18 ); - sprintf( meta, "meta.attr.%s.markup", name); - char *result = mlt_properties_get( properties, meta); - free(meta); - return result; -} - -/** Convert frames to Timecode -*/ - -char* frame_to_timecode( int frames, double fps) -{ - if (fps == 0) return strdup("-"); - char *res = malloc(12); - int seconds = frames / fps; - frames = frames % lrint( fps ); - int minutes = seconds / 60; - seconds = seconds % 60; - int hours = minutes / 60; - minutes = minutes % 60; - sprintf(res, "%.2d:%.2d:%.2d:%.2d", hours, minutes, seconds, frames); - return res; -} - -/** 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 ); - - // 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 const char *prefix = "properties."; - int len = strlen( prefix ); - - // Determine if this is an absolute or relative feed - int absolute = mlt_properties_get_int( feed, "absolute" ); - - // Make do with what we have - int length = !absolute ? - mlt_properties_get_int( feed, "out" ) - mlt_properties_get_int( feed, "in" ) + 1 : - mlt_properties_get_int( feed, "out" ) + 1; - - // Repeat period - int period = mlt_properties_get_int( properties, "period" ); - period = period == 0 ? 1 : period; - - // 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 ) ) - { - mlt_properties_set_position( properties, key, ( length - period ) / period ); - } - else - { - char *value = mlt_properties_get( feed, name + len ); - if ( value != NULL ) - { - // check for metadata keywords in metadata markup if user requested so - if ( mlt_properties_get_int( filter_properties, "dynamic" ) == 1 && !strcmp( name + strlen( name ) - 6, "markup") ) - { - // Find keywords which should be surrounded by '#', like: #title# - char* keywords = strtok( value, "#" ); - char result[512] = ""; // XXX: how much is enough? - int ct = 0; - int fromStart = ( value[0] == '#' ) ? 1 : 0; - - while ( keywords != NULL ) - { - if ( ct % 2 == fromStart ) - { - // backslash in front of # suppresses substitution - if ( keywords[ strlen( keywords ) -1 ] == '\\' ) - { - // keep characters except backslash - strncat( result, keywords, sizeof( result ) - strlen( result ) - 2 ); - strcat( result, "#" ); - ct++; - } - else - { - strncat( result, keywords, sizeof( result ) - strlen( result ) - 1 ); - } - } - else if ( !strcmp( keywords, "timecode" ) ) - { - // special case: replace #timecode# with current frame timecode - mlt_position frames = mlt_properties_get_position( feed, "position" ); - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - char *s = mlt_properties_frames_to_time( properties, frames, mlt_time_smpte_df ); - if ( s ) - strncat( result, s, sizeof( result ) - strlen( result ) - 1 ); - } - else if ( !strcmp( keywords, "frame" ) ) - { - // special case: replace #frame# with current frame number - int pos = mlt_properties_get_int( feed, "position" ); - char s[12]; - snprintf( s, sizeof(s) - 1, "%d", pos ); - s[sizeof( s ) - 1] = '\0'; - strncat( result, s, sizeof( result ) - strlen( result ) - 1 ); - } - else - { - // replace keyword with metadata value - char *metavalue = metadata_value( MLT_FRAME_PROPERTIES( frame ), keywords ); - strncat( result, metavalue ? metavalue : "-", sizeof( result ) - strlen( result ) -1 ); - } - keywords = strtok( NULL, "#" ); - ct++; - } - mlt_properties_set( properties, key, (char*) result ); - } - else mlt_properties_set( properties, key, value ); - } - } - } - } - - // Set the original position on the frame - if ( absolute == 0 ) - mlt_frame_set_position( frame, mlt_properties_get_int( feed, "position" ) - mlt_properties_get_int( feed, "in" ) ); - else - 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; -} - -void process_queue( mlt_deque data_queue, mlt_frame frame, mlt_filter filter ) -{ - if ( data_queue != NULL ) - { - // Create a new queue for those that we can't handle - mlt_deque temp_queue = mlt_deque_init( ); - - // Iterate through each entry on the queue - while ( mlt_deque_peek_front( data_queue ) != NULL ) - { - // Get the data feed - mlt_properties feed = mlt_deque_pop_front( data_queue ); - - if ( mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "debug" ) != NULL ) - mlt_properties_debug( feed, mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "debug" ), stderr ); - - // Process the data feed... - if ( process_feed( feed, filter, frame ) == 0 ) - mlt_properties_close( feed ); - else - mlt_deque_push_back( temp_queue, feed ); - } - - // Now put the unprocessed feeds back on the stack - while ( mlt_deque_peek_front( temp_queue ) ) - { - // Get the data feed - mlt_properties feed = mlt_deque_pop_front( temp_queue ); - - // Put it back on the data queue - mlt_deque_push_back( data_queue, feed ); - } - - // Close the temporary queue - mlt_deque_close( temp_queue ); - } -} - -/** 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 ); - - mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); - - // Track specific - process_queue( mlt_properties_get_data( frame_properties, "data_queue", NULL ), frame, filter ); - - // Global - process_queue( mlt_properties_get_data( frame_properties, "global_queue", NULL ), frame, filter ); - - mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); - - // 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 filter, mlt_frame frame ) -{ - // Push the filter - mlt_frame_push_service( frame, filter ); - - // 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( mlt_profile profile, mlt_service_type type, const char *id, void *arg ) -{ - // Create the filter - mlt_filter filter = mlt_filter_new( ); - - // Initialise it - if ( filter != NULL ) - { - // Get the properties - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - - // Assign the argument (default to titles) - mlt_properties_set( properties, "resource", arg == NULL ? NULL : arg ); - - // Specify the processing method - filter->process = filter_process; - } - - return filter; -} - diff --git a/src/modules/core/filter_data_show.yml b/src/modules/core/filter_data_show.yml deleted file mode 100644 index 0e051de18..000000000 --- a/src/modules/core/filter_data_show.yml +++ /dev/null @@ -1,50 +0,0 @@ -schema_version: 0.1 -type: filter -identifier: data_show -title: Template -version: 1 -copyright: Meltytech, LLC -creator: Charles Yates -license: LGPLv2.1 -language: en -tags: - - Video -description: Show data based on properties of the producer. -notes: | - The data show filter uses data provided by the data feed filter. - The producer properties must supply: > - * The keyword text to be inserted in the form of: - meta.attr.[keyword].markup=[text to insert] - - * The name of the properties to be used from the feed file in the form of: - meta.attr.[name]=1 - - * The text to be displayed in the form of: - meta.attr.[name].markup=[some text #keyword#] - (Keyword text is enclosed between #s.) - - e.g. - melt file.dv meta.attr.sometext.markup="this is some text" meta.attr.titles=1 meta.attr.titles.markup=#sometext# -filter data_show dynamic=1 - > - Two special keywords exist - * #timecode# shows the frame position as a timecode. - * #frame# shows the frame position as an integer. - e.g. - melt file.dv meta.attr.timecode=1 meta.attr.timecode.markup=#timecode# -attach data_feed:attr_check -attach data_show:custom_file.properties dynamic=1 - (where the file "custom_file" contains a filter definition by the name of "timecode") -parameters: - - identifier: argument - title: Feed Properties File - type: string - required: no - readonly: no - default: data_fx.properties - widget: fileopen - - - identifier: dynamic - title: Dynamic - type: integer - default: 0 - minimum: 0 - maximum: 1 - widget: checkbox diff --git a/src/modules/core/loader.ini b/src/modules/core/loader.ini index d861e3b29..99d3987ee 100644 --- a/src/modules/core/loader.ini +++ b/src/modules/core/loader.ini @@ -16,6 +16,3 @@ resizer=movit.resize,resize # audio filters channels=swresample,audiochannels resampler=resample - -# metadata filters -data=data_feed:attr_check diff --git a/src/modules/feeds/CMakeLists.txt b/src/modules/feeds/CMakeLists.txt deleted file mode 100644 index 7d9af45d7..000000000 --- a/src/modules/feeds/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -install(FILES - NTSC/data_fx.properties - NTSC/etv.properties - NTSC/obscure.properties - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/feeds/NTSC -) - -install(FILES - PAL/border.properties - PAL/data_fx.properties - PAL/etv.properties - PAL/example.properties - PAL/obscure.properties - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/feeds/PAL -) diff --git a/src/modules/feeds/Makefile b/src/modules/feeds/Makefile deleted file mode 100644 index 45bd7aed2..000000000 --- a/src/modules/feeds/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -include ../../../config.mak - -all: - -depend: - -distclean: - -clean: - -install: all - install -d "$(DESTDIR)$(mltdatadir)/feeds/PAL" - install -d "$(DESTDIR)$(mltdatadir)/feeds/NTSC" - install -m 644 PAL/*.* "$(DESTDIR)$(mltdatadir)/feeds/PAL" - install -m 644 NTSC/*.* "$(DESTDIR)$(mltdatadir)/feeds/NTSC" diff --git a/src/modules/feeds/NTSC/data_fx.properties b/src/modules/feeds/NTSC/data_fx.properties deleted file mode 100644 index fced7929a..000000000 --- a/src/modules/feeds/NTSC/data_fx.properties +++ /dev/null @@ -1,82 +0,0 @@ -# This properties file describes the fx available to the data_feed 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 -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%/70%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000ff -.filter[0].composite.geometry=0%/0%:100%x100%:0;5=0%/0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%/0%:100%x100%:0;8=0%/0%:100%x100%:100 -.filter[1].composite.titles=1 - -# -# The top titles filter definition -# - -top-titles=region -.description=Top Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%/5%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000ff -.filter[0].composite.geometry=0%/0%:100%x100%:0;5=0%/0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%/0%:100%x100%:0;8=0%/0%:100%x100%:100 -.filter[1].composite.halign=centre -.filter[1].composite.titles=1 - -# -# OK - Silly example... -# - -tickertape=region -.description=Tickertape -.properties.markup=filter[1].producer.markup -.type.markup=text -.properties.length[0]=filter[1].composite.out -.composite.geometry=0%/93%:100%x7% -.filter[0]=watermark -.filter[0].resource=colour:0x000000ff -.filter[0].composite.geometry=0%/0%:100%x100%:100 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=100%/0%:300%x100%:100;-1=-300%/0%:300%x100%:100 -.filter[1].producer.family=San -.filter[1].producer.size=32 -.filter[1].composite.titles=1 - diff --git a/src/modules/feeds/NTSC/etv.properties b/src/modules/feeds/NTSC/etv.properties deleted file mode 100644 index 421a48506..000000000 --- a/src/modules/feeds/NTSC/etv.properties +++ /dev/null @@ -1,186 +0,0 @@ -# This properties file describes the fx available to the data_feed 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. -# - -location=region -.description=Titles -.properties.markup=filter[1].producer.text -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0/14%:32%x5%:0;15=/:x:100 -.composite.luma=%luma01.pgm -.composite.softness=.3 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text= -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].composite.geometry=0/0:95%x100% -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=center - -courtesy=region -.description=Courtesy -.properties.markup=filter[1].producer.text -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0/20%:32%x5%:0;15=/:x:100 -.composite.luma=%luma01.pgm -.composite.softness=.3 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text= -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].composite.geometry=0/0:95%x100% -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=centre - -exclusive=region -.description=Exclusive -.properties.markup=filter[1].producer.text -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.period=2 -.properties.length[0]=composite.out -.composite.geometry=-32%/20%:32%x5%;15=0 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=ETV Exclusive -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].producer.weight=700 -.filter[1].composite.geometry=0/0:95%x100% -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=centre - -file_shot=region -.description=Titles -.period=2 -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.properties.length[0]=composite.out -.composite.geometry=82%/28%:11%x4%:0;15=/:x:100 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=File Shot -.filter[1].producer.family=Sans -.filter[1].producer.size=18 -.filter[1].producer.weight=700 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -special=region -.description=Special -.period=2 -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=65%/65%:35%x6% -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.geometry=100%/0%:100%x100%:0;15=0%/0%:x:100 -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=Special -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].producer.weight=700 -.filter[1].composite.geometry=100%/0%:100%x100%:0;15=0%/0%:x:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -ticker=region -.description=Tickertape -.properties.markup=filter[1].producer.text -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.properties.length[0]=filter[1].composite.out -.composite.geometry=0/87%:101%x13% -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=Ticker - provided for reference -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].producer.weight=700 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -super=region -.description=Transcription -.properties.0=filter[1].producer.text -.properties.1=filter[2].producer.text -.properties.align=filter[1].composite.valign -.properties.weight=filter[1].producer.weight -.properties.f0=filter[1].producer.family -.properties.s0=filter[1].producer.size -.properties.f1=filter[2].producer.family -.properties.s1=filter[2].producer.size -.properties.length[0]=composite.out -.period=2 -.composite.geometry=0/71%:100%x16%:0;30=/:x:100 -.composite.luma=%luma01.pgm -.composite.luma_invert=1 -.composite.softness=.3 -.filter[0]=watermark -.filter[0].resource=colour:0xbbbbbbff -.filter[0].composite.geometry=0/0:100%:100%:70 -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text= -.filter[1].producer.family=Sans -.filter[1].producer.size=32 -.filter[1].producer.weight=700 -.filter[1].producer.fgcolour=0x6c0101ff -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=top -.filter[2]=watermark -.filter[2].resource=pango: -.filter[2].producer.text= -.filter[2].producer.family=Sans -.filter[2].producer.size=32 -.filter[2].producer.fgcolour=0x6c0101ff -.filter[2].composite.titles=1 -.filter[2].composite.halign=centre -.filter[2].composite.valign=bottom - diff --git a/src/modules/feeds/NTSC/obscure.properties b/src/modules/feeds/NTSC/obscure.properties deleted file mode 100644 index f42383192..000000000 --- a/src/modules/feeds/NTSC/obscure.properties +++ /dev/null @@ -1,26 +0,0 @@ -# This properties file describes the fx available to the data_feed 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. -# - -obscure=region -.description=Obscure -.properties.geometry=composite.geometry -.properties.resource=resource -.properties.length[0]=composite.out -.composite.geometry= -.resource=rectangle -.composite.refresh=1 -.filter[0]=obscure -.filter[0].start=0/0:100%x100% - diff --git a/src/modules/feeds/PAL/border.properties b/src/modules/feeds/PAL/border.properties deleted file mode 100644 index 5acf2898b..000000000 --- a/src/modules/feeds/PAL/border.properties +++ /dev/null @@ -1,22 +0,0 @@ -border_left=watermark -.description=Border Left -.resource=colour:black -.reverse=1 -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0/0:100%x100%;25=2.5%/17.5%:45%x45% -.composite.halign=c -.composite.valign=c -.composite.fill=1 - -border_right=watermark -.description=Border Right -.resource=colour:black -.reverse=1 -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0/0:100%x100%;25=52.5%/17.5%:45%x45% -.composite.halign=c -.composite.valign=c -.composite.fill=1 - diff --git a/src/modules/feeds/PAL/data_fx.properties b/src/modules/feeds/PAL/data_fx.properties deleted file mode 100644 index 94a5cf202..000000000 --- a/src/modules/feeds/PAL/data_fx.properties +++ /dev/null @@ -1,80 +0,0 @@ -# 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 -.description=Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%/70%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000ff -.filter[0].composite.geometry=0%/0%:100%x100%:0;5=0%/0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%/0%:100%x100%:0;8=0%/0%:100%x100%:100 -.filter[1].composite.titles=1 - -# -# The top titles filter definition -# - -top-titles=region -.description=Top Titles -.properties.markup=filter[1].producer.markup -.type.markup=text -.period=2 -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=5%/5%:90%x20% -.filter[0]=watermark -.filter[0].resource=colour:0x000000ff -.filter[0].composite.geometry=0%/0%:100%x100%:0;5=0%/0%:100%x100%:40 -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=0%/0%:100%x100%:0;8=0%/0%:100%x100%:100 -.filter[1].composite.titles=1 - -# -# OK - Silly example... -# - -tickertape=region -.description=Tickertape -.properties.markup=filter[1].producer.markup -.type.markup=text -.properties.length[0]=filter[1].composite.out -.composite.geometry=0%/93%:100%x7% -.filter[0]=watermark -.filter[0].resource=colour:0x000000ff -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.markup=Shotcut -.filter[1].composite.geometry=100%/0%:300%x100%:100;-1=-300%/0%:300%x100%:100 -.filter[1].producer.family=San -.filter[1].producer.size=32 -.filter[1].composite.titles=1 - diff --git a/src/modules/feeds/PAL/etv.properties b/src/modules/feeds/PAL/etv.properties deleted file mode 100644 index e45f2823e..000000000 --- a/src/modules/feeds/PAL/etv.properties +++ /dev/null @@ -1,186 +0,0 @@ -# This properties file describes the fx available to the data_feed 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. -# - -location=region -.description=Titles -.properties.markup=filter[1].producer.text -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0/14%:32%x5%:0;12=/:x:100 -.composite.luma=%luma01.pgm -.composite.softness=.3 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text= -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].composite.geometry=0/0:95%x100% -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=center - -courtesy=region -.description=Courtesy -.properties.markup=filter[1].producer.text -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.period=2 -.properties.length[0]=composite.out -.composite.geometry=0/20%:32%x5%:0;12=/:x:100 -.composite.luma=%luma01.pgm -.composite.softness=.3 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text= -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].composite.geometry=0/0:95%x100% -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=centre - -exclusive=region -.description=Exclusive -.properties.markup=filter[1].producer.text -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.period=2 -.properties.length[0]=composite.out -.composite.geometry=-32%/20%:32%x5%;12=0 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=ETV Exclusive -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].producer.weight=700 -.filter[1].composite.geometry=0/0:95%x100% -.filter[1].composite.titles=1 -.filter[1].composite.halign=right -.filter[1].composite.valign=centre - -file_shot=region -.description=Titles -.period=2 -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.properties.length[0]=composite.out -.composite.geometry=82%/28%:11%x4%:0;12=/:x:100 -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=File Shot -.filter[1].producer.family=Sans -.filter[1].producer.size=18 -.filter[1].producer.weight=700 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -special=region -.description=Special -.period=2 -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.properties.length[0]=filter[0].composite.out -.properties.length[1]=filter[1].composite.out -.composite.geometry=65%/65%:35%x6% -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.geometry=100%/0%:100%x100%:0;12=0%/0%:x:100 -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=Special -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].producer.weight=700 -.filter[1].composite.geometry=100%/0%:100%x100%:0;12=0%/0%:x:100 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -ticker=region -.description=Tickertape -.properties.markup=filter[1].producer.text -.properties.family=filter[1].producer.family -.properties.size=filter[1].producer.size -.properties.length[0]=filter[1].composite.out -.composite.geometry=0/87%:101%x13% -.filter[0]=watermark -.filter[0].resource=colour:0x6c0101ff -.filter[0].composite.titles=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text=Ticker - provided for reference -.filter[1].producer.family=Sans -.filter[1].producer.size=24 -.filter[1].producer.weight=700 -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=centre - -super=region -.description=Transcription -.properties.0=filter[1].producer.text -.properties.1=filter[2].producer.text -.properties.align=filter[1].composite.valign -.properties.weight=filter[1].producer.weight -.properties.f0=filter[1].producer.family -.properties.s0=filter[1].producer.size -.properties.f1=filter[2].producer.family -.properties.s1=filter[2].producer.size -.properties.length[0]=composite.out -.period=2 -.composite.geometry=0/71%:100%x16%:0;25=/:x:100 -.composite.luma=%luma01.pgm -.composite.luma_invert=1 -.composite.softness=.3 -.filter[0]=watermark -.filter[0].resource=colour:0xbbbbbbff -.filter[0].composite.geometry=0/0:100%:100%:70 -.filter[0].composite.distort=1 -.filter[1]=watermark -.filter[1].resource=pango: -.filter[1].producer.text= -.filter[1].producer.family=Sans -.filter[1].producer.size=32 -.filter[1].producer.weight=700 -.filter[1].producer.fgcolour=0x6c0101ff -.filter[1].composite.titles=1 -.filter[1].composite.halign=centre -.filter[1].composite.valign=top -.filter[2]=watermark -.filter[2].resource=pango: -.filter[2].producer.text= -.filter[2].producer.family=Sans -.filter[2].producer.size=32 -.filter[2].producer.fgcolour=0x6c0101ff -.filter[2].composite.titles=1 -.filter[2].composite.halign=centre -.filter[2].composite.valign=bottom - diff --git a/src/modules/feeds/PAL/example.properties b/src/modules/feeds/PAL/example.properties deleted file mode 100644 index 0509fff87..000000000 --- a/src/modules/feeds/PAL/example.properties +++ /dev/null @@ -1,12 +0,0 @@ -greyscale=greyscale -.description=Greyscale - -sepia=sepia -.description=Sepia - -charcoal=charcoal -.description=Charcoal - -invert=invert -.description=Invert - diff --git a/src/modules/feeds/PAL/obscure.properties b/src/modules/feeds/PAL/obscure.properties deleted file mode 100644 index 3917d9a53..000000000 --- a/src/modules/feeds/PAL/obscure.properties +++ /dev/null @@ -1,35 +0,0 @@ -# This properties file describes the fx available to the data_feed 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. -# - -obscure0=region -.description=Primary Obscure -.properties.geometry=composite.geometry -.properties.resource=resource -.properties.length[0]=composite.out -.composite.geometry= -.resource=rectangle -.composite.refresh=1 -.filter[0]=obscure - -obscure1=region -.description=Secondary Obscure -.properties.geometry=composite.geometry -.properties.resource=resource -.properties.length[0]=composite.out -.composite.geometry= -.resource=rectangle -.composite.refresh=1 -.filter[0]=obscure - diff --git a/src/modules/xml/consumer_xml.c b/src/modules/xml/consumer_xml.c index 5812fe0a7..8992569d0 100644 --- a/src/modules/xml/consumer_xml.c +++ b/src/modules/xml/consumer_xml.c @@ -535,8 +535,6 @@ static void serialise_tractor( serialise_context context, mlt_service service, x xmlNewProp( child, _x("id"), _x(id) ); if ( mlt_properties_get( properties, "title" ) ) xmlNewProp( child, _x("title"), _x(mlt_properties_get( properties, "title" )) ); - if ( mlt_properties_get( properties, "global_feed" ) ) - xmlNewProp( child, _x("global_feed"), _x(mlt_properties_get( properties, "global_feed" )) ); if ( mlt_properties_get_position( properties, "in" ) >= 0 ) xmlNewProp( child, _x("in"), _x(mlt_properties_get_time( properties, "in", context->time_format )) ); if ( mlt_properties_get_position( properties, "out" ) >= 0 ) @@ -862,7 +860,6 @@ xmlDocPtr xml_make_doc( mlt_consumer consumer, mlt_service service ) // Assign a title property if ( mlt_properties_get( properties, "title" ) != NULL ) xmlNewProp( root, _x("title"), _x(mlt_properties_get( properties, "title" )) ); - mlt_properties_set_int( properties, "global_feed", 1 ); // Add a profile child element if ( profile ) diff --git a/src/modules/xml/mlt-xml.dtd b/src/modules/xml/mlt-xml.dtd index ececaf39a..6090260c6 100644 --- a/src/modules/xml/mlt-xml.dtd +++ b/src/modules/xml/mlt-xml.dtd @@ -1,6 +1,6 @@ - + producer_map, mlt_properties_get( properties, "id" ), service, 0, NULL, NULL ); From f77f28180326fc214aa6f4a8a0702e6c511ecb73 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 6 Mar 2021 21:35:57 -0600 Subject: [PATCH 055/122] Preserve colorspace in timeremap --- src/modules/core/link_timeremap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/modules/core/link_timeremap.c b/src/modules/core/link_timeremap.c index 571d318f6..eb04b67b2 100644 --- a/src/modules/core/link_timeremap.c +++ b/src/modules/core/link_timeremap.c @@ -204,6 +204,7 @@ static int link_get_image_blend( mlt_frame frame, uint8_t** image, mlt_image_for uint8_t* images[MAX_BLEND_IMAGES]; int image_count = 0; mlt_position in_frame_pos = floor( source_time * source_fps ); + int colorspace = 0; while ( image_count < MAX_BLEND_IMAGES ) { char key[19]; @@ -211,6 +212,7 @@ static int link_get_image_blend( mlt_frame frame, uint8_t** image, mlt_image_for mlt_frame src_frame = (mlt_frame)mlt_properties_get_data( unique_properties, key, NULL ); if ( src_frame && !mlt_frame_get_image( src_frame, &images[image_count], format, width, height, 0 ) ) { + colorspace = mlt_properties_get_int( MLT_FRAME_PROPERTIES(src_frame), "colorspace" ); in_frame_pos++; image_count++; } @@ -246,6 +248,7 @@ static int link_get_image_blend( mlt_frame frame, uint8_t** image, mlt_image_for mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "format", *format ); mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "width", *width ); mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "height", *height ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "colorspace", colorspace ); return 0; } @@ -277,6 +280,7 @@ static int link_get_image_nearest( mlt_frame frame, uint8_t** image, mlt_image_f mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "format", *format ); mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "width", *width ); mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "height", *height ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "colorspace", mlt_properties_get_int( MLT_FRAME_PROPERTIES(src_frame), "colorspace" )); uint8_t* in_alpha = mlt_frame_get_alpha( src_frame ); if ( in_alpha ) From 7968d7680363257db618cd21abba9399abac8397 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 7 Mar 2021 19:34:34 -0600 Subject: [PATCH 056/122] Fix crash on setting speed higher than 23x https://forum.shotcut.org/t/fails-when-speed-of-video-is-set-to-above-x23/25481 --- src/framework/mlt.vers | 1 + src/framework/mlt_audio.c | 63 ++++++++++++++++++++++++ src/framework/mlt_audio.h | 1 + src/modules/avformat/filter_swresample.c | 9 +++- 4 files changed, 72 insertions(+), 2 deletions(-) diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index 6c8648e66..60853d0e8 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -595,4 +595,5 @@ MLT_7.0.0 { mlt_repository_links; mlt_animation_shift_frames; mlt_animation_get_string; + mlt_audio_silence; } MLT_6.22.0; diff --git a/src/framework/mlt_audio.c b/src/framework/mlt_audio.c index 1541977eb..ec1fe41be 100644 --- a/src/framework/mlt_audio.c +++ b/src/framework/mlt_audio.c @@ -208,6 +208,69 @@ void mlt_audio_get_planes( mlt_audio self, uint8_t** planes ) } } +/** Set a range of samples to silence. + * + * \public \memberof mlt_frame_s + * \param self the Audio object + * \param samples the new number of samples to silent + * \param start the sample to begin the silence + * \return none + */ + +void mlt_audio_silence( mlt_audio self, int samples, int start ) +{ + if ( ( start + samples ) > self->samples ) + { + mlt_log_error( NULL, "mlt_audio_silence: avoid buffer overrun\n" ); + return; + } + + switch ( self->format ) + { + case mlt_audio_none: + mlt_log_error( NULL, "mlt_audio_silence: mlt_audio_none\n" ); + return; + // Interleaved 8bit formats + case mlt_audio_u8: + { + int8_t* s = (int8_t*)self->data + ( start * self->channels ); + int size = self->channels * samples * sizeof(int8_t); + memset( s, 127, size ); + return; + } + // Interleaved 16bit formats + case mlt_audio_s16: + { + int16_t* s = (int16_t*)self->data + ( start * self->channels ); + int size = self->channels * samples * sizeof(int16_t); + memset( s, 0, size ); + return; + } + // Interleaved 32bit formats + case mlt_audio_s32le: + case mlt_audio_f32le: + { + int32_t* s = (int32_t*)self->data + ( start * self->channels ); + int size = self->channels * samples * sizeof(int32_t); + memset( s, 0, size ); + return; + } + // Planer 32bit formats + case mlt_audio_s32: + case mlt_audio_float: + { + int p = 0; + for ( p = 0; p < self->channels; p++ ) + { + int32_t* s = (int32_t*)self->data + (p * self->samples) + start; + int size = samples * sizeof(int32_t); + memset( s, 0, size ); + } + return; + } + } +} + /** Shrink the audio to the new number of samples. * * Existing samples will be moved as necessary to ensure that the audio planes diff --git a/src/framework/mlt_audio.h b/src/framework/mlt_audio.h index 3177e119e..7cd72e086 100644 --- a/src/framework/mlt_audio.h +++ b/src/framework/mlt_audio.h @@ -51,6 +51,7 @@ extern int mlt_audio_calculate_size( mlt_audio self ); extern int mlt_audio_plane_count( mlt_audio self ); extern int mlt_audio_plane_size( mlt_audio self ); extern void mlt_audio_get_planes( mlt_audio self, uint8_t** planes ); +extern void mlt_audio_silence( mlt_audio self, int samples, int start ); extern void mlt_audio_shrink( mlt_audio self , int samples ); extern void mlt_audio_reverse( mlt_audio self ); extern void mlt_audio_copy( mlt_audio dst, mlt_audio src, int samples, int src_start, int dst_start ); diff --git a/src/modules/avformat/filter_swresample.c b/src/modules/avformat/filter_swresample.c index 0978695d8..8bb6e33f5 100644 --- a/src/modules/avformat/filter_swresample.c +++ b/src/modules/avformat/filter_swresample.c @@ -206,9 +206,14 @@ static int filter_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *f mlt_audio_get_planes( &out, pdata->out_buffers ); int received_samples = swr_convert( pdata->ctx, pdata->out_buffers, out.samples, (const uint8_t**)pdata->in_buffers, in.samples ); - if( received_samples > 0 ) + if( received_samples >= 0 ) { - if( received_samples < requested_samples ) + if ( received_samples == 0 ) + { + mlt_log_info( MLT_FILTER_SERVICE(filter), "Precharge required - return silence\n" ); + mlt_audio_silence( &out, out.samples, 0 ); + } + else if( received_samples < requested_samples ) { // Duplicate samples to return the exact number requested. mlt_audio_copy( &out, &out, received_samples, 0, requested_samples - received_samples ); From 1f3ec73ac286659f68d2446b6e0ef0d40c3652e9 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Tue, 9 Mar 2021 22:51:41 -0600 Subject: [PATCH 057/122] Fix crash when requesting scaling on yuv420p image The image will not be scaled, but the size will be reported correctly --- src/modules/core/filter_rescale.c | 5 +++++ src/modules/core/filter_resize.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/modules/core/filter_rescale.c b/src/modules/core/filter_rescale.c index 92f512f41..b51e44798 100644 --- a/src/modules/core/filter_rescale.c +++ b/src/modules/core/filter_rescale.c @@ -237,6 +237,11 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *width = owidth; *height = oheight; } + else + { + *width = iwidth; + *height = iheight; + } // Scale the alpha channel only if exists and not correct size int alpha_size = 0; mlt_properties_get_data( properties, "alpha", &alpha_size ); diff --git a/src/modules/core/filter_resize.c b/src/modules/core/filter_resize.c index e926e74ad..fcbdd75d3 100644 --- a/src/modules/core/filter_resize.c +++ b/src/modules/core/filter_resize.c @@ -284,6 +284,11 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format { *image = frame_resize_image( frame, *width, *height, *format ); } + else + { + *width = owidth; + *height = oheight; + } return error; } From b54f13b713f60509930e14451d6daaad43d2d19e Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Wed, 10 Mar 2021 12:49:41 +0100 Subject: [PATCH 058/122] cmake: use PRIVATE everywhere --- src/framework/CMakeLists.txt | 4 ++-- src/melt/CMakeLists.txt | 6 +++--- src/mlt++/CMakeLists.txt | 2 +- src/modules/core/CMakeLists.txt | 2 +- src/modules/decklink/CMakeLists.txt | 2 +- src/modules/frei0r/CMakeLists.txt | 2 +- src/modules/kdenlive/CMakeLists.txt | 2 +- src/modules/motion_est/CMakeLists.txt | 2 +- src/modules/normalize/CMakeLists.txt | 2 +- src/modules/oldfilm/CMakeLists.txt | 2 +- src/modules/opencv/CMakeLists.txt | 2 +- src/modules/opengl/CMakeLists.txt | 4 ++-- src/modules/plus/CMakeLists.txt | 6 +++--- src/modules/plusgpl/CMakeLists.txt | 6 +++--- src/modules/qt/CMakeLists.txt | 6 +++--- src/modules/resample/CMakeLists.txt | 2 +- src/modules/rtaudio/CMakeLists.txt | 14 +++++++------- src/modules/rubberband/CMakeLists.txt | 2 +- src/modules/sdl/CMakeLists.txt | 4 ++-- src/modules/sdl2/CMakeLists.txt | 2 +- src/modules/sox/CMakeLists.txt | 2 +- src/modules/vid.stab/CMakeLists.txt | 2 +- src/modules/vmfx/CMakeLists.txt | 2 +- src/modules/vorbis/CMakeLists.txt | 2 +- src/modules/xine/CMakeLists.txt | 2 +- src/modules/xml/CMakeLists.txt | 2 +- src/swig/csharp/CMakeLists.txt | 2 +- src/swig/java/CMakeLists.txt | 2 +- src/swig/lua/CMakeLists.txt | 2 +- src/swig/nodejs/CMakeLists.txt | 2 +- src/swig/perl/CMakeLists.txt | 2 +- src/swig/php/CMakeLists.txt | 2 +- src/swig/python/CMakeLists.txt | 2 +- src/swig/tcl/CMakeLists.txt | 2 +- 34 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 7753c5676..65bb23090 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -32,7 +32,7 @@ add_library(mlt SHARED mlt_version.c ) -target_link_libraries(mlt m Threads::Threads ${CMAKE_DL_LIBS}) +target_link_libraries(mlt PRIVATE m Threads::Threads ${CMAKE_DL_LIBS}) target_include_directories(mlt PUBLIC $ @@ -50,7 +50,7 @@ if(WIN32) ) endif() target_sources(mlt PRIVATE ../win32/win32.c ../win32/strptime.c) - target_link_libraries(mlt Iconv::Iconv) + target_link_libraries(mlt PRIVATE Iconv::Iconv) if(NOT WINDOWS_DEPLOY) target_compile_definitions(mlt PRIVATE NODEPLOY) endif() diff --git a/src/melt/CMakeLists.txt b/src/melt/CMakeLists.txt index 40f171de3..e26598537 100644 --- a/src/melt/CMakeLists.txt +++ b/src/melt/CMakeLists.txt @@ -1,13 +1,13 @@ add_executable(melt melt.c io.c) -target_link_libraries(melt mlt Threads::Threads) +target_link_libraries(melt PRIVATE mlt Threads::Threads) target_compile_definitions(melt PRIVATE VERSION="${MLT_VERSION}") if(TARGET PkgConfig::sdl2) add_library(sdl2 ALIAS PkgConfig::sdl2) - target_link_libraries(melt sdl2) + target_link_libraries(melt PRIVATE sdl2) target_compile_definitions(melt PRIVATE HAVE_SDL2) if(MINGW) - target_link_libraries(melt mingw32) + target_link_libraries(melt PRIVATE mingw32) endif() endif() diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index 83fd905b6..42881e84d 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -28,7 +28,7 @@ add_library(mlt++ SHARED MltTransition.cpp ) -target_link_libraries(mlt++ mlt) +target_link_libraries(mlt++ PRIVATE mlt) target_include_directories(mlt++ PUBLIC $ diff --git a/src/modules/core/CMakeLists.txt b/src/modules/core/CMakeLists.txt index 4877d1155..284beccee 100644 --- a/src/modules/core/CMakeLists.txt +++ b/src/modules/core/CMakeLists.txt @@ -42,7 +42,7 @@ add_library(mltcore MODULE transition_region.c ) -target_link_libraries(mltcore mlt Threads::Threads) +target_link_libraries(mltcore PRIVATE m mlt Threads::Threads) if(WIN32) target_sources(mltcore PRIVATE ../../win32/fnmatch.c) diff --git a/src/modules/decklink/CMakeLists.txt b/src/modules/decklink/CMakeLists.txt index af23ac05e..065a68c75 100644 --- a/src/modules/decklink/CMakeLists.txt +++ b/src/modules/decklink/CMakeLists.txt @@ -4,7 +4,7 @@ add_library(mltdecklink MODULE producer_decklink.cpp ) -target_link_libraries(mltdecklink mlt Threads::Threads) +target_link_libraries(mltdecklink PRIVATE mlt Threads::Threads) if(WIN32) target_sources(mltdecklink PRIVATE win/DeckLinkAPI_i.cpp) diff --git a/src/modules/frei0r/CMakeLists.txt b/src/modules/frei0r/CMakeLists.txt index ff545e775..78864475b 100644 --- a/src/modules/frei0r/CMakeLists.txt +++ b/src/modules/frei0r/CMakeLists.txt @@ -7,7 +7,7 @@ add_library(mltfrei0r MODULE transition_frei0r.c ) -target_link_libraries(mltfrei0r mlt m ${CMAKE_DL_LIBS}) +target_link_libraries(mltfrei0r PRIVATE mlt m ${CMAKE_DL_LIBS}) set_target_properties(mltfrei0r PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/kdenlive/CMakeLists.txt b/src/modules/kdenlive/CMakeLists.txt index 113ee082b..03fa3fc2c 100644 --- a/src/modules/kdenlive/CMakeLists.txt +++ b/src/modules/kdenlive/CMakeLists.txt @@ -6,7 +6,7 @@ add_library(mltkdenlive MODULE producer_framebuffer.c ) -target_link_libraries(mltkdenlive mlt m) +target_link_libraries(mltkdenlive PRIVATE mlt m) set_target_properties(mltkdenlive PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/motion_est/CMakeLists.txt b/src/modules/motion_est/CMakeLists.txt index 66ab03195..380da47af 100644 --- a/src/modules/motion_est/CMakeLists.txt +++ b/src/modules/motion_est/CMakeLists.txt @@ -8,7 +8,7 @@ add_library(mltmotion_est MODULE producer_slowmotion.c ) -target_link_libraries(mltmotion_est mlt m) +target_link_libraries(mltmotion_est PRIVATE mlt m) set_target_properties(mltmotion_est PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/normalize/CMakeLists.txt b/src/modules/normalize/CMakeLists.txt index b44640f0e..8132c5f2e 100644 --- a/src/modules/normalize/CMakeLists.txt +++ b/src/modules/normalize/CMakeLists.txt @@ -4,7 +4,7 @@ add_library(mltnormalize MODULE filter_volume.c ) -target_link_libraries(mltnormalize mlt m) +target_link_libraries(mltnormalize PRIVATE mlt m) set_target_properties(mltnormalize PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/oldfilm/CMakeLists.txt b/src/modules/oldfilm/CMakeLists.txt index f434bc731..3ef42f32a 100644 --- a/src/modules/oldfilm/CMakeLists.txt +++ b/src/modules/oldfilm/CMakeLists.txt @@ -8,7 +8,7 @@ add_library(mltoldfilm MODULE filter_vignette.c ) -target_link_libraries(mltoldfilm mlt m) +target_link_libraries(mltoldfilm PRIVATE mlt m) set_target_properties(mltoldfilm PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/opencv/CMakeLists.txt b/src/modules/opencv/CMakeLists.txt index 7b195a509..dd6f8a501 100644 --- a/src/modules/opencv/CMakeLists.txt +++ b/src/modules/opencv/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(mltopencv MODULE factory.c filter_opencv_tracker.cpp) -target_link_libraries(mltopencv mlt ${OpenCV_LIBS}) +target_link_libraries(mltopencv PRIVATE mlt ${OpenCV_LIBS}) set_target_properties(mltopencv PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/opengl/CMakeLists.txt b/src/modules/opengl/CMakeLists.txt index a2533c79c..980d31e32 100644 --- a/src/modules/opengl/CMakeLists.txt +++ b/src/modules/opengl/CMakeLists.txt @@ -24,10 +24,10 @@ add_library(mltopengl MODULE transition_movit_overlay.cpp ) -target_link_libraries(mltopengl m Threads::Threads mlt mlt++ OpenGL::GL PkgConfig::movit) +target_link_libraries(mltopengl PRIVATE m Threads::Threads mlt mlt++ OpenGL::GL PkgConfig::movit) if(UNIX AND NOT APPLE) - target_link_libraries(mltopengl X11::X11) + target_link_libraries(mltopengl PRIVATE X11::X11) endif() pkg_get_variable(SHADERDIR movit shaderdir) diff --git a/src/modules/plus/CMakeLists.txt b/src/modules/plus/CMakeLists.txt index 4c9eadd40..5af171c54 100644 --- a/src/modules/plus/CMakeLists.txt +++ b/src/modules/plus/CMakeLists.txt @@ -22,17 +22,17 @@ add_library(mltplus MODULE transition_affine.c ) -target_link_libraries(mltplus mlt m Threads::Threads) +target_link_libraries(mltplus PRIVATE mlt m Threads::Threads) if(TARGET PkgConfig::FFTW) target_sources(mltplus PRIVATE filter_dance.c filter_fft.c) - target_link_libraries(mltplus PkgConfig::FFTW) + target_link_libraries(mltplus PRIVATE PkgConfig::FFTW) target_compile_definitions(mltplus PRIVATE USE_FFTW) install(FILES filter_dance.yml filter_fft.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/plus) endif() if(TARGET PkgConfig::libebur128) - target_link_libraries(mltplus PkgConfig::libebur128) + target_link_libraries(mltplus PRIVATE PkgConfig::libebur128) else() target_sources(mltplus PRIVATE ebur128/ebur128.c) target_include_directories(mltplus PRIVATE ebur128 ebur128/queue) diff --git a/src/modules/plusgpl/CMakeLists.txt b/src/modules/plusgpl/CMakeLists.txt index fa3fd3111..14e6222d4 100644 --- a/src/modules/plusgpl/CMakeLists.txt +++ b/src/modules/plusgpl/CMakeLists.txt @@ -10,12 +10,12 @@ add_library(mltplusgpl MODULE utils.c ) -target_link_libraries(mltplusgpl mlt m Threads::Threads) +target_link_libraries(mltplusgpl PRIVATE mlt m Threads::Threads) if(WIN32) - target_link_libraries(mltplusgpl ws2_32) + target_link_libraries(mltplusgpl PRIVATE ws2_32) elseif(UNIX) - target_link_libraries(mltplusgpl rt) + target_link_libraries(mltplusgpl PRIVATE rt) endif() set_target_properties(mltplusgpl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/qt/CMakeLists.txt b/src/modules/qt/CMakeLists.txt index a5f46b654..1368d60d9 100644 --- a/src/modules/qt/CMakeLists.txt +++ b/src/modules/qt/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(mltqt MODULE typewriter.cpp ) -target_link_libraries(mltqt +target_link_libraries(mltqt PRIVATE mlt++ mlt m @@ -44,13 +44,13 @@ endif() if(TARGET PkgConfig::FFTW) target_sources(mltqt PRIVATE filter_audiospectrum.cpp filter_lightshow.cpp) - target_link_libraries(mltqt PkgConfig::FFTW) + target_link_libraries(mltqt PRIVATE PkgConfig::FFTW) target_compile_definitions(mltqt PRIVATE USE_FFTW) install(FILES filter_audiospectrum.yml filter_lightshow.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/qt) endif() if(TARGET PkgConfig::libexif) - target_link_libraries(mltqt PkgConfig::libexif) + target_link_libraries(mltqt PRIVATE PkgConfig::libexif) target_compile_definitions(mltqt PRIVATE USE_EXIF) endif() diff --git a/src/modules/resample/CMakeLists.txt b/src/modules/resample/CMakeLists.txt index 7ae0ee9d2..ec6b0e240 100644 --- a/src/modules/resample/CMakeLists.txt +++ b/src/modules/resample/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(mltresample MODULE factory.c filter_resample.c) -target_link_libraries(mltresample mlt PkgConfig::samplerate) +target_link_libraries(mltresample PRIVATE mlt PkgConfig::samplerate) set_target_properties(mltresample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/rtaudio/CMakeLists.txt b/src/modules/rtaudio/CMakeLists.txt index c9b5d2612..95373f3dd 100644 --- a/src/modules/rtaudio/CMakeLists.txt +++ b/src/modules/rtaudio/CMakeLists.txt @@ -1,28 +1,28 @@ add_library(mltrtaudio MODULE consumer_rtaudio.cpp) -target_link_libraries(mltrtaudio mlt Threads::Threads) +target_link_libraries(mltrtaudio PRIVATE mlt Threads::Threads) if(TARGET PkgConfig::rtaudio) - target_link_libraries(mltrtaudio PkgConfig::rtaudio) + target_link_libraries(mltrtaudio PRIVATE PkgConfig::rtaudio) else() target_sources(mltrtaudio PRIVATE RtAudio.cpp) target_include_directories(mltrtaudio PRIVATE .) if(APPLE) - target_link_libraries(mltrtaudio CoreAudio CoreFoundation) + target_link_libraries(mltrtaudio PRIVATE CoreAudio CoreFoundation) target_compile_definitions(mltrtaudio PRIVATE __MACOSX_CORE__) elseif(WIN32) - target_link_libraries(mltrtaudio ole32 dsound winmm ksuser) + target_link_libraries(mltrtaudio PRIVATE ole32 dsound winmm ksuser) target_compile_definitions(mltrtaudio PRIVATE __WINDOWS_DS__ __WINDOWS_WASAPI__) else() if(TARGET PkgConfig::alsa) - target_link_libraries(mltrtaudio PkgConfig::alsa) + target_link_libraries(mltrtaudio PRIVATE PkgConfig::alsa) target_compile_definitions(mltrtaudio PRIVATE __LINUX_ALSA__) endif() if(TARGET PkgConfig::libpulse-simple) - target_link_libraries(mltrtaudio PkgConfig::libpulse-simple) + target_link_libraries(mltrtaudio PRIVATE PkgConfig::libpulse-simple) target_compile_definitions(mltrtaudio PRIVATE __LINUX_PULSE__) endif() if(NOT (TARGET PkgConfig::alsa OR TARGET PkgConfig::libpulse-simple)) - target_link_libraries(mltrtaudio ossaudio) + target_link_libraries(mltrtaudio PRIVATE ossaudio) target_compile_definitions(mltrtaudio PRIVATE __LINUX_OSS__) endif() endif() diff --git a/src/modules/rubberband/CMakeLists.txt b/src/modules/rubberband/CMakeLists.txt index 8902382d1..0b4aeda3b 100644 --- a/src/modules/rubberband/CMakeLists.txt +++ b/src/modules/rubberband/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(mltrubberband MODULE factory.c filter_rbpitch.cpp) -target_link_libraries(mltrubberband mlt PkgConfig::rubberband) +target_link_libraries(mltrubberband PRIVATE mlt PkgConfig::rubberband) set_target_properties(mltrubberband PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/sdl/CMakeLists.txt b/src/modules/sdl/CMakeLists.txt index 4103c954a..a10b98b5c 100644 --- a/src/modules/sdl/CMakeLists.txt +++ b/src/modules/sdl/CMakeLists.txt @@ -6,11 +6,11 @@ add_library(mltsdl MODULE factory.c ) -target_link_libraries(mltsdl mlt m Threads::Threads PkgConfig::sdl) +target_link_libraries(mltsdl PRIVATE mlt m Threads::Threads PkgConfig::sdl) if(TARGET PkgConfig::sdl_image) target_sources(mltsdl PRIVATE producer_sdl_image.c) - target_link_libraries(mltsdl PkgConfig::sdl_image) + target_link_libraries(mltsdl PRIVATE PkgConfig::sdl_image) target_compile_definitions(mltsdl PRIVATE WITH_SDL_IMAGE) install(FILES producer_sdl_image.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/sdl) endif() diff --git a/src/modules/sdl2/CMakeLists.txt b/src/modules/sdl2/CMakeLists.txt index 4912b0c50..440b05a71 100644 --- a/src/modules/sdl2/CMakeLists.txt +++ b/src/modules/sdl2/CMakeLists.txt @@ -5,7 +5,7 @@ add_library(mltsdl2 MODULE factory.c ) -target_link_libraries(mltsdl2 mlt m Threads::Threads sdl2) +target_link_libraries(mltsdl2 PRIVATE mlt m Threads::Threads sdl2) set_target_properties(mltsdl2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/sox/CMakeLists.txt b/src/modules/sox/CMakeLists.txt index 1b122a057..da1a49c93 100644 --- a/src/modules/sox/CMakeLists.txt +++ b/src/modules/sox/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(mltsox MODULE factory.c filter_sox.c) -target_link_libraries(mltsox mlt m PkgConfig::sox) +target_link_libraries(mltsox PRIVATE mlt m PkgConfig::sox) if(${sox_VERSION} GREATER 13) target_compile_definitions(mltsox PRIVATE SOX14) diff --git a/src/modules/vid.stab/CMakeLists.txt b/src/modules/vid.stab/CMakeLists.txt index 90bde8dcc..e94d7a305 100644 --- a/src/modules/vid.stab/CMakeLists.txt +++ b/src/modules/vid.stab/CMakeLists.txt @@ -5,7 +5,7 @@ add_library(mltvidstab MODULE filter_vidstab.cpp ) -target_link_libraries(mltvidstab mlt m mlt++ PkgConfig::vidstab) +target_link_libraries(mltvidstab PRIVATE mlt m mlt++ PkgConfig::vidstab) set_target_properties(mltvidstab PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/vmfx/CMakeLists.txt b/src/modules/vmfx/CMakeLists.txt index 22700641a..9ba8c9909 100644 --- a/src/modules/vmfx/CMakeLists.txt +++ b/src/modules/vmfx/CMakeLists.txt @@ -7,7 +7,7 @@ add_library(mltvmfx MODULE producer_pgm.c ) -target_link_libraries(mltvmfx mlt) +target_link_libraries(mltvmfx PRIVATE mlt) set_target_properties(mltvmfx PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/vorbis/CMakeLists.txt b/src/modules/vorbis/CMakeLists.txt index 1c25c1fb0..ab9a3730d 100644 --- a/src/modules/vorbis/CMakeLists.txt +++ b/src/modules/vorbis/CMakeLists.txt @@ -1,5 +1,5 @@ add_library(mltvorbis MODULE factory.c producer_vorbis.c) -target_link_libraries(mltvorbis mlt PkgConfig::vorbis PkgConfig::vorbisfile) +target_link_libraries(mltvorbis PRIVATE mlt PkgConfig::vorbis PkgConfig::vorbisfile) set_target_properties(mltvorbis PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/xine/CMakeLists.txt b/src/modules/xine/CMakeLists.txt index 34f06e528..3ded5a29c 100644 --- a/src/modules/xine/CMakeLists.txt +++ b/src/modules/xine/CMakeLists.txt @@ -5,7 +5,7 @@ add_library(mltxine MODULE filter_deinterlace.c ) -target_link_libraries(mltxine mlt) +target_link_libraries(mltxine PRIVATE mlt) set_target_properties(mltxine PROPERTIES POSITION_INDEPENDENT_CODE ON) diff --git a/src/modules/xml/CMakeLists.txt b/src/modules/xml/CMakeLists.txt index 6540fa740..6720f60e1 100644 --- a/src/modules/xml/CMakeLists.txt +++ b/src/modules/xml/CMakeLists.txt @@ -5,7 +5,7 @@ add_library(mltxml MODULE producer_xml.c ) -target_link_libraries(mltxml mlt Threads::Threads PkgConfig::xml) +target_link_libraries(mltxml PRIVATE mlt Threads::Threads PkgConfig::xml) set_target_properties(mltxml PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/swig/csharp/CMakeLists.txt b/src/swig/csharp/CMakeLists.txt index 2016e8aa6..e3b00420e 100644 --- a/src/swig/csharp/CMakeLists.txt +++ b/src/swig/csharp/CMakeLists.txt @@ -1,7 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltsharp LANGUAGE csharp OUTPUT_DIR src_swig SOURCES ../mlt.i) -target_link_libraries(mltsharp mlt mlt++) +target_link_libraries(mltsharp PRIVATE mlt mlt++) add_custom_command(TARGET mltsharp POST_BUILD COMMAND mcs -out:mlt-sharp.dll -target:library src_swig/*.cs diff --git a/src/swig/java/CMakeLists.txt b/src/swig/java/CMakeLists.txt index 226f59739..9d26850b0 100644 --- a/src/swig/java/CMakeLists.txt +++ b/src/swig/java/CMakeLists.txt @@ -1,7 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltjava LANGUAGE java OUTPUT_DIR src_swig SOURCES ../mlt.i) -target_link_libraries(mltjava mlt mlt++) +target_link_libraries(mltjava PRIVATE mlt mlt++) target_include_directories(mltjava PRIVATE ${JNI_INCLUDE_DIRS}) set_target_properties(mltjava PROPERTIES OUTPUT_NAME "mlt_java") diff --git a/src/swig/lua/CMakeLists.txt b/src/swig/lua/CMakeLists.txt index 2b9470695..7148c91ca 100644 --- a/src/swig/lua/CMakeLists.txt +++ b/src/swig/lua/CMakeLists.txt @@ -1,6 +1,6 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltlua LANGUAGE lua SOURCES ../mlt.i) -target_link_libraries(mltlua mlt mlt++) +target_link_libraries(mltlua PRIVATE mlt mlt++) target_include_directories(mltlua PRIVATE ${LUA_INCLUDE_DIR}) set_target_properties(mltlua PROPERTIES OUTPUT_NAME "mlt") diff --git a/src/swig/nodejs/CMakeLists.txt b/src/swig/nodejs/CMakeLists.txt index f5e8c1616..05c894709 100644 --- a/src/swig/nodejs/CMakeLists.txt +++ b/src/swig/nodejs/CMakeLists.txt @@ -1,7 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltnodejs LANGUAGE javascript SOURCES ../mlt.i) -target_link_libraries(mltnodejs mlt mlt++) +target_link_libraries(mltnodejs PRIVATE mlt mlt++) target_include_directories(mltnodejs PRIVATE ${NODEJS_INCLUDE_DIRS}) set_target_properties(mltnodejs PROPERTIES diff --git a/src/swig/perl/CMakeLists.txt b/src/swig/perl/CMakeLists.txt index 8d007ac15..19532be4f 100644 --- a/src/swig/perl/CMakeLists.txt +++ b/src/swig/perl/CMakeLists.txt @@ -1,7 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltperl LANGUAGE perl SOURCES ../mlt.i) -target_link_libraries(mltperl mlt mlt++) +target_link_libraries(mltperl PRIVATE mlt mlt++) target_include_directories(mltperl PRIVATE ${PERL_INCLUDE_PATH}) set_target_properties(mltperl PROPERTIES OUTPUT_NAME "mlt") diff --git a/src/swig/php/CMakeLists.txt b/src/swig/php/CMakeLists.txt index 6d89987e6..7925befec 100644 --- a/src/swig/php/CMakeLists.txt +++ b/src/swig/php/CMakeLists.txt @@ -1,7 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltphp LANGUAGE php SOURCES ../mlt.i) -target_link_libraries(mltphp mlt mlt++ PHP::Extension) +target_link_libraries(mltphp PRIVATE mlt mlt++ PHP::Extension) set_target_properties(mltphp PROPERTIES OUTPUT_NAME "mlt") if(PHP_EXTENSION_DIR) diff --git a/src/swig/python/CMakeLists.txt b/src/swig/python/CMakeLists.txt index 25a120a66..75410d0d8 100644 --- a/src/swig/python/CMakeLists.txt +++ b/src/swig/python/CMakeLists.txt @@ -1,7 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltpython LANGUAGE python SOURCES ../mlt.i) -target_link_libraries(mltpython mlt mlt++ Python3::Module) +target_link_libraries(mltpython PRIVATE mlt mlt++ Python3::Module) set_target_properties(mltpython PROPERTIES PREFIX "_" OUTPUT_NAME "mlt") string(REGEX MATCH "[lL]ib.*" PYTHON_MODULE_INSTALL_DIR ${Python3_SITELIB}) diff --git a/src/swig/tcl/CMakeLists.txt b/src/swig/tcl/CMakeLists.txt index bd280efa3..eea6102c1 100644 --- a/src/swig/tcl/CMakeLists.txt +++ b/src/swig/tcl/CMakeLists.txt @@ -1,6 +1,6 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mlttcl LANGUAGE tcl SOURCES ../mlt.i) -target_link_libraries(mlttcl mlt mlt++) +target_link_libraries(mlttcl PRIVATE mlt mlt++) target_include_directories(mlttcl PRIVATE ${TCL_INCLUDE_PATH}) set_target_properties(mlttcl PROPERTIES OUTPUT_NAME "mlt") From 43b8ea8e2da632ac63d8401908756a59332d84f0 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Wed, 10 Mar 2021 12:49:41 +0100 Subject: [PATCH 059/122] cmake: use target_compile_options() --- CMakeLists.txt | 4 ++-- src/framework/CMakeLists.txt | 2 ++ src/melt/CMakeLists.txt | 4 ++++ src/mlt++/CMakeLists.txt | 2 ++ src/modules/avformat/CMakeLists.txt | 2 ++ src/modules/core/CMakeLists.txt | 2 ++ src/modules/decklink/CMakeLists.txt | 1 + src/modules/frei0r/CMakeLists.txt | 2 ++ src/modules/gdk/CMakeLists.txt | 2 ++ src/modules/jackrack/CMakeLists.txt | 3 +++ src/modules/kdenlive/CMakeLists.txt | 2 ++ src/modules/motion_est/CMakeLists.txt | 2 ++ src/modules/ndi/CMakeLists.txt | 2 ++ src/modules/normalize/CMakeLists.txt | 2 ++ src/modules/oldfilm/CMakeLists.txt | 2 ++ src/modules/opencv/CMakeLists.txt | 3 +++ src/modules/opengl/CMakeLists.txt | 2 ++ src/modules/plus/CMakeLists.txt | 2 ++ src/modules/plusgpl/CMakeLists.txt | 2 ++ src/modules/qt/CMakeLists.txt | 2 ++ src/modules/resample/CMakeLists.txt | 3 +++ src/modules/rtaudio/CMakeLists.txt | 3 +++ src/modules/rubberband/CMakeLists.txt | 3 +++ src/modules/sdl/CMakeLists.txt | 2 ++ src/modules/sdl2/CMakeLists.txt | 2 ++ src/modules/sox/CMakeLists.txt | 3 +++ src/modules/vid.stab/CMakeLists.txt | 2 ++ src/modules/vmfx/CMakeLists.txt | 2 ++ src/modules/vorbis/CMakeLists.txt | 3 +++ src/modules/xine/CMakeLists.txt | 2 ++ src/modules/xml/CMakeLists.txt | 2 ++ src/swig/csharp/CMakeLists.txt | 1 + src/swig/java/CMakeLists.txt | 1 + src/swig/lua/CMakeLists.txt | 1 + src/swig/nodejs/CMakeLists.txt | 1 + src/swig/perl/CMakeLists.txt | 1 + src/swig/php/CMakeLists.txt | 1 + src/swig/python/CMakeLists.txt | 1 + src/swig/ruby/CMakeLists.txt | 1 + src/swig/tcl/CMakeLists.txt | 1 + src/tests/CMakeLists.txt | 1 + 41 files changed, 80 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f89e7cbae..647a5ee81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,9 +102,9 @@ if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64)") endif() if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") - add_compile_options(-ffast-math) + set(MLT_COMPILE_OPTIONS "$<$:-ffast-math>") elseif(MSVC) - add_compile_options(/fp:fast) + set(MLT_COMPILE_OPTIONS "$<$:/fp:fast>") endif() find_package(Threads REQUIRED) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 65bb23090..8a33f05fe 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -32,6 +32,8 @@ add_library(mlt SHARED mlt_version.c ) +target_compile_options(mlt PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mlt PRIVATE m Threads::Threads ${CMAKE_DL_LIBS}) target_include_directories(mlt PUBLIC diff --git a/src/melt/CMakeLists.txt b/src/melt/CMakeLists.txt index e26598537..5d2c44839 100644 --- a/src/melt/CMakeLists.txt +++ b/src/melt/CMakeLists.txt @@ -1,5 +1,9 @@ add_executable(melt melt.c io.c) + +target_compile_options(melt PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(melt PRIVATE mlt Threads::Threads) + target_compile_definitions(melt PRIVATE VERSION="${MLT_VERSION}") if(TARGET PkgConfig::sdl2) diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index 42881e84d..2903efdba 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -28,6 +28,8 @@ add_library(mlt++ SHARED MltTransition.cpp ) +target_compile_options(mlt++ PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mlt++ PRIVATE mlt) target_include_directories(mlt++ PUBLIC diff --git a/src/modules/avformat/CMakeLists.txt b/src/modules/avformat/CMakeLists.txt index 426a086c0..d8c6c49f7 100644 --- a/src/modules/avformat/CMakeLists.txt +++ b/src/modules/avformat/CMakeLists.txt @@ -6,6 +6,8 @@ add_library(mltavformat MODULE filter_swscale.c ) +target_compile_options(mltavformat PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltavformat PRIVATE mlt m diff --git a/src/modules/core/CMakeLists.txt b/src/modules/core/CMakeLists.txt index 284beccee..3ad7434c6 100644 --- a/src/modules/core/CMakeLists.txt +++ b/src/modules/core/CMakeLists.txt @@ -42,6 +42,8 @@ add_library(mltcore MODULE transition_region.c ) +target_compile_options(mltcore PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltcore PRIVATE m mlt Threads::Threads) if(WIN32) diff --git a/src/modules/decklink/CMakeLists.txt b/src/modules/decklink/CMakeLists.txt index 065a68c75..8263ea05c 100644 --- a/src/modules/decklink/CMakeLists.txt +++ b/src/modules/decklink/CMakeLists.txt @@ -3,6 +3,7 @@ add_library(mltdecklink MODULE consumer_decklink.cpp producer_decklink.cpp ) +target_compile_options(mltdecklink PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltdecklink PRIVATE mlt Threads::Threads) diff --git a/src/modules/frei0r/CMakeLists.txt b/src/modules/frei0r/CMakeLists.txt index 78864475b..ef9cd449b 100644 --- a/src/modules/frei0r/CMakeLists.txt +++ b/src/modules/frei0r/CMakeLists.txt @@ -7,6 +7,8 @@ add_library(mltfrei0r MODULE transition_frei0r.c ) +target_compile_options(mltfrei0r PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltfrei0r PRIVATE mlt m ${CMAKE_DL_LIBS}) set_target_properties(mltfrei0r PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/gdk/CMakeLists.txt b/src/modules/gdk/CMakeLists.txt index dbbe60113..83f7ccce5 100644 --- a/src/modules/gdk/CMakeLists.txt +++ b/src/modules/gdk/CMakeLists.txt @@ -5,6 +5,8 @@ add_library(mltgdk MODULE producer_pixbuf.c ) +target_compile_options(mltgdk PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltgdk PRIVATE mlt m Threads::Threads PkgConfig::GdkPixbuf) target_compile_definitions(mltgdk PRIVATE USE_PIXBUF) diff --git a/src/modules/jackrack/CMakeLists.txt b/src/modules/jackrack/CMakeLists.txt index a09649994..f9e5967bb 100644 --- a/src/modules/jackrack/CMakeLists.txt +++ b/src/modules/jackrack/CMakeLists.txt @@ -1,4 +1,7 @@ add_library(mltjack MODULE consumer_jack.c factory.c) + +target_compile_options(mltjack PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltjack PRIVATE mlt Threads::Threads PkgConfig::jack) if(GPL AND TARGET PkgConfig::xml AND TARGET PkgConfig::glib AND ladspa_h_FOUND) diff --git a/src/modules/kdenlive/CMakeLists.txt b/src/modules/kdenlive/CMakeLists.txt index 03fa3fc2c..fad3a089c 100644 --- a/src/modules/kdenlive/CMakeLists.txt +++ b/src/modules/kdenlive/CMakeLists.txt @@ -6,6 +6,8 @@ add_library(mltkdenlive MODULE producer_framebuffer.c ) +target_compile_options(mltkdenlive PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltkdenlive PRIVATE mlt m) set_target_properties(mltkdenlive PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/motion_est/CMakeLists.txt b/src/modules/motion_est/CMakeLists.txt index 380da47af..935996fee 100644 --- a/src/modules/motion_est/CMakeLists.txt +++ b/src/modules/motion_est/CMakeLists.txt @@ -8,6 +8,8 @@ add_library(mltmotion_est MODULE producer_slowmotion.c ) +target_compile_options(mltmotion_est PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltmotion_est PRIVATE mlt m) set_target_properties(mltmotion_est PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/ndi/CMakeLists.txt b/src/modules/ndi/CMakeLists.txt index bcc1dd86a..b336abe42 100644 --- a/src/modules/ndi/CMakeLists.txt +++ b/src/modules/ndi/CMakeLists.txt @@ -4,6 +4,8 @@ add_library(mltndi MODULE producer_ndi.c ) +target_compile_options(mltndi PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltndi PRIVATE mlt NDI::NDI) set_target_properties(mltndi PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/normalize/CMakeLists.txt b/src/modules/normalize/CMakeLists.txt index 8132c5f2e..6882a113b 100644 --- a/src/modules/normalize/CMakeLists.txt +++ b/src/modules/normalize/CMakeLists.txt @@ -4,6 +4,8 @@ add_library(mltnormalize MODULE filter_volume.c ) +target_compile_options(mltnormalize PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltnormalize PRIVATE mlt m) set_target_properties(mltnormalize PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/oldfilm/CMakeLists.txt b/src/modules/oldfilm/CMakeLists.txt index 3ef42f32a..8b766a4bc 100644 --- a/src/modules/oldfilm/CMakeLists.txt +++ b/src/modules/oldfilm/CMakeLists.txt @@ -8,6 +8,8 @@ add_library(mltoldfilm MODULE filter_vignette.c ) +target_compile_options(mltoldfilm PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltoldfilm PRIVATE mlt m) set_target_properties(mltoldfilm PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/opencv/CMakeLists.txt b/src/modules/opencv/CMakeLists.txt index dd6f8a501..832b5150d 100644 --- a/src/modules/opencv/CMakeLists.txt +++ b/src/modules/opencv/CMakeLists.txt @@ -1,4 +1,7 @@ add_library(mltopencv MODULE factory.c filter_opencv_tracker.cpp) + +target_compile_options(mltopencv PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltopencv PRIVATE mlt ${OpenCV_LIBS}) set_target_properties(mltopencv PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/opengl/CMakeLists.txt b/src/modules/opengl/CMakeLists.txt index 980d31e32..e3b95c0ce 100644 --- a/src/modules/opengl/CMakeLists.txt +++ b/src/modules/opengl/CMakeLists.txt @@ -24,6 +24,8 @@ add_library(mltopengl MODULE transition_movit_overlay.cpp ) +target_compile_options(mltopengl PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltopengl PRIVATE m Threads::Threads mlt mlt++ OpenGL::GL PkgConfig::movit) if(UNIX AND NOT APPLE) diff --git a/src/modules/plus/CMakeLists.txt b/src/modules/plus/CMakeLists.txt index 5af171c54..7e6211589 100644 --- a/src/modules/plus/CMakeLists.txt +++ b/src/modules/plus/CMakeLists.txt @@ -22,6 +22,8 @@ add_library(mltplus MODULE transition_affine.c ) +target_compile_options(mltplus PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltplus PRIVATE mlt m Threads::Threads) if(TARGET PkgConfig::FFTW) diff --git a/src/modules/plusgpl/CMakeLists.txt b/src/modules/plusgpl/CMakeLists.txt index 14e6222d4..cfde502af 100644 --- a/src/modules/plusgpl/CMakeLists.txt +++ b/src/modules/plusgpl/CMakeLists.txt @@ -10,6 +10,8 @@ add_library(mltplusgpl MODULE utils.c ) +target_compile_options(mltplusgpl PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltplusgpl PRIVATE mlt m Threads::Threads) if(WIN32) diff --git a/src/modules/qt/CMakeLists.txt b/src/modules/qt/CMakeLists.txt index 1368d60d9..499bc0825 100644 --- a/src/modules/qt/CMakeLists.txt +++ b/src/modules/qt/CMakeLists.txt @@ -18,6 +18,8 @@ add_library(mltqt MODULE typewriter.cpp ) +target_compile_options(mltqt PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltqt PRIVATE mlt++ mlt diff --git a/src/modules/resample/CMakeLists.txt b/src/modules/resample/CMakeLists.txt index ec6b0e240..861f12737 100644 --- a/src/modules/resample/CMakeLists.txt +++ b/src/modules/resample/CMakeLists.txt @@ -1,4 +1,7 @@ add_library(mltresample MODULE factory.c filter_resample.c) + +target_compile_options(mltresample PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltresample PRIVATE mlt PkgConfig::samplerate) set_target_properties(mltresample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/rtaudio/CMakeLists.txt b/src/modules/rtaudio/CMakeLists.txt index 95373f3dd..951a22667 100644 --- a/src/modules/rtaudio/CMakeLists.txt +++ b/src/modules/rtaudio/CMakeLists.txt @@ -1,4 +1,7 @@ add_library(mltrtaudio MODULE consumer_rtaudio.cpp) + +target_compile_options(mltrtaudio PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltrtaudio PRIVATE mlt Threads::Threads) if(TARGET PkgConfig::rtaudio) diff --git a/src/modules/rubberband/CMakeLists.txt b/src/modules/rubberband/CMakeLists.txt index 0b4aeda3b..dd5f33b27 100644 --- a/src/modules/rubberband/CMakeLists.txt +++ b/src/modules/rubberband/CMakeLists.txt @@ -1,4 +1,7 @@ add_library(mltrubberband MODULE factory.c filter_rbpitch.cpp) + +target_compile_options(mltrubberband PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltrubberband PRIVATE mlt PkgConfig::rubberband) set_target_properties(mltrubberband PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/sdl/CMakeLists.txt b/src/modules/sdl/CMakeLists.txt index a10b98b5c..5b75b8c96 100644 --- a/src/modules/sdl/CMakeLists.txt +++ b/src/modules/sdl/CMakeLists.txt @@ -6,6 +6,8 @@ add_library(mltsdl MODULE factory.c ) +target_compile_options(mltsdl PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltsdl PRIVATE mlt m Threads::Threads PkgConfig::sdl) if(TARGET PkgConfig::sdl_image) diff --git a/src/modules/sdl2/CMakeLists.txt b/src/modules/sdl2/CMakeLists.txt index 440b05a71..0c1a9a0d5 100644 --- a/src/modules/sdl2/CMakeLists.txt +++ b/src/modules/sdl2/CMakeLists.txt @@ -5,6 +5,8 @@ add_library(mltsdl2 MODULE factory.c ) +target_compile_options(mltsdl2 PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltsdl2 PRIVATE mlt m Threads::Threads sdl2) set_target_properties(mltsdl2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/sox/CMakeLists.txt b/src/modules/sox/CMakeLists.txt index da1a49c93..a51fc579f 100644 --- a/src/modules/sox/CMakeLists.txt +++ b/src/modules/sox/CMakeLists.txt @@ -1,4 +1,7 @@ add_library(mltsox MODULE factory.c filter_sox.c) + +target_compile_options(mltsox PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltsox PRIVATE mlt m PkgConfig::sox) if(${sox_VERSION} GREATER 13) diff --git a/src/modules/vid.stab/CMakeLists.txt b/src/modules/vid.stab/CMakeLists.txt index e94d7a305..744f5c4b7 100644 --- a/src/modules/vid.stab/CMakeLists.txt +++ b/src/modules/vid.stab/CMakeLists.txt @@ -5,6 +5,8 @@ add_library(mltvidstab MODULE filter_vidstab.cpp ) +target_compile_options(mltvidstab PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltvidstab PRIVATE mlt m mlt++ PkgConfig::vidstab) set_target_properties(mltvidstab PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/vmfx/CMakeLists.txt b/src/modules/vmfx/CMakeLists.txt index 9ba8c9909..08d5859e5 100644 --- a/src/modules/vmfx/CMakeLists.txt +++ b/src/modules/vmfx/CMakeLists.txt @@ -7,6 +7,8 @@ add_library(mltvmfx MODULE producer_pgm.c ) +target_compile_options(mltvmfx PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltvmfx PRIVATE mlt) set_target_properties(mltvmfx PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/vorbis/CMakeLists.txt b/src/modules/vorbis/CMakeLists.txt index ab9a3730d..881765e0c 100644 --- a/src/modules/vorbis/CMakeLists.txt +++ b/src/modules/vorbis/CMakeLists.txt @@ -1,4 +1,7 @@ add_library(mltvorbis MODULE factory.c producer_vorbis.c) + +target_compile_options(mltvorbis PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltvorbis PRIVATE mlt PkgConfig::vorbis PkgConfig::vorbisfile) set_target_properties(mltvorbis PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/xine/CMakeLists.txt b/src/modules/xine/CMakeLists.txt index 3ded5a29c..84b02f30e 100644 --- a/src/modules/xine/CMakeLists.txt +++ b/src/modules/xine/CMakeLists.txt @@ -5,6 +5,8 @@ add_library(mltxine MODULE filter_deinterlace.c ) +target_compile_options(mltxine PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltxine PRIVATE mlt) set_target_properties(mltxine PROPERTIES POSITION_INDEPENDENT_CODE ON) diff --git a/src/modules/xml/CMakeLists.txt b/src/modules/xml/CMakeLists.txt index 6720f60e1..e0a3a62ec 100644 --- a/src/modules/xml/CMakeLists.txt +++ b/src/modules/xml/CMakeLists.txt @@ -5,6 +5,8 @@ add_library(mltxml MODULE producer_xml.c ) +target_compile_options(mltxml PRIVATE ${MLT_COMPILE_OPTIONS}) + target_link_libraries(mltxml PRIVATE mlt Threads::Threads PkgConfig::xml) set_target_properties(mltxml PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/swig/csharp/CMakeLists.txt b/src/swig/csharp/CMakeLists.txt index e3b00420e..b927e0b19 100644 --- a/src/swig/csharp/CMakeLists.txt +++ b/src/swig/csharp/CMakeLists.txt @@ -1,6 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltsharp LANGUAGE csharp OUTPUT_DIR src_swig SOURCES ../mlt.i) +target_compile_options(mltsharp PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltsharp PRIVATE mlt mlt++) add_custom_command(TARGET mltsharp POST_BUILD diff --git a/src/swig/java/CMakeLists.txt b/src/swig/java/CMakeLists.txt index 9d26850b0..ef6efb36f 100644 --- a/src/swig/java/CMakeLists.txt +++ b/src/swig/java/CMakeLists.txt @@ -1,6 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltjava LANGUAGE java OUTPUT_DIR src_swig SOURCES ../mlt.i) +target_compile_options(mltjava PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltjava PRIVATE mlt mlt++) target_include_directories(mltjava PRIVATE ${JNI_INCLUDE_DIRS}) set_target_properties(mltjava PROPERTIES OUTPUT_NAME "mlt_java") diff --git a/src/swig/lua/CMakeLists.txt b/src/swig/lua/CMakeLists.txt index 7148c91ca..e2e3372ed 100644 --- a/src/swig/lua/CMakeLists.txt +++ b/src/swig/lua/CMakeLists.txt @@ -1,6 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltlua LANGUAGE lua SOURCES ../mlt.i) +target_compile_options(mltlua PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltlua PRIVATE mlt mlt++) target_include_directories(mltlua PRIVATE ${LUA_INCLUDE_DIR}) set_target_properties(mltlua PROPERTIES OUTPUT_NAME "mlt") diff --git a/src/swig/nodejs/CMakeLists.txt b/src/swig/nodejs/CMakeLists.txt index 05c894709..9ae1a2395 100644 --- a/src/swig/nodejs/CMakeLists.txt +++ b/src/swig/nodejs/CMakeLists.txt @@ -1,6 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltnodejs LANGUAGE javascript SOURCES ../mlt.i) +target_compile_options(mltnodejs PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltnodejs PRIVATE mlt mlt++) target_include_directories(mltnodejs PRIVATE ${NODEJS_INCLUDE_DIRS}) diff --git a/src/swig/perl/CMakeLists.txt b/src/swig/perl/CMakeLists.txt index 19532be4f..6ac2672a2 100644 --- a/src/swig/perl/CMakeLists.txt +++ b/src/swig/perl/CMakeLists.txt @@ -1,6 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltperl LANGUAGE perl SOURCES ../mlt.i) +target_compile_options(mltperl PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltperl PRIVATE mlt mlt++) target_include_directories(mltperl PRIVATE ${PERL_INCLUDE_PATH}) set_target_properties(mltperl PROPERTIES OUTPUT_NAME "mlt") diff --git a/src/swig/php/CMakeLists.txt b/src/swig/php/CMakeLists.txt index 7925befec..8005022f3 100644 --- a/src/swig/php/CMakeLists.txt +++ b/src/swig/php/CMakeLists.txt @@ -1,6 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltphp LANGUAGE php SOURCES ../mlt.i) +target_compile_options(mltphp PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltphp PRIVATE mlt mlt++ PHP::Extension) set_target_properties(mltphp PROPERTIES OUTPUT_NAME "mlt") diff --git a/src/swig/python/CMakeLists.txt b/src/swig/python/CMakeLists.txt index 75410d0d8..8c336e705 100644 --- a/src/swig/python/CMakeLists.txt +++ b/src/swig/python/CMakeLists.txt @@ -1,6 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltpython LANGUAGE python SOURCES ../mlt.i) +target_compile_options(mltpython PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltpython PRIVATE mlt mlt++ Python3::Module) set_target_properties(mltpython PROPERTIES PREFIX "_" OUTPUT_NAME "mlt") diff --git a/src/swig/ruby/CMakeLists.txt b/src/swig/ruby/CMakeLists.txt index 1cbcb25a2..ddfdd6b28 100644 --- a/src/swig/ruby/CMakeLists.txt +++ b/src/swig/ruby/CMakeLists.txt @@ -1,6 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mltruby LANGUAGE ruby SOURCES ../mlt.i) +target_compile_options(mltruby PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltruby PRIVATE mlt++) target_include_directories(mltruby PRIVATE ${RUBY_INCLUDE_DIRS}) set_target_properties(mltruby PROPERTIES OUTPUT_NAME "mlt") diff --git a/src/swig/tcl/CMakeLists.txt b/src/swig/tcl/CMakeLists.txt index eea6102c1..0b1abc604 100644 --- a/src/swig/tcl/CMakeLists.txt +++ b/src/swig/tcl/CMakeLists.txt @@ -1,6 +1,7 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES ON CPLUSPLUS ON) swig_add_library(mlttcl LANGUAGE tcl SOURCES ../mlt.i) +target_compile_options(mlttcl PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mlttcl PRIVATE mlt mlt++) target_include_directories(mlttcl PRIVATE ${TCL_INCLUDE_PATH}) set_target_properties(mlttcl PROPERTIES OUTPUT_NAME "mlt") diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 39a99d798..26fec3566 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -2,6 +2,7 @@ set(CMAKE_AUTOMOC ON) foreach(QT_TEST_NAME animation audio events filter frame image playlist properties repository service tractor) add_executable(test_${QT_TEST_NAME} test_${QT_TEST_NAME}/test_${QT_TEST_NAME}.cpp) + target_compile_options(test_${QT_TEST_NAME} PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(test_${QT_TEST_NAME} PRIVATE Qt5::Core Qt5::Test mlt++) add_test(NAME "QtTest:${QT_TEST_NAME}" COMMAND test_${QT_TEST_NAME}) if(NOT WIN32) From 3ae868db78d7ac198ee153f366fbf5e60a449373 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Wed, 10 Mar 2021 12:49:41 +0100 Subject: [PATCH 060/122] cmake: clean up arch specific settings --- CMakeLists.txt | 30 ++++++++++++++++++--------- src/mlt++/CMakeLists.txt | 2 +- src/modules/avformat/CMakeLists.txt | 4 ++++ src/modules/core/CMakeLists.txt | 7 ++++++- src/modules/decklink/CMakeLists.txt | 4 ++++ src/modules/gdk/CMakeLists.txt | 10 +++++++-- src/modules/motion_est/CMakeLists.txt | 4 ++++ src/modules/ndi/CMakeLists.txt | 4 ++++ src/modules/xine/CMakeLists.txt | 21 +++++++++++++++++-- 9 files changed, 70 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 647a5ee81..3dd0221ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -91,20 +91,30 @@ set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_EXTENSIONS OFF) -if(CMAKE_SYSTEM_PROCESSOR MATCHES "(x86_64)|(AMD64)") - if(${ARCH} MATCHES "i686") - else() - set(X86_64 ON) - if(NOT MSVC) - add_compile_definitions(USE_MMX USE_SSE USE_SSE2 ARCH_X86_64) +list(APPEND MLT_COMPILE_OPTIONS "") + +# MSVC cl doesn't support GNU inline assembly (but MSVC-compatible clang-cl does) +if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") + if(CMAKE_SYSTEM_PROCESSOR MATCHES "i686|x86|x86_64|AMD64") + set(CPU_MMX ON) + set(CPU_SSE ON) + set(CPU_SSE2 ON) + if(NOT MSVC) # also NOT clang-cl + list(APPEND MLT_COMPILE_OPTIONS "-mmmx;-msse;-msse2") endif() endif() + if(CMAKE_SYSTEM_PROCESSOR MATCHES "i686" OR (WIN32 AND CMAKE_SYSTEM_PROCESSOR MATCHES "x86")) + set(CPU_X86_32 ON) + endif() + if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64") + set(CPU_X86_64 ON) + endif() endif() -if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") - set(MLT_COMPILE_OPTIONS "$<$:-ffast-math>") -elseif(MSVC) - set(MLT_COMPILE_OPTIONS "$<$:/fp:fast>") +if(MSVC) + list(APPEND MLT_COMPILE_OPTIONS "$<$:/fp:fast>") +elseif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") + list(APPEND MLT_COMPILE_OPTIONS "$<$:-ffast-math>") endif() find_package(Threads REQUIRED) diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index 2903efdba..3ee918ede 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -30,7 +30,7 @@ add_library(mlt++ SHARED target_compile_options(mlt++ PRIVATE ${MLT_COMPILE_OPTIONS}) -target_link_libraries(mlt++ PRIVATE mlt) +target_link_libraries(mlt++ PUBLIC mlt) target_include_directories(mlt++ PUBLIC $ diff --git a/src/modules/avformat/CMakeLists.txt b/src/modules/avformat/CMakeLists.txt index d8c6c49f7..ad02940b7 100644 --- a/src/modules/avformat/CMakeLists.txt +++ b/src/modules/avformat/CMakeLists.txt @@ -46,6 +46,10 @@ if(TARGET PkgConfig::libswresample) target_compile_definitions(mltavformat PRIVATE SWRESAMPLE) endif() +if(CPU_MMX) + target_compile_definitions(mltavformat PRIVATE USE_MMX) +endif() + set_target_properties(mltavformat PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltavformat LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/core/CMakeLists.txt b/src/modules/core/CMakeLists.txt index 3ad7434c6..5ebc19d49 100644 --- a/src/modules/core/CMakeLists.txt +++ b/src/modules/core/CMakeLists.txt @@ -51,8 +51,13 @@ if(WIN32) target_include_directories(mltcore PRIVATE ../../win32) endif() -if(X86_64) +if(CPU_SSE) + target_compile_definitions(mltcore PRIVATE USE_SSE) +endif() + +if(CPU_X86_64) target_sources(mltcore PRIVATE composite_line_yuv_sse2_simple.c) + target_compile_definitions(mltcore PRIVATE ARCH_X86_64) endif() set_target_properties(mltcore PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/decklink/CMakeLists.txt b/src/modules/decklink/CMakeLists.txt index 8263ea05c..0cfd5abb7 100644 --- a/src/modules/decklink/CMakeLists.txt +++ b/src/modules/decklink/CMakeLists.txt @@ -18,6 +18,10 @@ else() target_include_directories(mltdecklink PRIVATE linux) endif() +if(CPU_SSE) + target_compile_definitions(mltdecklink PRIVATE USE_SSE) +endif() + set_target_properties(mltdecklink PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltdecklink LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/gdk/CMakeLists.txt b/src/modules/gdk/CMakeLists.txt index 83f7ccce5..bc5f97bc0 100644 --- a/src/modules/gdk/CMakeLists.txt +++ b/src/modules/gdk/CMakeLists.txt @@ -23,8 +23,14 @@ if(TARGET PkgConfig::pango AND TARGET PkgConfig::fontconfig) install(FILES producer_pango.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/gdk) endif() -# Only for MMX but not x86_64: deprecated -# target_sources(mltgdk PRIVATE have_mmx.S scale_line_22_yuv_mmx.S) +if(CPU_MMX) + target_sources(mltgdk PRIVATE have_mmx.S scale_line_22_yuv_mmx.S) + target_compile_definitions(mltgdk PRIVATE USE_MMX) +endif() + +if(CPU_X86_64) + target_compile_definitions(mltgdk PRIVATE ARCH_X86_64) +endif() set_target_properties(mltgdk PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") diff --git a/src/modules/motion_est/CMakeLists.txt b/src/modules/motion_est/CMakeLists.txt index 935996fee..f56b3fa50 100644 --- a/src/modules/motion_est/CMakeLists.txt +++ b/src/modules/motion_est/CMakeLists.txt @@ -12,6 +12,10 @@ target_compile_options(mltmotion_est PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltmotion_est PRIVATE mlt m) +if(CPU_SSE) + target_compile_definitions(mltmotion_est PRIVATE USE_SSE) +endif() + set_target_properties(mltmotion_est PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltmotion_est LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/ndi/CMakeLists.txt b/src/modules/ndi/CMakeLists.txt index b336abe42..9263b8147 100644 --- a/src/modules/ndi/CMakeLists.txt +++ b/src/modules/ndi/CMakeLists.txt @@ -8,6 +8,10 @@ target_compile_options(mltndi PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltndi PRIVATE mlt NDI::NDI) +if(CPU_SSE) + target_compile_definitions(mltndi PRIVATE USE_SSE) +endif() + set_target_properties(mltndi PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltndi LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) diff --git a/src/modules/xine/CMakeLists.txt b/src/modules/xine/CMakeLists.txt index 84b02f30e..5d399df27 100644 --- a/src/modules/xine/CMakeLists.txt +++ b/src/modules/xine/CMakeLists.txt @@ -13,14 +13,31 @@ set_target_properties(mltxine PROPERTIES POSITION_INDEPENDENT_CODE ON) target_compile_definitions(mltxine PRIVATE PIC) -if(X86_64) +if(CPU_MMX) + target_compile_definitions(mltxine PRIVATE USE_MMX) target_sources(mltxine PRIVATE cpu_accel.c) - if("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + if(CMAKE_C_COMPILER_ID MATCHES "GNU") # avoid crash in yadif filter_line_sse2 target_compile_options(mltxine PRIVATE -fno-tree-dominator-opts -fno-tree-pre) endif() endif() +if(CPU_SSE) + target_compile_definitions(mltxine PRIVATE USE_SSE) +endif() + +if(CPU_SSE2) + target_compile_definitions(mltxine PRIVATE USE_SSE2) +endif() + +if(CPU_X86_32) + target_compile_definitions(mltxine PRIVATE ARCH_X86) +endif() + +if(CPU_X86_64) + target_compile_definitions(mltxine PRIVATE ARCH_X86_64) +endif() + set_target_properties(mltxine PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltxine LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) From d56f8e4567d132107fd9007802192ae07c607689 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Wed, 10 Mar 2021 12:49:41 +0100 Subject: [PATCH 061/122] cmake: add major version to files/dirs --- CMakeLists.txt | 14 ++++++++++++-- src/examples/CMakeLists.txt | 2 +- src/framework/CMakeLists.txt | 19 +++++++++++-------- src/framework/mlt-framework.pc.in | 8 ++++---- src/melt/CMakeLists.txt | 9 ++++++++- src/mlt++/CMakeLists.txt | 15 +++++++++------ src/mlt++/mlt++.pc.in | 6 +++--- src/modules/avformat/CMakeLists.txt | 4 ++-- src/modules/core/CMakeLists.txt | 4 ++-- src/modules/decklink/CMakeLists.txt | 4 ++-- src/modules/frei0r/CMakeLists.txt | 4 ++-- src/modules/gdk/CMakeLists.txt | 6 +++--- src/modules/jackrack/CMakeLists.txt | 6 +++--- src/modules/kdenlive/CMakeLists.txt | 4 ++-- src/modules/motion_est/CMakeLists.txt | 4 ++-- src/modules/ndi/CMakeLists.txt | 4 ++-- src/modules/normalize/CMakeLists.txt | 4 ++-- src/modules/oldfilm/CMakeLists.txt | 4 ++-- src/modules/opencv/CMakeLists.txt | 4 ++-- src/modules/opengl/CMakeLists.txt | 4 ++-- src/modules/plus/CMakeLists.txt | 6 +++--- src/modules/plusgpl/CMakeLists.txt | 4 ++-- src/modules/qt/CMakeLists.txt | 8 ++++---- src/modules/resample/CMakeLists.txt | 4 ++-- src/modules/rtaudio/CMakeLists.txt | 4 ++-- src/modules/rubberband/CMakeLists.txt | 4 ++-- src/modules/sdl/CMakeLists.txt | 6 +++--- src/modules/sdl2/CMakeLists.txt | 4 ++-- src/modules/sox/CMakeLists.txt | 4 ++-- src/modules/vid.stab/CMakeLists.txt | 4 ++-- src/modules/vmfx/CMakeLists.txt | 4 ++-- src/modules/vorbis/CMakeLists.txt | 4 ++-- src/modules/xine/CMakeLists.txt | 2 +- src/modules/xml/CMakeLists.txt | 4 ++-- src/swig/python/CMakeLists.txt | 7 +++++-- 35 files changed, 112 insertions(+), 86 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dd0221ee..eb216c10f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,13 @@ else() file(CREATE_LINK "${CMAKE_SOURCE_DIR}/profiles" "${MLT_DATA_OUTPUT_DIRECTORY}/profiles" SYMBOLIC) endif() +set(MLT_INSTALL_MODULE_DIR ${CMAKE_INSTALL_LIBDIR}/mlt) +set(MLT_INSTALL_DATA_DIR ${CMAKE_INSTALL_DATADIR}/mlt) +if(NOT (WIN32 OR APPLE)) + set(MLT_INSTALL_MODULE_DIR ${CMAKE_INSTALL_LIBDIR}/mlt-${MLT_VERSION_MAJOR}) + set(MLT_INSTALL_DATA_DIR ${CMAKE_INSTALL_DATADIR}/mlt-${MLT_VERSION_MAJOR}) +endif() + set(CMAKE_C_STANDARD 11) set(CMAKE_C_STANDARD_REQUIRED ON) set(CMAKE_C_EXTENSIONS ON) @@ -309,10 +316,13 @@ if(BUILD_DOCS) doxygen_add_docs(docs src/framework) endif() -install(DIRECTORY presets profiles DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt) +install(DIRECTORY presets profiles DESTINATION ${MLT_INSTALL_DATA_DIR}) if(UNIX AND NOT APPLE) - install(FILES docs/melt.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + install(FILES docs/melt.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 RENAME melt-${MLT_VERSION_MAJOR}.1) + install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${CMAKE_INSTALL_FULL_MANDIR}/man1/melt-${MLT_VERSION_MAJOR}.1 ${CMAKE_INSTALL_FULL_MANDIR}/man1/melt.1)" + ) endif() add_subdirectory(src) diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt index 4898916fc..fca8b980d 100644 --- a/src/examples/CMakeLists.txt +++ b/src/examples/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.14) project(MLT-examples) find_package(PkgConfig REQUIRED) -pkg_check_modules(mlt++ REQUIRED IMPORTED_TARGET mlt++) +pkg_check_modules(mlt++ REQUIRED IMPORTED_TARGET mlt++-7) add_executable(play play.cpp) target_link_libraries(play PRIVATE PkgConfig::mlt++) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 8a33f05fe..2bcac864b 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -38,13 +38,16 @@ target_link_libraries(mlt PRIVATE m Threads::Threads ${CMAKE_DL_LIBS}) target_include_directories(mlt PUBLIC $ - $ + $ ) -set_target_properties(mlt PROPERTIES SOVERSION ${MLT_VERSION_MAJOR} VERSION ${MLT_VERSION}) +set_target_properties(mlt PROPERTIES + VERSION 1.${MLT_VERSION_MINOR}.${MLT_VERSION_PATCH} + SOVERSION 1 + OUTPUT_NAME mlt-${MLT_VERSION_MAJOR} +) if(WIN32) - set_target_properties(mlt PROPERTIES OUTPUT_NAME "mlt-${MLT_VERSION_MAJOR}") if(MINGW) install(FILES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libmlt-${MLT_VERSION_MAJOR}.dll" DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -61,7 +64,7 @@ endif() if(NOT (WIN32 OR APPLE)) target_compile_definitions(mlt PRIVATE $ - $ + $ ) target_link_options(mlt PRIVATE -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/mlt.vers) set_target_properties(mlt PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mlt.vers) @@ -109,13 +112,13 @@ install(TARGETS mlt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mlt/framework + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mlt-${MLT_VERSION_MAJOR}/framework ) -install(FILES metaschema.yaml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt) +install(FILES metaschema.yaml DESTINATION ${MLT_INSTALL_DATA_DIR}) -configure_file(mlt-framework.pc.in mlt-framework.pc @ONLY) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mlt-framework.pc +configure_file(mlt-framework.pc.in mlt-framework-${MLT_VERSION_MAJOR}.pc @ONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mlt-framework-${MLT_VERSION_MAJOR}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT Development ) diff --git a/src/framework/mlt-framework.pc.in b/src/framework/mlt-framework.pc.in index 9c15bbc81..a15899a7a 100644 --- a/src/framework/mlt-framework.pc.in +++ b/src/framework/mlt-framework.pc.in @@ -4,12 +4,12 @@ libdir=@CMAKE_INSTALL_FULL_LIBDIR@ includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ datadir=@CMAKE_INSTALL_FULL_DATADIR@ -moduledir=${libdir}/mlt -mltdatadir=${datadir}/mlt +moduledir=${libdir}/mlt-@MLT_VERSION_MAJOR@ +mltdatadir=${datadir}/mlt-@MLT_VERSION_MAJOR@ Name: mlt-framework Description: MLT multimedia framework Version: @MLT_VERSION@ Requires: -Libs: -L${libdir} -lmlt -Cflags: -I${includedir} -I${includedir}/mlt +Libs: -L${libdir} -lmlt-@MLT_VERSION_MAJOR@ +Cflags: -I${includedir}/mlt-@MLT_VERSION_MAJOR@ diff --git a/src/melt/CMakeLists.txt b/src/melt/CMakeLists.txt index 5d2c44839..c9106c73a 100644 --- a/src/melt/CMakeLists.txt +++ b/src/melt/CMakeLists.txt @@ -19,4 +19,11 @@ if(MINGW) target_link_options(melt PRIVATE -mconsole) endif() -install(TARGETS melt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +if(WIN32 OR APPLE) + install(TARGETS melt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) +else() + install(PROGRAMS "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/melt" DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME melt-${MLT_VERSION_MAJOR}) + install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${CMAKE_INSTALL_FULL_BINDIR}/melt-${MLT_VERSION_MAJOR} ${CMAKE_INSTALL_FULL_BINDIR}/melt)" + ) +endif() diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index 3ee918ede..0caf69030 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -34,13 +34,16 @@ target_link_libraries(mlt++ PUBLIC mlt) target_include_directories(mlt++ PUBLIC $ - $ + $ ) -set_target_properties(mlt++ PROPERTIES SOVERSION ${MLT_VERSION_MAJOR} VERSION ${MLT_VERSION}) +set_target_properties(mlt++ PROPERTIES + VERSION 1.${MLT_VERSION_MINOR}.${MLT_VERSION_PATCH} + SOVERSION 1 + OUTPUT_NAME mlt++-${MLT_VERSION_MAJOR} +) if(WIN32) - set_target_properties(mlt++ PROPERTIES OUTPUT_NAME "mlt++-${MLT_VERSION_MAJOR}") if(MINGW) install(FILES "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/libmlt++-${MLT_VERSION_MAJOR}.dll" DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -93,11 +96,11 @@ install(TARGETS mlt++ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mlt++ + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mlt-${MLT_VERSION_MAJOR}/mlt++ ) -configure_file(mlt++.pc.in mlt++.pc @ONLY) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mlt++.pc +configure_file(mlt++.pc.in mlt++-${MLT_VERSION_MAJOR}.pc @ONLY) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mlt++-${MLT_VERSION_MAJOR}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT Development ) diff --git a/src/mlt++/mlt++.pc.in b/src/mlt++/mlt++.pc.in index 3719cd83a..ef7a870b2 100644 --- a/src/mlt++/mlt++.pc.in +++ b/src/mlt++/mlt++.pc.in @@ -7,6 +7,6 @@ datadir=@CMAKE_INSTALL_FULL_DATADIR@ Name: mlt++ Description: C++ API for MLT multimedia framework Version: @MLT_VERSION@ -Requires: mlt-framework -Libs: -L${libdir} -lmlt++ -Cflags: -I${includedir} -I${includedir}/mlt++ +Requires: mlt-framework-@MLT_VERSION_MAJOR@ +Libs: -L${libdir} -lmlt++-@MLT_VERSION_MAJOR@ +Cflags: -I${includedir}/mlt-@MLT_VERSION_MAJOR@/mlt++ diff --git a/src/modules/avformat/CMakeLists.txt b/src/modules/avformat/CMakeLists.txt index ad02940b7..146702e46 100644 --- a/src/modules/avformat/CMakeLists.txt +++ b/src/modules/avformat/CMakeLists.txt @@ -52,7 +52,7 @@ endif() set_target_properties(mltavformat PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltavformat LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltavformat LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES consumer_avformat.yml @@ -60,5 +60,5 @@ install(FILES resolution_scale.yml blacklist.txt yuv_only.txt - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/avformat + DESTINATION ${MLT_INSTALL_DATA_DIR}/avformat ) diff --git a/src/modules/core/CMakeLists.txt b/src/modules/core/CMakeLists.txt index 5ebc19d49..fe95104be 100644 --- a/src/modules/core/CMakeLists.txt +++ b/src/modules/core/CMakeLists.txt @@ -62,7 +62,7 @@ endif() set_target_properties(mltcore PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltcore LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltcore LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES consumer_multi.yml @@ -104,5 +104,5 @@ install(FILES transition_region.yml loader.dict loader.ini - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/core + DESTINATION ${MLT_INSTALL_DATA_DIR}/core ) diff --git a/src/modules/decklink/CMakeLists.txt b/src/modules/decklink/CMakeLists.txt index 0cfd5abb7..8c6a74166 100644 --- a/src/modules/decklink/CMakeLists.txt +++ b/src/modules/decklink/CMakeLists.txt @@ -24,10 +24,10 @@ endif() set_target_properties(mltdecklink PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltdecklink LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltdecklink LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES consumer_decklink.yml producer_decklink.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/decklink + DESTINATION ${MLT_INSTALL_DATA_DIR}/decklink ) diff --git a/src/modules/frei0r/CMakeLists.txt b/src/modules/frei0r/CMakeLists.txt index ef9cd449b..352b6a7e3 100644 --- a/src/modules/frei0r/CMakeLists.txt +++ b/src/modules/frei0r/CMakeLists.txt @@ -13,12 +13,12 @@ target_link_libraries(mltfrei0r PRIVATE mlt m ${CMAKE_DL_LIBS}) set_target_properties(mltfrei0r PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltfrei0r LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltfrei0r LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES filter_cairoblend_mode.yml resolution_scale.yml param_name_map.yaml blacklist.txt not_thread_safe.txt - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/frei0r + DESTINATION ${MLT_INSTALL_DATA_DIR}/frei0r ) diff --git a/src/modules/gdk/CMakeLists.txt b/src/modules/gdk/CMakeLists.txt index bc5f97bc0..debff9aaf 100644 --- a/src/modules/gdk/CMakeLists.txt +++ b/src/modules/gdk/CMakeLists.txt @@ -20,7 +20,7 @@ if(TARGET PkgConfig::pango AND TARGET PkgConfig::fontconfig) target_sources(mltgdk PRIVATE producer_pango.c) target_link_libraries(mltgdk PRIVATE PkgConfig::pango PkgConfig::fontconfig PkgConfig::pangoft2) target_compile_definitions(mltgdk PRIVATE USE_PANGO) - install(FILES producer_pango.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/gdk) + install(FILES producer_pango.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/gdk) endif() if(CPU_MMX) @@ -34,6 +34,6 @@ endif() set_target_properties(mltgdk PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltgdk LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltgdk LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) -install(FILES filter_rescale.yml producer_pixbuf.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/gdk) +install(FILES filter_rescale.yml producer_pixbuf.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/gdk) diff --git a/src/modules/jackrack/CMakeLists.txt b/src/modules/jackrack/CMakeLists.txt index f9e5967bb..ddc78d8cf 100644 --- a/src/modules/jackrack/CMakeLists.txt +++ b/src/modules/jackrack/CMakeLists.txt @@ -24,12 +24,12 @@ if(GPL AND TARGET PkgConfig::xml AND TARGET PkgConfig::glib AND ladspa_h_FOUND) filter_jack.yml filter_ladspa.yml producer_ladspa.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/jackrack + DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack ) endif() set_target_properties(mltjack PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltjack LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltjack LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) -install(FILES consumer_jack.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/jackrack) +install(FILES consumer_jack.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) diff --git a/src/modules/kdenlive/CMakeLists.txt b/src/modules/kdenlive/CMakeLists.txt index fad3a089c..0d8e8630d 100644 --- a/src/modules/kdenlive/CMakeLists.txt +++ b/src/modules/kdenlive/CMakeLists.txt @@ -12,12 +12,12 @@ target_link_libraries(mltkdenlive PRIVATE mlt m) set_target_properties(mltkdenlive PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltkdenlive LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltkdenlive LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES filter_boxblur.yml filter_freeze.yml filter_wave.yml producer_framebuffer.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/kdenlive + DESTINATION ${MLT_INSTALL_DATA_DIR}/kdenlive ) diff --git a/src/modules/motion_est/CMakeLists.txt b/src/modules/motion_est/CMakeLists.txt index f56b3fa50..3e3ca65fe 100644 --- a/src/modules/motion_est/CMakeLists.txt +++ b/src/modules/motion_est/CMakeLists.txt @@ -18,12 +18,12 @@ endif() set_target_properties(mltmotion_est PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltmotion_est LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltmotion_est LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES filter_autotrack_rectangle.yml filter_motion_est.yml filter_vismv.yml producer_slowmotion.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/motion_est + DESTINATION ${MLT_INSTALL_DATA_DIR}/motion_est ) diff --git a/src/modules/ndi/CMakeLists.txt b/src/modules/ndi/CMakeLists.txt index 9263b8147..94835fd74 100644 --- a/src/modules/ndi/CMakeLists.txt +++ b/src/modules/ndi/CMakeLists.txt @@ -14,5 +14,5 @@ endif() set_target_properties(mltndi PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltndi LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) -install(FILES consumer_ndi.yml producer_ndi.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/ndi) +install(TARGETS mltndi LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) +install(FILES consumer_ndi.yml producer_ndi.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/ndi) diff --git a/src/modules/normalize/CMakeLists.txt b/src/modules/normalize/CMakeLists.txt index 6882a113b..55b0b8a74 100644 --- a/src/modules/normalize/CMakeLists.txt +++ b/src/modules/normalize/CMakeLists.txt @@ -10,10 +10,10 @@ target_link_libraries(mltnormalize PRIVATE mlt m) set_target_properties(mltnormalize PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltnormalize LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltnormalize LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES filter_audiolevel.yml filter_volume.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/normalize + DESTINATION ${MLT_INSTALL_DATA_DIR}/normalize ) diff --git a/src/modules/oldfilm/CMakeLists.txt b/src/modules/oldfilm/CMakeLists.txt index 8b766a4bc..d74def2f6 100644 --- a/src/modules/oldfilm/CMakeLists.txt +++ b/src/modules/oldfilm/CMakeLists.txt @@ -14,7 +14,7 @@ target_link_libraries(mltoldfilm PRIVATE mlt m) set_target_properties(mltoldfilm PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltoldfilm LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltoldfilm LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES filter_dust.yml @@ -34,5 +34,5 @@ install(FILES oldfilm.svg tcolor.svg vignette.svg - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/oldfilm + DESTINATION ${MLT_INSTALL_DATA_DIR}/oldfilm ) diff --git a/src/modules/opencv/CMakeLists.txt b/src/modules/opencv/CMakeLists.txt index 832b5150d..b9e9b3a25 100644 --- a/src/modules/opencv/CMakeLists.txt +++ b/src/modules/opencv/CMakeLists.txt @@ -6,5 +6,5 @@ target_link_libraries(mltopencv PRIVATE mlt ${OpenCV_LIBS}) set_target_properties(mltopencv PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltopencv LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) -install(FILES filter_opencv_tracker.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/opencv) +install(TARGETS mltopencv LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) +install(FILES filter_opencv_tracker.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/opencv) diff --git a/src/modules/opengl/CMakeLists.txt b/src/modules/opengl/CMakeLists.txt index e3b95c0ce..4389e0aa4 100644 --- a/src/modules/opengl/CMakeLists.txt +++ b/src/modules/opengl/CMakeLists.txt @@ -37,7 +37,7 @@ target_compile_definitions(mltopengl PRIVATE SHADERDIR="${SHADERDIR}") set_target_properties(mltopengl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltopengl LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltopengl LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES filter_movit_blur.yml @@ -55,5 +55,5 @@ install(FILES transition_movit_luma.yml transition_movit_mix.yml transition_movit_overlay.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/opengl + DESTINATION ${MLT_INSTALL_DATA_DIR}/opengl ) diff --git a/src/modules/plus/CMakeLists.txt b/src/modules/plus/CMakeLists.txt index 7e6211589..b65477735 100644 --- a/src/modules/plus/CMakeLists.txt +++ b/src/modules/plus/CMakeLists.txt @@ -30,7 +30,7 @@ if(TARGET PkgConfig::FFTW) target_sources(mltplus PRIVATE filter_dance.c filter_fft.c) target_link_libraries(mltplus PRIVATE PkgConfig::FFTW) target_compile_definitions(mltplus PRIVATE USE_FFTW) - install(FILES filter_dance.yml filter_fft.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/plus) + install(FILES filter_dance.yml filter_fft.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/plus) endif() if(TARGET PkgConfig::libebur128) @@ -43,7 +43,7 @@ endif() set_target_properties(mltplus PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltplus LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltplus LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES consumer_blipflash.yml @@ -66,5 +66,5 @@ install(FILES producer_blipflash.yml producer_count.yml transition_affine.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/plus + DESTINATION ${MLT_INSTALL_DATA_DIR}/plus ) diff --git a/src/modules/plusgpl/CMakeLists.txt b/src/modules/plusgpl/CMakeLists.txt index cfde502af..0069dfebc 100644 --- a/src/modules/plusgpl/CMakeLists.txt +++ b/src/modules/plusgpl/CMakeLists.txt @@ -22,12 +22,12 @@ endif() set_target_properties(mltplusgpl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltplusgpl LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltplusgpl LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES consumer_cbrts.yml filter_burningtv.yml filter_lumaliftgaingamma.yml filter_rotoscoping.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/plusgpl + DESTINATION ${MLT_INSTALL_DATA_DIR}/plusgpl ) diff --git a/src/modules/qt/CMakeLists.txt b/src/modules/qt/CMakeLists.txt index 499bc0825..75196a6ad 100644 --- a/src/modules/qt/CMakeLists.txt +++ b/src/modules/qt/CMakeLists.txt @@ -41,14 +41,14 @@ endif() if(GPL3) target_sources(mltqt PRIVATE transition_vqm.cpp) target_compile_definitions(mltqt PRIVATE GPL3) - install(FILES transition_vqm.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/qt) + install(FILES transition_vqm.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/qt) endif() if(TARGET PkgConfig::FFTW) target_sources(mltqt PRIVATE filter_audiospectrum.cpp filter_lightshow.cpp) target_link_libraries(mltqt PRIVATE PkgConfig::FFTW) target_compile_definitions(mltqt PRIVATE USE_FFTW) - install(FILES filter_audiospectrum.yml filter_lightshow.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/qt) + install(FILES filter_audiospectrum.yml filter_lightshow.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/qt) endif() if(TARGET PkgConfig::libexif) @@ -58,7 +58,7 @@ endif() set_target_properties(mltqt PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltqt LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltqt LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES filter_audiowaveform.yml @@ -70,5 +70,5 @@ install(FILES producer_qimage.yml producer_qtext.yml transition_qtblend.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/qt + DESTINATION ${MLT_INSTALL_DATA_DIR}/qt ) diff --git a/src/modules/resample/CMakeLists.txt b/src/modules/resample/CMakeLists.txt index 861f12737..3a7d7570f 100644 --- a/src/modules/resample/CMakeLists.txt +++ b/src/modules/resample/CMakeLists.txt @@ -6,6 +6,6 @@ target_link_libraries(mltresample PRIVATE mlt PkgConfig::samplerate) set_target_properties(mltresample PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltresample LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltresample LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) -install(FILES filter_resample.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/resample) +install(FILES filter_resample.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/resample) diff --git a/src/modules/rtaudio/CMakeLists.txt b/src/modules/rtaudio/CMakeLists.txt index 951a22667..3194c9bc9 100644 --- a/src/modules/rtaudio/CMakeLists.txt +++ b/src/modules/rtaudio/CMakeLists.txt @@ -33,6 +33,6 @@ endif() set_target_properties(mltrtaudio PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltrtaudio LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltrtaudio LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) -install(FILES consumer_rtaudio.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/rtaudio) +install(FILES consumer_rtaudio.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/rtaudio) diff --git a/src/modules/rubberband/CMakeLists.txt b/src/modules/rubberband/CMakeLists.txt index dd5f33b27..93264689d 100644 --- a/src/modules/rubberband/CMakeLists.txt +++ b/src/modules/rubberband/CMakeLists.txt @@ -6,6 +6,6 @@ target_link_libraries(mltrubberband PRIVATE mlt PkgConfig::rubberband) set_target_properties(mltrubberband PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltrubberband LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltrubberband LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) -install(FILES filter_rbpitch.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/rubberband) +install(FILES filter_rbpitch.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/rubberband) diff --git a/src/modules/sdl/CMakeLists.txt b/src/modules/sdl/CMakeLists.txt index 5b75b8c96..cf2a2c09e 100644 --- a/src/modules/sdl/CMakeLists.txt +++ b/src/modules/sdl/CMakeLists.txt @@ -14,17 +14,17 @@ if(TARGET PkgConfig::sdl_image) target_sources(mltsdl PRIVATE producer_sdl_image.c) target_link_libraries(mltsdl PRIVATE PkgConfig::sdl_image) target_compile_definitions(mltsdl PRIVATE WITH_SDL_IMAGE) - install(FILES producer_sdl_image.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/sdl) + install(FILES producer_sdl_image.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/sdl) endif() set_target_properties(mltsdl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltsdl LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltsdl LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES consumer_sdl_audio.yml consumer_sdl_preview.yml consumer_sdl_still.yml consumer_sdl.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/sdl + DESTINATION ${MLT_INSTALL_DATA_DIR}/sdl ) diff --git a/src/modules/sdl2/CMakeLists.txt b/src/modules/sdl2/CMakeLists.txt index 0c1a9a0d5..f75bb6721 100644 --- a/src/modules/sdl2/CMakeLists.txt +++ b/src/modules/sdl2/CMakeLists.txt @@ -11,6 +11,6 @@ target_link_libraries(mltsdl2 PRIVATE mlt m Threads::Threads sdl2) set_target_properties(mltsdl2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltsdl2 LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltsdl2 LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) -install(FILES consumer_sdl2_audio.yml consumer_sdl2.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/sdl2) +install(FILES consumer_sdl2_audio.yml consumer_sdl2.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/sdl2) diff --git a/src/modules/sox/CMakeLists.txt b/src/modules/sox/CMakeLists.txt index a51fc579f..6fa3a5ba8 100644 --- a/src/modules/sox/CMakeLists.txt +++ b/src/modules/sox/CMakeLists.txt @@ -10,6 +10,6 @@ endif() set_target_properties(mltsox PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltsox LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltsox LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) -install(FILES filter_sox_effect.yml filter_sox.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/sox) +install(FILES filter_sox_effect.yml filter_sox.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/sox) diff --git a/src/modules/vid.stab/CMakeLists.txt b/src/modules/vid.stab/CMakeLists.txt index 744f5c4b7..434691c61 100644 --- a/src/modules/vid.stab/CMakeLists.txt +++ b/src/modules/vid.stab/CMakeLists.txt @@ -11,6 +11,6 @@ target_link_libraries(mltvidstab PRIVATE mlt m mlt++ PkgConfig::vidstab) set_target_properties(mltvidstab PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltvidstab LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltvidstab LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) -install(FILES filter_deshake.yml filter_vidstab.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/vidstab) +install(FILES filter_deshake.yml filter_vidstab.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/vidstab) diff --git a/src/modules/vmfx/CMakeLists.txt b/src/modules/vmfx/CMakeLists.txt index 08d5859e5..a9e6101dd 100644 --- a/src/modules/vmfx/CMakeLists.txt +++ b/src/modules/vmfx/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(mltvmfx PRIVATE mlt) set_target_properties(mltvmfx PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltvmfx LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltvmfx LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES filter_chroma_hold.yml @@ -21,5 +21,5 @@ install(FILES filter_mono.yml filter_shape.yml producer_pgm.yml - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/vmfx + DESTINATION ${MLT_INSTALL_DATA_DIR}/vmfx ) diff --git a/src/modules/vorbis/CMakeLists.txt b/src/modules/vorbis/CMakeLists.txt index 881765e0c..2c4a459d3 100644 --- a/src/modules/vorbis/CMakeLists.txt +++ b/src/modules/vorbis/CMakeLists.txt @@ -6,6 +6,6 @@ target_link_libraries(mltvorbis PRIVATE mlt PkgConfig::vorbis PkgConfig::vorbisf set_target_properties(mltvorbis PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltvorbis LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltvorbis LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) -install(FILES producer_vorbis.yml DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/vorbis) +install(FILES producer_vorbis.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/vorbis) diff --git a/src/modules/xine/CMakeLists.txt b/src/modules/xine/CMakeLists.txt index 5d399df27..478d68800 100644 --- a/src/modules/xine/CMakeLists.txt +++ b/src/modules/xine/CMakeLists.txt @@ -40,4 +40,4 @@ endif() set_target_properties(mltxine PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltxine LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltxine LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) diff --git a/src/modules/xml/CMakeLists.txt b/src/modules/xml/CMakeLists.txt index e0a3a62ec..96af855cc 100644 --- a/src/modules/xml/CMakeLists.txt +++ b/src/modules/xml/CMakeLists.txt @@ -11,7 +11,7 @@ target_link_libraries(mltxml PRIVATE mlt Threads::Threads PkgConfig::xml) set_target_properties(mltxml PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltxml LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/mlt) +install(TARGETS mltxml LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES consumer_xml.yml @@ -19,5 +19,5 @@ install(FILES producer_xml-string.yml producer_xml.yml mlt-xml.dtd - DESTINATION ${CMAKE_INSTALL_DATADIR}/mlt/xml + DESTINATION ${MLT_INSTALL_DATA_DIR}/xml ) diff --git a/src/swig/python/CMakeLists.txt b/src/swig/python/CMakeLists.txt index 8c336e705..321fa011c 100644 --- a/src/swig/python/CMakeLists.txt +++ b/src/swig/python/CMakeLists.txt @@ -3,9 +3,12 @@ set_source_files_properties(../mlt.i PROPERTIES USE_TARGET_INCLUDE_DIRECTORIES O swig_add_library(mltpython LANGUAGE python SOURCES ../mlt.i) target_compile_options(mltpython PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltpython PRIVATE mlt mlt++ Python3::Module) -set_target_properties(mltpython PROPERTIES PREFIX "_" OUTPUT_NAME "mlt") +set_target_properties(mltpython PROPERTIES PREFIX "_" OUTPUT_NAME "mlt${MLT_VERSION_MAJOR}") string(REGEX MATCH "[lL]ib.*" PYTHON_MODULE_INSTALL_DIR ${Python3_SITELIB}) install(TARGETS mltpython DESTINATION ${PYTHON_MODULE_INSTALL_DIR}) -install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mlt.py DESTINATION ${PYTHON_MODULE_INSTALL_DIR}) +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mlt.py + DESTINATION ${PYTHON_MODULE_INSTALL_DIR} + RENAME mlt${MLT_VERSION_MAJOR}.py +) From 2f5f0b3e72f421caa042033bdcba33c00bcc1e15 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Wed, 10 Mar 2021 12:49:41 +0100 Subject: [PATCH 062/122] cmake: add MltConfig.cmake --- CMakeLists.txt | 200 ++++++++++++++++++++++++++++++----- MltConfig.cmake.in | 12 +++ src/examples/CMakeLists.txt | 13 ++- src/framework/CMakeLists.txt | 3 + src/mlt++/CMakeLists.txt | 5 + src/modules/CMakeLists.txt | 38 +++---- 6 files changed, 222 insertions(+), 49 deletions(-) create mode 100644 MltConfig.cmake.in diff --git a/CMakeLists.txt b/CMakeLists.txt index eb216c10f..751e7cf44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,16 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") list(APPEND MLT_COMPILE_OPTIONS "$<$:-ffast-math>") endif() +if(NOT GPL) + set(MOD_MOTION_EST OFF) + set(MOD_NORMALIZE OFF) + set(MOD_PLUSGPL OFF) + set(MOD_QT OFF) + set(MOD_RUBBERBAND OFF) + set(MOD_VIDSTAB OFF) + set(MOD_XINE OFF) +endif() + find_package(Threads REQUIRED) find_package(PkgConfig REQUIRED) @@ -143,10 +153,6 @@ if(BUILD_TESTING) enable_testing() endif() -if(MOD_QT) - find_package(Qt5 COMPONENTS Core Gui Xml Svg Widgets) -endif() - if(MOD_QT OR MOD_PLUS) pkg_check_modules(FFTW IMPORTED_TARGET fftw3) if(NOT FFTW_FOUND) @@ -170,53 +176,120 @@ if(MOD_AVFORMAT) pkg_check_modules(libavformat IMPORTED_TARGET libavformat) pkg_check_modules(libswscale IMPORTED_TARGET libswscale) pkg_check_modules(libavutil IMPORTED_TARGET libavutil) - pkg_check_modules(libavcodec IMPORTED_TARGET libavcodec) - pkg_check_modules(libavfilter IMPORTED_TARGET libavfilter) - pkg_check_modules(libavdevice IMPORTED_TARGET libavdevice) - pkg_check_modules(libswresample IMPORTED_TARGET libswresample) + if(TARGET PkgConfig::libavformat AND TARGET PkgConfig::libswscale AND TARGET PkgConfig::libavutil) + pkg_check_modules(libavcodec IMPORTED_TARGET libavcodec) + pkg_check_modules(libavfilter IMPORTED_TARGET libavfilter) + pkg_check_modules(libavdevice IMPORTED_TARGET libavdevice) + pkg_check_modules(libswresample IMPORTED_TARGET libswresample) + list(APPEND MLT_SUPPORTED_COMPONENTS avformat) + else() + set(MOD_AVFORMAT OFF) + endif() +endif() + +if(MOD_DECKLINK) + list(APPEND MLT_SUPPORTED_COMPONENTS decklink) endif() if(MOD_FREI0R) pkg_check_modules(FREI0R frei0r) + if(FREI0R_FOUND) + list(APPEND MLT_SUPPORTED_COMPONENTS frei0r) + else() + set(MOD_FREI0R OFF) + endif() endif() if(MOD_GDK) pkg_check_modules(GdkPixbuf IMPORTED_TARGET gdk-pixbuf-2.0) - pkg_check_modules(pango IMPORTED_TARGET pango) - pkg_check_modules(pangoft2 IMPORTED_TARGET pangoft2) + if(TARGET PkgConfig::GdkPixbuf) + pkg_check_modules(pango IMPORTED_TARGET pango) + pkg_check_modules(pangoft2 IMPORTED_TARGET pangoft2) + list(APPEND MLT_SUPPORTED_COMPONENTS gdk) + else() + set(MOD_GDK OFF) + endif() endif() if(MOD_JACKRACK) pkg_check_modules(jack IMPORTED_TARGET jack) - pkg_check_modules(glib IMPORTED_TARGET glib-2.0) - check_include_file(ladspa.h ladspa_h_FOUND) + if(TARGET PkgConfig::jack) + pkg_check_modules(glib IMPORTED_TARGET glib-2.0) + check_include_file(ladspa.h ladspa_h_FOUND) + list(APPEND MLT_SUPPORTED_COMPONENTS jackrack) + else() + set(MOD_JACKRACK OFF) + endif() +endif() + +if(MOD_KDENLIVE) + list(APPEND MLT_SUPPORTED_COMPONENTS kdenlive) +endif() + +if(MOD_MOTION_EST) + list(APPEND MLT_SUPPORTED_COMPONENTS motion_est) endif() if(MOD_NDI) find_package(NDI REQUIRED) + list(APPEND MLT_SUPPORTED_COMPONENTS ndi) +endif() + +if(MOD_NORMALIZE) + list(APPEND MLT_SUPPORTED_COMPONENTS normalize) +endif() + +if(MOD_OLDFILM) + list(APPEND MLT_SUPPORTED_COMPONENTS oldfilm) endif() if(MOD_OPENCV) - find_package(OpenCV QUIET OPTIONAL_COMPONENTS tracking) + find_package(OpenCV REQUIRED COMPONENTS tracking) + if(OpenCV_tracking_FOUND) + list(APPEND MLT_SUPPORTED_COMPONENTS opencv) + else() + set(MOD_OPENCV OFF) + endif() endif() if(MOD_OPENGL) pkg_check_modules(movit IMPORTED_TARGET movit) find_package(OpenGL) - if(UNIX AND NOT APPLE) - find_package(X11) - if(NOT TARGET X11::X11) - set(MOD_OPENGL OFF) + if(TARGET PkgConfig::movit AND TARGET OpenGL::GL) + if(UNIX AND NOT APPLE) + find_package(X11 REQUIRED) endif() + list(APPEND MLT_SUPPORTED_COMPONENTS opengl) + else() + set(MOD_OPENGL OFF) endif() endif() if(MOD_PLUS) pkg_check_modules(libebur128 IMPORTED_TARGET libebur128) + list(APPEND MLT_SUPPORTED_COMPONENTS plus) +endif() + +if(MOD_PLUSGPL) + list(APPEND MLT_SUPPORTED_COMPONENTS plusgpl) +endif() + +if(MOD_QT) + find_package(Qt5 COMPONENTS Core Gui Xml Svg Widgets) + if(Qt5_FOUND) + list(APPEND MLT_SUPPORTED_COMPONENTS qt) + else() + set(MOD_QT OFF) + endif() endif() if(MOD_RESAMPLE) pkg_check_modules(samplerate IMPORTED_TARGET samplerate) + if(TARGET PkgConfig::samplerate) + list(APPEND MLT_SUPPORTED_COMPONENTS resample) + else() + set(MOD_RESAMPLE OFF) + endif() endif() if(MOD_RTAUDIO) @@ -225,46 +298,96 @@ if(MOD_RTAUDIO) pkg_check_modules(alsa IMPORTED_TARGET alsa) pkg_check_modules(libpulse-simple IMPORTED_TARGET libpulse-simple) endif() + list(APPEND MLT_SUPPORTED_COMPONENTS rtaudio) endif() if(MOD_RUBBERBAND) pkg_check_modules(rubberband IMPORTED_TARGET rubberband) + if(TARGET PkgConfig::rubberband) + list(APPEND MLT_SUPPORTED_COMPONENTS rubberband) + else() + set(MOD_RUBBERBAND OFF) + endif() endif() if(MOD_SDL1) pkg_check_modules(sdl IMPORTED_TARGET sdl) - pkg_check_modules(sdl_image IMPORTED_TARGET SDL_image) + if(TARGET PkgConfig::sdl) + pkg_check_modules(sdl_image IMPORTED_TARGET SDL_image) + list(APPEND MLT_SUPPORTED_COMPONENTS sdl) + else() + set(MOD_SDL1 OFF) + endif() +endif() + +if(MOD_SDL2) + if(TARGET sdl2) + list(APPEND MLT_SUPPORTED_COMPONENTS sdl2) + else() + set(MOD_SDL2 OFF) + endif() endif() if(MOD_SOX) pkg_check_modules(sox IMPORTED_TARGET sox) + if(TARGET PkgConfig::sox) + list(APPEND MLT_SUPPORTED_COMPONENTS sox) + else() + set(MOD_SOX OFF) + endif() endif() if(MOD_VIDSTAB) pkg_check_modules(vidstab IMPORTED_TARGET vidstab) + if(TARGET PkgConfig::vidstab) + list(APPEND MLT_SUPPORTED_COMPONENTS vidstab) + else() + set(MOD_VIDSTAB OFF) + endif() +endif() + +if(MOD_VMFX) + list(APPEND MLT_SUPPORTED_COMPONENTS vmfx) endif() if(MOD_VORBIS) pkg_check_modules(vorbis IMPORTED_TARGET vorbis) pkg_check_modules(vorbisfile IMPORTED_TARGET vorbisfile) + if(TARGET PkgConfig::vorbis AND TARGET PkgConfig::vorbisfile) + list(APPEND MLT_SUPPORTED_COMPONENTS vorbis) + else() + set(MOD_VORBIS OFF) + endif() +endif() + +if(MOD_XINE) + list(APPEND MLT_SUPPORTED_COMPONENTS xine) +endif() + +if(MOD_XML) + if(TARGET PkgConfig::xml) + list(APPEND MLT_SUPPORTED_COMPONENTS xml) + else() + set(MOD_XML OFF) + endif() endif() find_package(SWIG) if(SWIG_CSHARP) - find_package(Mono) + find_package(Mono REQUIRED) endif() if(SWIG_JAVA) - find_package(JNI) + find_package(JNI REQUIRED) endif() if(SWIG_LUA) - find_package(Lua) + find_package(Lua REQUIRED) endif() if(SWIG_NODEJS) - find_package(Node) + find_package(Node REQUIRED) if(NODE_VERSION_MAJOR VERSION_GREATER_EQUAL 12 AND SWIG_VERSION VERSION_LESS 4.1) # https://github.com/swig/swig/issues/1520 set(SWIG_NODEJS OFF) @@ -272,23 +395,23 @@ if(SWIG_NODEJS) endif() if(SWIG_PERL) - find_package(PerlLibs) + find_package(PerlLibs REQUIRED) endif() if(SWIG_PHP) - find_package(PHP) + find_package(PHP REQUIRED) endif() if(SWIG_PYTHON) - find_package(Python3 COMPONENTS Interpreter Development) + find_package(Python3 REQUIRED COMPONENTS Interpreter Development) endif() if(SWIG_RUBY) - find_package(Ruby) + find_package(Ruby REQUIRED) endif() if(SWIG_TCL) - find_package(TCL) + find_package(TCL REQUIRED) endif() if(BUILD_DOCS) @@ -326,3 +449,26 @@ if(UNIX AND NOT APPLE) endif() add_subdirectory(src) + +install(EXPORT MltTargets + FILE Mlt${MLT_VERSION_MAJOR}Targets.cmake + NAMESPACE Mlt${MLT_VERSION_MAJOR}:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Mlt${MLT_VERSION_MAJOR} +) + +include(CMakePackageConfigHelpers) +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/MltConfig.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/Mlt${MLT_VERSION_MAJOR}Config.cmake" + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Mlt${MLT_VERSION_MAJOR} + NO_CHECK_REQUIRED_COMPONENTS_MACRO +) +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/Mlt${MLT_VERSION_MAJOR}ConfigVersion.cmake" + COMPATIBILITY SameMajorVersion +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/Mlt${MLT_VERSION_MAJOR}Config.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/Mlt${MLT_VERSION_MAJOR}ConfigVersion.cmake" + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Mlt${MLT_VERSION_MAJOR} +) diff --git a/MltConfig.cmake.in b/MltConfig.cmake.in new file mode 100644 index 000000000..7ac044629 --- /dev/null +++ b/MltConfig.cmake.in @@ -0,0 +1,12 @@ +@PACKAGE_INIT@ + +set(_supported_components "@MLT_SUPPORTED_COMPONENTS@") + +foreach(_comp ${Mlt@MLT_VERSION_MAJOR@_FIND_COMPONENTS}) + if (NOT _comp IN_LIST _supported_components) + set(Mlt@MLT_VERSION_MAJOR@_FOUND False) + set(Mlt@MLT_VERSION_MAJOR@_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}") + endif() +endforeach() + +include("${CMAKE_CURRENT_LIST_DIR}/Mlt@MLT_VERSION_MAJOR@Targets.cmake") diff --git a/src/examples/CMakeLists.txt b/src/examples/CMakeLists.txt index fca8b980d..07e8130cc 100644 --- a/src/examples/CMakeLists.txt +++ b/src/examples/CMakeLists.txt @@ -2,8 +2,15 @@ cmake_minimum_required(VERSION 3.14) project(MLT-examples) -find_package(PkgConfig REQUIRED) -pkg_check_modules(mlt++ REQUIRED IMPORTED_TARGET mlt++-7) +option(WITH_PKGCONFIG "Use pkg-config to find MLT" OFF) add_executable(play play.cpp) -target_link_libraries(play PRIVATE PkgConfig::mlt++) + +if(WITH_PKGCONFIG) + find_package(PkgConfig REQUIRED) + pkg_check_modules(mlt++ REQUIRED IMPORTED_TARGET mlt++-7) + target_link_libraries(play PRIVATE PkgConfig::mlt++) +else() + find_package(Mlt7 REQUIRED COMPONENTS avformat sdl) + target_link_libraries(play PRIVATE Mlt7::mlt++) +endif() diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 2bcac864b..c64877a4f 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -32,6 +32,8 @@ add_library(mlt SHARED mlt_version.c ) +add_library(Mlt${MLT_VERSION_MAJOR}::mlt ALIAS mlt) + target_compile_options(mlt PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mlt PRIVATE m Threads::Threads ${CMAKE_DL_LIBS}) @@ -109,6 +111,7 @@ set(MLT_PUPLIC_HEADERS set_target_properties(mlt PROPERTIES PUBLIC_HEADER "${MLT_PUPLIC_HEADERS}") install(TARGETS mlt + EXPORT MltTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index 0caf69030..e83f284b1 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -28,6 +28,8 @@ add_library(mlt++ SHARED MltTransition.cpp ) +add_library(Mlt${MLT_VERSION_MAJOR}::mlt++ ALIAS mlt++) + target_compile_options(mlt++ PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mlt++ PUBLIC mlt) @@ -93,6 +95,7 @@ set(MLTPP_PUPLIC_HEADERS set_target_properties(mlt++ PROPERTIES PUBLIC_HEADER "${MLTPP_PUPLIC_HEADERS}") install(TARGETS mlt++ + EXPORT MltTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -104,3 +107,5 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mlt++-${MLT_VERSION_MAJOR}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT Development ) + +add_library(MLT7::mlt++ ALIAS mlt++) diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index d1ebe2d03..f81b1db0f 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -1,6 +1,6 @@ add_subdirectory(core) -if(MOD_AVFORMAT AND TARGET PkgConfig::libavformat AND TARGET PkgConfig::libswscale AND TARGET PkgConfig::libavutil) +if(MOD_AVFORMAT) add_subdirectory(avformat) endif() @@ -8,15 +8,15 @@ if(MOD_DECKLINK) add_subdirectory(decklink) endif() -if(MOD_FREI0R AND FREI0R_FOUND) +if(MOD_FREI0R) add_subdirectory(frei0r) endif() -if(MOD_GDK AND TARGET PkgConfig::GdkPixbuf) +if(MOD_GDK) add_subdirectory(gdk) endif() -if(MOD_JACKRACK AND TARGET PkgConfig::jack) +if(MOD_JACKRACK) add_subdirectory(jackrack) endif() @@ -24,7 +24,7 @@ if(MOD_KDENLIVE) add_subdirectory(kdenlive) endif() -if(MOD_MOTION_EST AND GPL) +if(MOD_MOTION_EST) add_subdirectory(motion_est) endif() @@ -32,7 +32,7 @@ if(MOD_NDI) add_subdirectory(ndi) endif() -if(MOD_NORMALIZE AND GPL) +if(MOD_NORMALIZE) add_subdirectory(normalize) endif() @@ -40,11 +40,11 @@ if(MOD_OLDFILM) add_subdirectory(oldfilm) endif() -if(MOD_OPENCV AND OpenCV_tracking_FOUND) +if(MOD_OPENCV) add_subdirectory(opencv) endif() -if(MOD_OPENGL AND TARGET PkgConfig::movit AND TARGET OpenGL::GL) +if(MOD_OPENGL) add_subdirectory(opengl) endif() @@ -52,15 +52,15 @@ if(MOD_PLUS) add_subdirectory(plus) endif() -if(MOD_PLUSGPL AND GPL) +if(MOD_PLUSGPL) add_subdirectory(plusgpl) endif() -if(MOD_QT AND GPL AND Qt5_FOUND) +if(MOD_QT) add_subdirectory(qt) endif() -if(MOD_RESAMPLE AND TARGET PkgConfig::samplerate) +if(MOD_RESAMPLE) add_subdirectory(resample) endif() @@ -68,23 +68,23 @@ if(MOD_RTAUDIO) add_subdirectory(rtaudio) endif() -if(MOD_RUBBERBAND AND GPL AND TARGET PkgConfig::rubberband) +if(MOD_RUBBERBAND) add_subdirectory(rubberband) endif() -if(MOD_SDL1 AND TARGET PkgConfig::sdl) +if(MOD_SDL1) add_subdirectory(sdl) endif() -if(MOD_SDL2 AND TARGET sdl2) +if(MOD_SDL2) add_subdirectory(sdl2) endif() -if(MOD_SOX AND TARGET PkgConfig::sox) +if(MOD_SOX) add_subdirectory(sox) endif() -if(MOD_VIDSTAB AND GPL AND TARGET PkgConfig::vidstab) +if(MOD_VIDSTAB) add_subdirectory(vid.stab) endif() @@ -92,14 +92,14 @@ if(MOD_VMFX) add_subdirectory(vmfx) endif() -if(MOD_VORBIS AND TARGET PkgConfig::vorbis AND TARGET PkgConfig::vorbisfile) +if(MOD_VORBIS) add_subdirectory(vorbis) endif() -if(MOD_XINE AND GPL) +if(MOD_XINE) add_subdirectory(xine) endif() -if(MOD_XML AND TARGET PkgConfig::xml) +if(MOD_XML) add_subdirectory(xml) endif() From a70934ba831e8ac0857a93bbe8e7c510ce503bc3 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Wed, 10 Mar 2021 12:55:33 +0100 Subject: [PATCH 063/122] cmake: move public headers --- src/framework/CMakeLists.txt | 75 ++++++++++++++++++------------------ src/mlt++/CMakeLists.txt | 69 ++++++++++++++++----------------- 2 files changed, 70 insertions(+), 74 deletions(-) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index c64877a4f..4865facfd 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -1,3 +1,39 @@ +set(MLT_PUPLIC_HEADERS + mlt.h + mlt_animation.h + mlt_audio.h + mlt_cache.h + mlt_chain.h + mlt_consumer.h + mlt_deque.h + mlt_events.h + mlt_factory.h + mlt_field.h + mlt_filter.h + mlt_frame.h + mlt_geometry.h + mlt_image.h + mlt_link.h + mlt_log.h + mlt_luma_map.h + mlt_multitrack.h + mlt_parser.h + mlt_playlist.h + mlt_pool.h + mlt_producer.h + mlt_profile.h + mlt_properties.h + mlt_property.h + mlt_repository.h + mlt_service.h + mlt_slices.h + mlt_tokeniser.h + mlt_tractor.h + mlt_transition.h + mlt_types.h + mlt_version.h +) + add_library(mlt SHARED mlt_animation.c mlt_audio.c @@ -47,6 +83,7 @@ set_target_properties(mlt PROPERTIES VERSION 1.${MLT_VERSION_MINOR}.${MLT_VERSION_PATCH} SOVERSION 1 OUTPUT_NAME mlt-${MLT_VERSION_MAJOR} + PUBLIC_HEADER "${MLT_PUPLIC_HEADERS}" ) if(WIN32) @@ -72,44 +109,6 @@ if(NOT (WIN32 OR APPLE)) set_target_properties(mlt PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mlt.vers) endif() -set(MLT_PUPLIC_HEADERS - mlt.h - mlt_animation.h - mlt_audio.h - mlt_cache.h - mlt_chain.h - mlt_consumer.h - mlt_deque.h - mlt_events.h - mlt_factory.h - mlt_field.h - mlt_filter.h - mlt_frame.h - mlt_geometry.h - mlt_image.h - mlt_link.h - mlt_log.h - mlt_luma_map.h - mlt_multitrack.h - mlt_parser.h - mlt_playlist.h - mlt_pool.h - mlt_producer.h - mlt_profile.h - mlt_properties.h - mlt_property.h - mlt_repository.h - mlt_service.h - mlt_slices.h - mlt_tokeniser.h - mlt_tractor.h - mlt_transition.h - mlt_types.h - mlt_version.h -) - -set_target_properties(mlt PROPERTIES PUBLIC_HEADER "${MLT_PUPLIC_HEADERS}") - install(TARGETS mlt EXPORT MltTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index e83f284b1..9a7138538 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -1,3 +1,35 @@ +set(MLTPP_PUPLIC_HEADERS + Mlt.h + MltAnimation.h + MltAudio.h + MltChain.h + MltConfig.h + MltConsumer.h + MltDeque.h + MltEvent.h + MltFactory.h + MltField.h + MltFilter.h + MltFilteredConsumer.h + MltFilteredProducer.h + MltFrame.h + MltGeometry.h + MltImage.h + MltLink.h + MltMultitrack.h + MltParser.h + MltPlaylist.h + MltProducer.h + MltProfile.h + MltProperties.h + MltPushConsumer.h + MltRepository.h + MltService.h + MltTokeniser.h + MltTractor.h + MltTransition.h +) + add_library(mlt++ SHARED MltAnimation.cpp MltAudio.cpp @@ -43,6 +75,7 @@ set_target_properties(mlt++ PROPERTIES VERSION 1.${MLT_VERSION_MINOR}.${MLT_VERSION_PATCH} SOVERSION 1 OUTPUT_NAME mlt++-${MLT_VERSION_MAJOR} + PUBLIC_HEADER "${MLTPP_PUPLIC_HEADERS}" ) if(WIN32) @@ -60,40 +93,6 @@ if(NOT (WIN32 OR APPLE)) set_target_properties(mlt++ PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mlt++.vers) endif() -set(MLTPP_PUPLIC_HEADERS - Mlt.h - MltAnimation.h - MltAudio.h - MltChain.h - MltConfig.h - MltConsumer.h - MltDeque.h - MltEvent.h - MltFactory.h - MltField.h - MltFilter.h - MltFilteredConsumer.h - MltFilteredProducer.h - MltFrame.h - MltGeometry.h - MltImage.h - MltLink.h - MltMultitrack.h - MltParser.h - MltPlaylist.h - MltProducer.h - MltProfile.h - MltProperties.h - MltPushConsumer.h - MltRepository.h - MltService.h - MltTokeniser.h - MltTractor.h - MltTransition.h -) - -set_target_properties(mlt++ PROPERTIES PUBLIC_HEADER "${MLTPP_PUPLIC_HEADERS}") - install(TARGETS mlt++ EXPORT MltTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} @@ -107,5 +106,3 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/mlt++-${MLT_VERSION_MAJOR}.pc DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT Development ) - -add_library(MLT7::mlt++ ALIAS mlt++) From 1d0c3a5cb0b620b99942a36efb3aceac05f9233a Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Wed, 10 Mar 2021 16:00:40 -0800 Subject: [PATCH 064/122] fix mlt_image_format_size() not declared warnings --- src/framework/mlt_frame.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/framework/mlt_frame.h b/src/framework/mlt_frame.h index 90d3af5ba..fee520628 100644 --- a/src/framework/mlt_frame.h +++ b/src/framework/mlt_frame.h @@ -24,6 +24,7 @@ #define MLT_FRAME_H #include "mlt_audio.h" +#include "mlt_image.h" #include "mlt_properties.h" #include "mlt_deque.h" #include "mlt_service.h" From 83e4e6a83d5ac0dc2b817a22e183d39d412ddb40 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Fri, 12 Mar 2021 22:18:21 -0600 Subject: [PATCH 065/122] Fix video does not show after chain creation Make sure all properties are passed from the chain to the source producer when deserializing from XML --- src/modules/xml/producer_xml.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/xml/producer_xml.c b/src/modules/xml/producer_xml.c index 7721c8eb1..15cb147e5 100644 --- a/src/modules/xml/producer_xml.c +++ b/src/modules/xml/producer_xml.c @@ -667,6 +667,8 @@ static void on_end_chain( deserialise_context context, const xmlChar *name ) } if ( !source ) source = mlt_factory_producer( context->profile, NULL, "colour:red" ); + // Propogate properties to the source + mlt_properties_inherit( MLT_PRODUCER_PROPERTIES( source ), properties ); // Add the source producer to the chain mlt_chain_set_source( chain, source ); From 83c24539c1e46b1ec7b2ff6248764431c2345f5a Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 14 Mar 2021 16:46:33 -0500 Subject: [PATCH 066/122] Remove mlt_image_opengl It is the same format as mlt_image_rgb24a --- src/framework/mlt_frame.c | 1 - src/framework/mlt_image.c | 4 ---- src/framework/mlt_types.h | 1 - src/modules/avformat/filter_avcolour_space.c | 5 ++--- src/modules/avformat/filter_avfilter.c | 1 - src/modules/avformat/filter_swscale.c | 2 -- src/modules/avformat/producer_avformat.c | 4 ++-- src/modules/core/filter_imageconvert.c | 7 +++---- src/modules/core/filter_rescale.c | 2 +- src/modules/gdk/filter_rescale.c | 3 +-- src/modules/opengl/filter_movit_convert.cpp | 2 +- src/modules/plusgpl/filter_rotoscoping.c | 2 -- 12 files changed, 10 insertions(+), 24 deletions(-) diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 54698a5a6..2bc351dfe 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -431,7 +431,6 @@ static int generate_test_image( mlt_properties properties, uint8_t **buffer, ml { case mlt_image_rgb24: case mlt_image_rgb24a: - case mlt_image_opengl: case mlt_image_yuv422: case mlt_image_yuv422p16: case mlt_image_yuv420p: diff --git a/src/framework/mlt_image.c b/src/framework/mlt_image.c index 82477643b..0013cd3f8 100644 --- a/src/framework/mlt_image.c +++ b/src/framework/mlt_image.c @@ -176,7 +176,6 @@ int mlt_image_calculate_size( mlt_image self ) { case mlt_image_rgb24: return self->width * self->height * 3; - case mlt_image_opengl: case mlt_image_rgb24a: return self->width * self->height * 4; case mlt_image_yuv422: @@ -209,7 +208,6 @@ const char * mlt_image_format_name( mlt_image_format format ) case mlt_image_rgb24a: return "rgb24a"; case mlt_image_yuv422: return "yuv422"; case mlt_image_yuv420p: return "yuv420p"; - case mlt_image_opengl: return "opengl"; case mlt_image_glsl: return "glsl"; case mlt_image_glsl_texture: return "glsl_texture"; case mlt_image_yuv422p16: return "yuv422p16"; @@ -255,7 +253,6 @@ void mlt_image_fill_black( mlt_image self ) return; case mlt_image_rgb24: case mlt_image_rgb24a: - case mlt_image_opengl: { int size = mlt_image_calculate_size( self ); memset( self->planes[0], 255, size ); @@ -324,7 +321,6 @@ int mlt_image_format_size( mlt_image_format format, int width, int height, int * case mlt_image_rgb24: if ( bpp ) *bpp = 3; return width * height * 3; - case mlt_image_opengl: case mlt_image_rgb24a: if ( bpp ) *bpp = 4; return width * height * 4; diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index 8d28aed5c..3ac907e21 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -49,7 +49,6 @@ typedef enum mlt_image_rgb24a, /**< 8-bit RGB with alpha channel */ mlt_image_yuv422, /**< 8-bit YUV 4:2:2 packed */ mlt_image_yuv420p, /**< 8-bit YUV 4:2:0 planar */ - mlt_image_opengl, /**< (deprecated) suitable for OpenGL texture */ mlt_image_glsl, /**< for opengl module internal use only */ mlt_image_glsl_texture, /**< an OpenGL texture name */ mlt_image_yuv422p16, /**< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian */ diff --git a/src/modules/avformat/filter_avcolour_space.c b/src/modules/avformat/filter_avcolour_space.c index 086afc436..6dc203aaa 100644 --- a/src/modules/avformat/filter_avcolour_space.c +++ b/src/modules/avformat/filter_avcolour_space.c @@ -55,7 +55,6 @@ static int convert_mlt_to_av_cs( mlt_image_format format ) value = AV_PIX_FMT_RGB24; break; case mlt_image_rgb24a: - case mlt_image_opengl: value = AV_PIX_FMT_RGBA; break; case mlt_image_yuv422: @@ -150,7 +149,7 @@ static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *fo uint8_t *output = mlt_pool_alloc( size ); if (out_width == width && out_height == height) { - if ( *format == mlt_image_rgb24a || *format == mlt_image_opengl ) + if ( *format == mlt_image_rgb24a ) { register int len = width * height; uint8_t *alpha = mlt_pool_alloc( len ); @@ -202,7 +201,7 @@ static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *fo mlt_properties_set_int(properties, "height", out_height); if (out_width == width && out_height == height) - if ( output_format == mlt_image_rgb24a || output_format == mlt_image_opengl ) + if ( output_format == mlt_image_rgb24a ) { register int len = width * height; int alpha_size = 0; diff --git a/src/modules/avformat/filter_avfilter.c b/src/modules/avformat/filter_avfilter.c index 354991217..aef4d1e3b 100644 --- a/src/modules/avformat/filter_avfilter.c +++ b/src/modules/avformat/filter_avfilter.c @@ -107,7 +107,6 @@ static mlt_image_format get_supported_image_format( mlt_image_format format ) mlt_log_error(NULL, "[filter_avfilter] Unknown image format requested: %d\n", format ); case mlt_image_none: case mlt_image_yuv422: - case mlt_image_opengl: case mlt_image_glsl: case mlt_image_glsl_texture: return mlt_image_yuv422; diff --git a/src/modules/avformat/filter_swscale.c b/src/modules/avformat/filter_swscale.c index 52c165f9f..8fe7f8795 100644 --- a/src/modules/avformat/filter_swscale.c +++ b/src/modules/avformat/filter_swscale.c @@ -43,7 +43,6 @@ static inline int convert_mlt_to_av_cs( mlt_image_format format ) value = AV_PIX_FMT_RGB24; break; case mlt_image_rgb24a: - case mlt_image_opengl: value = AV_PIX_FMT_RGBA; break; case mlt_image_yuv422: @@ -100,7 +99,6 @@ static int filter_scale( mlt_frame frame, uint8_t **image, mlt_image_format *for case mlt_image_yuv422: case mlt_image_rgb24: case mlt_image_rgb24a: - case mlt_image_opengl: break; default: // XXX: we only know how to rescale packed formats diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index 2ba45cc97..d736da3a6 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -1459,7 +1459,7 @@ static int convert_image( producer_avformat self, AVFrame *frame, uint8_t *buffe || pix_fmt == AV_PIX_FMT_YUVA444P #endif ) && - *format != mlt_image_rgb24a && *format != mlt_image_opengl && + *format != mlt_image_rgb24a && frame->data[3] && frame->linesize[3] ) { int i; @@ -1519,7 +1519,7 @@ static int convert_image( producer_avformat self, AVFrame *frame, uint8_t *buffe out_data, out_stride); sws_freeContext( context ); } - else if ( *format == mlt_image_rgb24a || *format == mlt_image_opengl ) + else if ( *format == mlt_image_rgb24a ) { int flags = mlt_get_sws_flags(width, height, src_pix_fmt, width, height, AV_PIX_FMT_RGBA); struct SwsContext *context = sws_getContext( width, height, src_pix_fmt, diff --git a/src/modules/core/filter_imageconvert.c b/src/modules/core/filter_imageconvert.c index 71a035601..8b78de53a 100644 --- a/src/modules/core/filter_imageconvert.c +++ b/src/modules/core/filter_imageconvert.c @@ -323,10 +323,9 @@ static int convert_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *f int size = width * height * bpp_table[ requested_format - 1 ]; int alpha_size = width * height; uint8_t *image = mlt_pool_alloc( size ); - uint8_t *alpha = ( *format == mlt_image_rgb24a || - *format == mlt_image_opengl ) + uint8_t *alpha = ( *format == mlt_image_rgb24a ) ? mlt_pool_alloc( width * height ) : NULL; - if ( requested_format == mlt_image_rgb24a || requested_format == mlt_image_opengl ) + if ( requested_format == mlt_image_rgb24a ) { if ( alpha ) mlt_pool_release( alpha ); @@ -337,7 +336,7 @@ static int convert_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *f if ( !( error = converter( *buffer, image, alpha, width, height ) ) ) { mlt_frame_set_image( frame, image, size, mlt_pool_release ); - if ( alpha && ( *format == mlt_image_rgb24a || *format == mlt_image_opengl ) ) + if ( alpha && *format == mlt_image_rgb24a ) mlt_frame_set_alpha( frame, alpha, alpha_size, mlt_pool_release ); *buffer = image; *format = requested_format; diff --git a/src/modules/core/filter_rescale.c b/src/modules/core/filter_rescale.c index b51e44798..f0db5b835 100644 --- a/src/modules/core/filter_rescale.c +++ b/src/modules/core/filter_rescale.c @@ -230,7 +230,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // If valid colorspace if ( *format == mlt_image_yuv422 || *format == mlt_image_rgb24 || - *format == mlt_image_rgb24a || *format == mlt_image_opengl ) + *format == mlt_image_rgb24a ) { // Call the virtual function scaler_method( frame, image, format, iwidth, iheight, owidth, oheight ); diff --git a/src/modules/gdk/filter_rescale.c b/src/modules/gdk/filter_rescale.c index 6a907156d..1f3355bd6 100644 --- a/src/modules/gdk/filter_rescale.c +++ b/src/modules/gdk/filter_rescale.c @@ -72,14 +72,13 @@ static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format *form } case mlt_image_rgb24: case mlt_image_rgb24a: - case mlt_image_opengl: { if ( strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) ) { // Create the output image uint8_t *output = mlt_pool_alloc( size ); GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( *image, GDK_COLORSPACE_RGB, - ( *format == mlt_image_rgb24a || *format == mlt_image_opengl ), 8, iwidth, iheight, + ( *format == mlt_image_rgb24a ), 8, iwidth, iheight, iwidth * bpp, NULL, NULL ); GdkPixbuf *scaled = gdk_pixbuf_scale_simple( pixbuf, owidth, oheight, interp ); g_object_unref( pixbuf ); diff --git a/src/modules/opengl/filter_movit_convert.cpp b/src/modules/opengl/filter_movit_convert.cpp index 13ea14449..2b767ae1a 100644 --- a/src/modules/opengl/filter_movit_convert.cpp +++ b/src/modules/opengl/filter_movit_convert.cpp @@ -476,7 +476,7 @@ static MltInput* create_input( mlt_properties properties, mlt_image_format forma } MltInput* input = new MltInput( format ); - if ( format == mlt_image_rgb24a || format == mlt_image_opengl ) { + if ( format == mlt_image_rgb24a ) { // TODO: Get the color space if available. input->useFlatInput( FORMAT_RGBA_POSTMULTIPLIED_ALPHA, width, height ); } diff --git a/src/modules/plusgpl/filter_rotoscoping.c b/src/modules/plusgpl/filter_rotoscoping.c index 436287d6c..fe05eb2ed 100644 --- a/src/modules/plusgpl/filter_rotoscoping.c +++ b/src/modules/plusgpl/filter_rotoscoping.c @@ -399,7 +399,6 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format { case mlt_image_rgb24: case mlt_image_rgb24a: - case mlt_image_opengl: while ( p != q ) { p[0] = p[1] = p[2] = map[i++]; @@ -426,7 +425,6 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format switch ( *format ) { case mlt_image_rgb24a: - case mlt_image_opengl: switch ( mlt_properties_get_int( unique, "alpha_operation" ) ) { case ALPHA_CLEAR: From d9bd6890fd00c943df304836e3ec83c362bc906f Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Sun, 14 Mar 2021 16:53:17 -0700 Subject: [PATCH 067/122] mlt_event_data (#662) * mlt_events: remove mlt_transmitter and stop using variable args * add mlt_event_data and friends to wrap raw pointers * fix C++ Mlt::EventData and SWIG PlaylistNextListener * fix broken unit test for Mlt::Event * let mlt_event_data be allocated on the stack * fix unit test * fix Mlt::EventData::to_object() * update ruby swig binding for EventData change * add doxygen comments for event data functions * more doxygen comments * fix white space * pass event data by value --- src/framework/mlt.vers | 9 + src/framework/mlt_chain.c | 8 +- src/framework/mlt_consumer.c | 132 ++++------- src/framework/mlt_consumer.h | 9 +- src/framework/mlt_events.c | 225 ++++++++++++++----- src/framework/mlt_events.h | 56 +++-- src/framework/mlt_factory.c | 93 ++++---- src/framework/mlt_factory.h | 38 +++- src/framework/mlt_field.c | 6 +- src/framework/mlt_playlist.c | 28 +-- src/framework/mlt_playlist.h | 2 +- src/framework/mlt_producer.c | 14 +- src/framework/mlt_properties.c | 37 +-- src/framework/mlt_properties.h | 3 + src/framework/mlt_service.c | 40 +--- src/framework/mlt_service.h | 2 +- src/framework/mlt_types.h | 1 + src/melt/melt.c | 45 ++-- src/mlt++/MltEvent.cpp | 50 ++++- src/mlt++/MltEvent.h | 24 +- src/mlt++/MltProperties.cpp | 16 +- src/mlt++/MltProperties.h | 6 +- src/mlt++/mlt++.vers | 12 + src/modules/avformat/consumer_avformat.c | 48 ++-- src/modules/avformat/filter_avfilter.c | 8 +- src/modules/core/consumer_multi.c | 6 +- src/modules/core/consumer_null.c | 4 +- src/modules/core/producer_consumer.c | 9 +- src/modules/core/producer_timewarp.c | 11 +- src/modules/decklink/consumer_decklink.cpp | 7 +- src/modules/decklink/producer_decklink.cpp | 5 +- src/modules/gdk/producer_pango.c | 2 +- src/modules/gdk/producer_pango.yml | 2 +- src/modules/gdk/producer_pixbuf.c | 7 +- src/modules/jackrack/consumer_jack.c | 12 +- src/modules/jackrack/filter_jackrack.c | 39 +--- src/modules/ndi/consumer_ndi.c | 2 +- src/modules/opencv/filter_opencv_tracker.cpp | 6 +- src/modules/opengl/consumer_xgl.c | 4 +- src/modules/opengl/filter_glsl_manager.cpp | 8 +- src/modules/opengl/filter_glsl_manager.h | 4 +- src/modules/plus/consumer_blipflash.c | 2 +- src/modules/plus/filter_dynamic_loudness.c | 5 +- src/modules/plus/filter_loudness_meter.c | 7 +- src/modules/plus/filter_text.c | 6 +- src/modules/plusgpl/consumer_cbrts.c | 13 +- src/modules/plusgpl/filter_rotoscoping.c | 5 +- src/modules/qt/consumer_qglsl.cpp | 23 +- src/modules/qt/filter_audiowaveform.cpp | 8 +- src/modules/qt/producer_qimage.c | 6 +- src/modules/qt/qimage_wrapper.cpp | 1 + src/modules/qt/qimage_wrapper.h | 1 + src/modules/rtaudio/consumer_rtaudio.cpp | 14 +- src/modules/sdl/consumer_sdl.c | 16 +- src/modules/sdl/consumer_sdl_audio.c | 11 +- src/modules/sdl/consumer_sdl_preview.c | 34 +-- src/modules/sdl/consumer_sdl_still.c | 16 +- src/modules/sdl2/consumer_sdl2.c | 15 +- src/modules/sdl2/consumer_sdl2_audio.c | 11 +- src/modules/xml/consumer_xml.c | 4 +- src/swig/mlt.i | 18 +- src/swig/ruby/play.rb | 2 +- src/swig/ruby/playlist.rb | 6 +- src/swig/ruby/thumbs.rb | 2 +- src/tests/test_events/test_events.cpp | 12 +- 65 files changed, 716 insertions(+), 562 deletions(-) diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index 77861caca..8da30f67d 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -604,4 +604,13 @@ MLT_7.0.0 { mlt_image_calculate_size; mlt_image_fill_black; mlt_audio_silence; + mlt_event_data_none; + mlt_event_data_from_int; + mlt_event_data_to_int; + mlt_event_data_from_string; + mlt_event_data_to_string; + mlt_event_data_from_frame; + mlt_event_data_to_frame; + mlt_event_data_from_object; + mlt_event_data_to_object; } MLT_6.22.0; diff --git a/src/framework/mlt_chain.c b/src/framework/mlt_chain.c index 87e53b2c3..0d6866fa3 100644 --- a/src/framework/mlt_chain.c +++ b/src/framework/mlt_chain.c @@ -189,7 +189,7 @@ void mlt_chain_set_source( mlt_chain self, mlt_producer source ) // Reconfigure the chain relink_chain( self ); - mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", NULL ); + mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", mlt_event_data_none() ); } } @@ -245,7 +245,7 @@ int mlt_chain_attach( mlt_chain self, mlt_link link ) mlt_properties_set_data( MLT_LINK_PROPERTIES( link ), "chain", self, 0, NULL, NULL ); base->links[ base->link_count ++ ] = link; relink_chain( self ); - mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", NULL ); + mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", mlt_event_data_none() ); } else { @@ -284,7 +284,7 @@ int mlt_chain_detach( mlt_chain self, mlt_link link ) base->link_count --; mlt_link_close( link ); relink_chain( self ); - mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", NULL ); + mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", mlt_event_data_none() ); } } return error; @@ -343,7 +343,7 @@ int mlt_chain_move_link( mlt_chain self, int from, int to ) } base->links[to] = link; relink_chain( self ); - mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", NULL ); + mlt_events_fire( MLT_CHAIN_PROPERTIES(self), "chain-changed", mlt_event_data_none() ); error = 0; } } diff --git a/src/framework/mlt_consumer.c b/src/framework/mlt_consumer.c index 15fb5cb07..a57233ee6 100644 --- a/src/framework/mlt_consumer.c +++ b/src/framework/mlt_consumer.c @@ -3,7 +3,7 @@ * \brief abstraction for all consumer services * \see mlt_consumer_s * - * Copyright (C) 2003-2020 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -80,16 +80,10 @@ typedef struct } consumer_private; -typedef void* ( *thread_function_t )( void* ); - -static void mlt_consumer_frame_render( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ); -static void mlt_consumer_frame_show( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ); -static void mlt_consumer_property_changed( mlt_properties owner, mlt_consumer self, char *name ); +static void mlt_consumer_property_changed(mlt_properties owner, mlt_consumer self, mlt_event_data ); static void apply_profile_properties( mlt_consumer self, mlt_profile profile, mlt_properties properties ); -static void on_consumer_frame_show( mlt_properties owner, mlt_consumer self, mlt_frame frame ); -static void transmit_thread_create( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ); -static void mlt_thread_create( mlt_consumer self, thread_function_t function ); -static void transmit_thread_join( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ); +static void on_consumer_frame_show(mlt_properties owner, mlt_consumer self, mlt_event_data ); +static void mlt_thread_create( mlt_consumer self, mlt_thread_function_t function ); static void mlt_thread_join( mlt_consumer self ); static void consumer_read_ahead_start( mlt_consumer self ); @@ -149,14 +143,14 @@ int mlt_consumer_init( mlt_consumer self, void *child, mlt_profile profile ) priv->image_format = mlt_image_yuv422; priv->audio_format = mlt_audio_s16; - mlt_events_register( properties, "consumer-frame-show", ( mlt_transmitter )mlt_consumer_frame_show ); - mlt_events_register( properties, "consumer-frame-render", ( mlt_transmitter )mlt_consumer_frame_render ); - mlt_events_register( properties, "consumer-thread-started", NULL ); - mlt_events_register( properties, "consumer-thread-stopped", NULL ); - mlt_events_register( properties, "consumer-stopping", NULL ); - mlt_events_register( properties, "consumer-stopped", NULL ); - mlt_events_register( properties, "consumer-thread-create", ( mlt_transmitter )transmit_thread_create ); - mlt_events_register( properties, "consumer-thread-join", ( mlt_transmitter )transmit_thread_join ); + mlt_events_register( properties, "consumer-frame-show" ); + mlt_events_register( properties, "consumer-frame-render" ); + mlt_events_register( properties, "consumer-thread-started" ); + mlt_events_register( properties, "consumer-thread-stopped" ); + mlt_events_register( properties, "consumer-stopping" ); + mlt_events_register( properties, "consumer-stopped" ); + mlt_events_register( properties, "consumer-thread-create" ); + mlt_events_register( properties, "consumer-thread-join" ); mlt_events_listen( properties, self, "consumer-frame-show", ( mlt_listener )on_consumer_frame_show ); // Register a property-changed listener to handle the profile property - @@ -208,9 +202,10 @@ static void apply_profile_properties( mlt_consumer self, mlt_profile profile, ml * \param name the name of the property that changed */ -static void mlt_consumer_property_changed( mlt_properties owner, mlt_consumer self, char *name ) +static void mlt_consumer_property_changed( mlt_properties owner, mlt_consumer self, mlt_event_data event_data ) { - if ( !strcmp( name, "mlt_profile" ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && !strcmp( name, "mlt_profile" ) ) { // Get the properties mlt_properties properties = MLT_CONSUMER_PROPERTIES( self ); @@ -330,40 +325,6 @@ static void mlt_consumer_property_changed( mlt_properties owner, mlt_consumer se } } -/** The transmitter for the consumer-frame-show event - * - * Invokes the listener. - * - * \private \memberof mlt_consumer_s - * \param listener a function pointer that will be invoked - * \param owner the events object that will be passed to \p listener - * \param self a service that will be passed to \p listener - * \param args an array of pointers - the first entry is passed as a frame to \p listener - */ - -static void mlt_consumer_frame_show( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener != NULL ) - listener( owner, self, ( mlt_frame )args[ 0 ] ); -} - -/** The transmitter for the consumer-frame-render event - * - * Invokes the listener. - * - * \private \memberof mlt_consumer_s - * \param listener a function pointer that will be invoked - * \param owner the events object that will be passed to \p listener - * \param self a service that will be passed to \p listener - * \param args an array of pointers - the first entry is passed as a frame to \p listener - */ - -static void mlt_consumer_frame_render( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener != NULL ) - listener( owner, self, ( mlt_frame )args[ 0 ] ); -} - /** A listener on the consumer-frame-show event * * Saves the position of the frame shown. @@ -374,8 +335,9 @@ static void mlt_consumer_frame_render( mlt_listener listener, mlt_properties own * \param frame the frame that was shown */ -static void on_consumer_frame_show( mlt_properties owner, mlt_consumer consumer, mlt_frame frame ) +static void on_consumer_frame_show( mlt_properties owner, mlt_consumer consumer, mlt_event_data event_data ) { + mlt_frame frame = mlt_event_data_to_frame(event_data); if ( frame ) { consumer_private* priv = consumer->local; pthread_mutex_lock( &priv->position_mutex ); @@ -810,7 +772,7 @@ static void *consumer_read_ahead_thread( void *arg ) set_audio_format( self ); set_image_format( self ); - mlt_events_fire( properties, "consumer-thread-started", NULL ); + mlt_events_fire( properties, "consumer-thread-started", mlt_event_data_none() ); // Get the first frame frame = mlt_consumer_get_frame( self ); @@ -828,7 +790,7 @@ static void *consumer_read_ahead_thread( void *arg ) // Get the image of the first frame if ( !video_off ) { - mlt_events_fire( MLT_CONSUMER_PROPERTIES( self ), "consumer-frame-render", frame, NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES( self ), "consumer-frame-render", mlt_event_data_from_frame(frame) ); mlt_frame_get_image( frame, &image, &priv->image_format, &width, &height, 0 ); } @@ -906,7 +868,7 @@ static void *consumer_read_ahead_thread( void *arg ) height = mlt_properties_get_int( properties, "height" ); // Get the image - mlt_events_fire( MLT_CONSUMER_PROPERTIES( self ), "consumer-frame-render", frame, NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES( self ), "consumer-frame-render", mlt_event_data_from_frame(frame) ); mlt_log_timings_begin(); mlt_frame_get_image( frame, &image, &priv->image_format, &width, &height, 0 ); mlt_log_timings_end( NULL, "mlt_frame_get_image" ); @@ -991,7 +953,7 @@ static void *consumer_read_ahead_thread( void *arg ) priv->queue = NULL; pthread_mutex_unlock( &priv->queue_mutex ); - mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-thread-stopped", NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-thread-stopped", mlt_event_data_none() ); return NULL; } @@ -1053,7 +1015,7 @@ static void *consumer_worker_thread( void *arg ) if ( preview_off && preview_format != 0 ) format = preview_format; - mlt_events_fire( properties, "consumer-thread-started", NULL ); + mlt_events_fire( properties, "consumer-thread-started", mlt_event_data_none() ); // Continue to read ahead while ( priv->ahead ) @@ -1099,7 +1061,7 @@ static void *consumer_worker_thread( void *arg ) // Fetch width/height again width = mlt_properties_get_int( properties, "width" ); height = mlt_properties_get_int( properties, "height" ); - mlt_events_fire( MLT_CONSUMER_PROPERTIES( self ), "consumer-frame-render", frame, NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES( self ), "consumer-frame-render", mlt_event_data_from_frame(frame) ); mlt_frame_get_image( frame, &image, &format, &width, &height, 0 ); } mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "rendered", 1 ); @@ -1140,7 +1102,7 @@ static void consumer_read_ahead_start( mlt_consumer self ) pthread_cond_init( &priv->queue_cond, NULL ); // Create the read ahead - mlt_thread_create( self, (thread_function_t) consumer_read_ahead_thread ); + mlt_thread_create( self, (mlt_thread_function_t) consumer_read_ahead_thread ); priv->started = 1; } @@ -1241,7 +1203,7 @@ static void consumer_read_ahead_stop( mlt_consumer self ) { // Inform thread to stop priv->ahead = 0; - mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-stopping", NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-stopping", mlt_event_data_none() ); // Broadcast to the condition in case it's waiting pthread_mutex_lock( &priv->queue_mutex ); @@ -1280,7 +1242,7 @@ static void consumer_work_stop( mlt_consumer self ) { // Inform thread to stop priv->ahead = 0; - mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-stopping", NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-stopping", mlt_event_data_none() ); // Broadcast to the queue condition in case it's waiting pthread_mutex_lock( &priv->queue_mutex ); @@ -1321,7 +1283,7 @@ static void consumer_work_stop( mlt_consumer self ) mlt_deque_close( priv->queue ); mlt_deque_close( priv->worker_threads ); - mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-thread-stopped", NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-thread-stopped", mlt_event_data_none() ); } } @@ -1603,7 +1565,7 @@ mlt_frame mlt_consumer_rt_frame( mlt_consumer self ) if ( !priv->ahead ) { priv->ahead = 1; - mlt_events_fire( properties, "consumer-thread-started", NULL ); + mlt_events_fire( properties, "consumer-thread-started", mlt_event_data_none() ); } // Get the frame in non real time frame = mlt_consumer_get_frame( self ); @@ -1630,7 +1592,7 @@ mlt_frame mlt_consumer_rt_frame( mlt_consumer self ) void mlt_consumer_stopped( mlt_consumer self ) { mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( self ), "running", 0 ); - mlt_events_fire( MLT_CONSUMER_PROPERTIES( self ), "consumer-stopped", NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES( self ), "consumer-stopped", mlt_event_data_none() ); mlt_event_unblock( ( ( consumer_private* ) self->local )->event_listener ); } @@ -1766,14 +1728,7 @@ mlt_position mlt_consumer_position( mlt_consumer consumer ) return result; } -static void transmit_thread_create( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener ) - listener( owner, self, - (void**) args[0] /* handle */, (int*) args[1] /* priority */, (thread_function_t) args[2], (void*) args[3] /* data */ ); -} - -static void mlt_thread_create( mlt_consumer self, thread_function_t function ) +static void mlt_thread_create(mlt_consumer self, mlt_thread_function_t function ) { consumer_private *priv = self->local; mlt_properties properties = MLT_CONSUMER_PROPERTIES( self ); @@ -1782,8 +1737,13 @@ static void mlt_thread_create( mlt_consumer self, thread_function_t function ) { struct sched_param priority; priority.sched_priority = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( self ), "priority" ); - if ( mlt_events_fire( properties, "consumer-thread-create", - &priv->ahead_thread, &priority.sched_priority, function, self, NULL ) < 1 ) + mlt_event_data_thread data = { + .thread = &priv->ahead_thread, + .priority = &priority.sched_priority, + .function = function, + .data = self + }; + if ( mlt_events_fire( properties, "consumer-thread-create", mlt_event_data_from_object(&data) ) < 1 ) { pthread_attr_t thread_attributes; pthread_attr_init( &thread_attributes ); @@ -1801,8 +1761,13 @@ static void mlt_thread_create( mlt_consumer self, thread_function_t function ) else { int priority = -1; - if ( mlt_events_fire( properties, "consumer-thread-create", - &priv->ahead_thread, &priority, function, self, NULL ) < 1 ) + mlt_event_data_thread data = { + .thread = &priv->ahead_thread, + .priority = &priority, + .function = function, + .data = self + }; + if ( mlt_events_fire( properties, "consumer-thread-create", mlt_event_data_from_object(&data) ) < 1 ) { priv->ahead_thread = malloc( sizeof( pthread_t ) ); pthread_t *handle = priv->ahead_thread; @@ -1811,16 +1776,11 @@ static void mlt_thread_create( mlt_consumer self, thread_function_t function ) } } -static void transmit_thread_join( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener ) - listener( owner, self, (void*) args[0] /* handle */ ); -} - static void mlt_thread_join( mlt_consumer self ) { consumer_private *priv = self->local; - if ( mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-thread-join", priv->ahead_thread, NULL ) < 1 ) + if ( mlt_events_fire( MLT_CONSUMER_PROPERTIES(self), "consumer-thread-join", + mlt_event_data_from_object(priv->ahead_thread) ) < 1 ) { pthread_t *handle = priv->ahead_thread; pthread_join( *handle, NULL ); diff --git a/src/framework/mlt_consumer.h b/src/framework/mlt_consumer.h index 9000e1da6..3b776c08b 100644 --- a/src/framework/mlt_consumer.h +++ b/src/framework/mlt_consumer.h @@ -3,7 +3,7 @@ * \brief abstraction for all consumer services * \see mlt_consumer_s * - * Copyright (C) 2003-2015 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -51,12 +51,15 @@ * environment variable MLT_TEST_CARD. If undefined, the hard-coded default test card is * white silence. A test card is what appears when nothing is produced. * \event \em consumer-frame-show Subclass implementations fire this immediately after showing a frame - * or when a frame should be shown (if audio-only consumer). - * \event \em consumer-frame-render The base class fires this immediately before rendering a frame. + * or when a frame should be shown (if audio-only consumer). The event data is a frame. + * \event \em consumer-frame-render The base class fires this immediately before rendering a frame; + * the event data is a frame. * \event \em consumer-thread-create Override the implementation of creating and * starting a thread by listening and responding to this (real_time 1 or -1 only). + * The event data is a pointer to mlt_event_data_thread. * \event \em consumer-thread-join Override the implementation of waiting and * joining a terminated thread by listening and responding to this (real_time 1 or -1 only). + * The event data is a pointer to mlt_event_data_thread. * \event \em consumer-thread-started The base class fires when beginning execution of a rendering thread. * \event \em consumer-thread-stopped The base class fires when a rendering thread has ended. * \event \em consumer-stopping This is fired when stop was requested, but before render threads are joined. diff --git a/src/framework/mlt_events.c b/src/framework/mlt_events.c index 6051befcd..dcb5b8b2c 100644 --- a/src/framework/mlt_events.c +++ b/src/framework/mlt_events.c @@ -3,7 +3,7 @@ * \brief event handling * \see mlt_events_struct * - * Copyright (C) 2004-2019 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,9 +21,9 @@ */ #include -#include #include #include +#include #include "mlt_properties.h" #include "mlt_events.h" @@ -48,7 +48,7 @@ static int events_destroyed = 0; struct mlt_events_struct { mlt_properties owner; - mlt_properties list; + mlt_properties listeners; }; typedef struct mlt_events_struct *mlt_events; @@ -59,11 +59,11 @@ typedef struct mlt_events_struct *mlt_events; struct mlt_event_struct { - mlt_events owner; + mlt_events parent; int ref_count; int block_count; mlt_listener listener; - void *service; + void *listener_data; }; /** Increment the reference count on self event. @@ -86,7 +86,7 @@ void mlt_event_inc_ref( mlt_event self ) void mlt_event_block( mlt_event self ) { - if ( self != NULL && self->owner != NULL ) + if ( self != NULL && self->parent != NULL ) self->block_count ++; } @@ -98,7 +98,7 @@ void mlt_event_block( mlt_event self ) void mlt_event_unblock( mlt_event self ) { - if ( self != NULL && self->owner != NULL ) + if ( self != NULL && self->parent != NULL ) self->block_count --; } @@ -113,7 +113,7 @@ void mlt_event_close( mlt_event self ) if ( self != NULL ) { if ( -- self->ref_count == 1 ) - self->owner = NULL; + self->parent = NULL; if ( self->ref_count <= 0 ) { #ifdef _MLT_EVENT_CHECKS_ @@ -142,31 +142,29 @@ void mlt_events_init( mlt_properties self ) if (!events && self) { events = calloc( 1, sizeof( struct mlt_events_struct ) ); if (events) { - events->list = mlt_properties_new( ); + events->listeners = mlt_properties_new( ); events->owner = self; mlt_properties_set_data( self, "_events", events, 0, ( mlt_destructor )mlt_events_close, NULL ); } } } -/** Register an event and transmitter. +/** Register an event. * * \public \memberof mlt_events_struct * \param self a properties list * \param id the name of an event - * \param transmitter the callback function to send an event message * \return true if there was an error */ -int mlt_events_register( mlt_properties self, const char *id, mlt_transmitter transmitter ) +int mlt_events_register(mlt_properties self, const char *id) { int error = 1; mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { - mlt_properties list = events->list; + mlt_properties list = events->listeners; char temp[ 128 ]; - error = mlt_properties_set_data( list, id, transmitter, 0, NULL, NULL ); sprintf( temp, "list:%s", id ); if ( mlt_properties_get_data( list, temp, NULL ) == NULL ) mlt_properties_set_data( list, temp, mlt_properties_new( ), 0, ( mlt_destructor )mlt_properties_close, NULL ); @@ -176,47 +174,33 @@ int mlt_events_register( mlt_properties self, const char *id, mlt_transmitter tr /** Fire an event. * - * This takes a variable number of arguments to supply to the listener. - * \public \memberof mlt_events_struct * \param self a properties list * \param id the name of an event + * \param event_data an event data object * \return the number of listeners */ -int mlt_events_fire( mlt_properties self, const char *id, ... ) +int mlt_events_fire(mlt_properties self, const char *id, mlt_event_data event_data) { int result = 0; mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { - int i = 0; - va_list alist; - void *args[ 10 ]; - mlt_properties list = events->list; + mlt_properties list = events->listeners; mlt_properties listeners = NULL; char temp[ 128 ]; - mlt_transmitter transmitter = mlt_properties_get_data( list, id, NULL ); sprintf( temp, "list:%s", id ); listeners = mlt_properties_get_data( list, temp, NULL ); - va_start( alist, id ); - do - args[ i ] = va_arg( alist, void * ); - while( args[ i ++ ] != NULL ); - va_end( alist ); - if ( listeners != NULL ) { - for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) + for ( int i = 0; i < mlt_properties_count( listeners ); i ++ ) { mlt_event event = mlt_properties_get_data_at( listeners, i, NULL ); - if ( event != NULL && event->owner != NULL && event->block_count == 0 ) + if ( event != NULL && event->parent != NULL && event->block_count == 0 ) { - if ( transmitter != NULL ) - transmitter( event->listener, event->owner->owner, event->service, args ); - else - event->listener( event->owner->owner, event->service ); + event->listener( event->parent->owner, event->listener_data, event_data ); ++result; } } @@ -229,19 +213,19 @@ int mlt_events_fire( mlt_properties self, const char *id, ... ) * * \public \memberof mlt_events_struct * \param self a properties list - * \param service an opaque pointer + * \param listener_data an opaque pointer * \param id the name of the event to listen for * \param listener the callback to receive an event message - * \return + * \return an event */ -mlt_event mlt_events_listen( mlt_properties self, void *service, const char *id, mlt_listener listener ) +mlt_event mlt_events_listen( mlt_properties self, void *listener_data, const char *id, mlt_listener listener ) { mlt_event event = NULL; mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { - mlt_properties list = events->list; + mlt_properties list = events->listeners; mlt_properties listeners = NULL; char temp[ 128 ]; sprintf( temp, "list:%s", id ); @@ -253,12 +237,12 @@ mlt_event mlt_events_listen( mlt_properties self, void *service, const char *id, for ( i = 0; event == NULL && i < mlt_properties_count( listeners ); i ++ ) { mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - if ( entry != NULL && entry->owner != NULL ) + if ( entry != NULL && entry->parent != NULL ) { - if ( entry->service == service && entry->listener == listener ) + if ( entry->listener_data == listener_data && entry->listener == listener ) event = entry; } - else if ( ( entry == NULL || entry->owner == NULL ) && first_null == -1 ) + else if ( ( entry == NULL || entry->parent == NULL ) && first_null == -1 ) { first_null = i; } @@ -273,11 +257,11 @@ mlt_event mlt_events_listen( mlt_properties self, void *service, const char *id, events_created ++; #endif sprintf( temp, "%d", first_null == -1 ? mlt_properties_count( listeners ) : first_null ); - event->owner = events; + event->parent = events; event->ref_count = 0; event->block_count = 0; event->listener = listener; - event->service = service; + event->listener_data = listener_data; mlt_properties_set_data( listeners, temp, event, 0, ( mlt_destructor )mlt_event_close, NULL ); mlt_event_inc_ref( event ); } @@ -288,20 +272,20 @@ mlt_event mlt_events_listen( mlt_properties self, void *service, const char *id, return event; } -/** Block all events for a given service. +/** Block all events for a given listener_data. * * \public \memberof mlt_events_struct * \param self a properties list - * \param service an opaque pointer + * \param listener_data the listener's opaque data pointer */ -void mlt_events_block( mlt_properties self, void *service ) +void mlt_events_block( mlt_properties self, void *listener_data ) { mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { int i = 0, j = 0; - mlt_properties list = events->list; + mlt_properties list = events->listeners; for ( j = 0; j < mlt_properties_count( list ); j ++ ) { char *temp = mlt_properties_get_name( list, j ); @@ -311,7 +295,7 @@ void mlt_events_block( mlt_properties self, void *service ) for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) { mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - if ( entry != NULL && entry->service == service ) + if ( entry != NULL && entry->listener_data == listener_data ) mlt_event_block( entry ); } } @@ -319,20 +303,20 @@ void mlt_events_block( mlt_properties self, void *service ) } } -/** Unblock all events for a given service. +/** Unblock all events for a given listener_data. * * \public \memberof mlt_events_struct * \param self a properties list - * \param service an opaque pointer + * \param listener_data the listener's opaque data pointer */ -void mlt_events_unblock( mlt_properties self, void *service ) +void mlt_events_unblock( mlt_properties self, void *listener_data ) { mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { int i = 0, j = 0; - mlt_properties list = events->list; + mlt_properties list = events->listeners; for ( j = 0; j < mlt_properties_count( list ); j ++ ) { char *temp = mlt_properties_get_name( list, j ); @@ -342,7 +326,7 @@ void mlt_events_unblock( mlt_properties self, void *service ) for ( i = 0; i < mlt_properties_count( listeners ); i ++ ) { mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); - if ( entry != NULL && entry->service == service ) + if ( entry != NULL && entry->listener_data == listener_data ) mlt_event_unblock( entry ); } } @@ -350,20 +334,20 @@ void mlt_events_unblock( mlt_properties self, void *service ) } } -/** Disconnect all events for a given service. +/** Disconnect all events for a given listener_data. * * \public \memberof mlt_events_struct * \param self a properties list - * \param service an opaque pointer + * \param listener_data the listener's opaque data pointer */ -void mlt_events_disconnect( mlt_properties self, void *service ) +void mlt_events_disconnect( mlt_properties self, void *listener_data ) { mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { int i = 0, j = 0; - mlt_properties list = events->list; + mlt_properties list = events->listeners; for ( j = 0; j < mlt_properties_count( list ); j ++ ) { char *temp = mlt_properties_get_name( list, j ); @@ -374,7 +358,7 @@ void mlt_events_disconnect( mlt_properties self, void *service ) { mlt_event entry = mlt_properties_get_data_at( listeners, i, NULL ); char *name = mlt_properties_get_name( listeners, i ); - if ( entry != NULL && entry->service == service ) + if ( entry != NULL && entry->listener_data == listener_data ) mlt_properties_set_data( listeners, name, NULL, 0, NULL, NULL ); } } @@ -433,7 +417,7 @@ void mlt_events_wait_for( mlt_properties self, mlt_event event ) { if ( event != NULL ) { - condition_pair *pair = event->service; + condition_pair *pair = event->listener_data; pthread_cond_wait( &pair->cond, &pair->mutex ); } } @@ -449,8 +433,8 @@ void mlt_events_close_wait_for( mlt_properties self, mlt_event event ) { if ( event != NULL ) { - condition_pair *pair = event->service; - event->owner = NULL; + condition_pair *pair = event->listener_data; + event->parent = NULL; pthread_mutex_unlock( &pair->mutex ); pthread_mutex_destroy( &pair->mutex ); pthread_cond_destroy( &pair->cond ); @@ -483,7 +467,124 @@ static void mlt_events_close( mlt_events events ) { if ( events != NULL ) { - mlt_properties_close( events->list ); + mlt_properties_close( events->listeners ); free( events ); } } + +/** Initialize an empty event data. + * + * \public \memberof mlt_event_data + * \return an event data object + */ + +mlt_event_data mlt_event_data_none() +{ + mlt_event_data event_data; + event_data.u.p = NULL; + return event_data; +} + +/** Initialize event data with an integer. + * + * \public \memberof mlt_event_data + * \param value the integer with which to initialize the event data + * \return an event data object + */ + +mlt_event_data mlt_event_data_from_int(int value) +{ + mlt_event_data event_data; + event_data.u.i = value; + return event_data; +} + +/** Get an integer from the event data. + * + * \public \memberof mlt_event_data + * \param event_data an event data object + * \return an integer + */ + +int mlt_event_data_to_int(mlt_event_data event_data) +{ + return event_data.u.i; +} + +/** Initialize event data with a string. + * + * \public \memberof mlt_event_data + * \param value the string with which to initialize the event data + * \return an event data object + */ + +mlt_event_data mlt_event_data_from_string(const char *value) +{ + mlt_event_data event_data; + event_data.u.p = (void*) value; + return event_data; +} + +/** Get a string from the event data. + * + * \public \memberof mlt_event_data + * \param event_data an event data object + * \return a string + */ + +const char *mlt_event_data_to_string(mlt_event_data event_data) +{ + return event_data.u.p; +} + +/** Initialize event data with a frame. + * + * \public \memberof mlt_event_data + * \param frame the frame with which to initialize the event data + * \return an event data object + */ + +mlt_event_data mlt_event_data_from_frame(mlt_frame frame) +{ + mlt_event_data event_data; + event_data.u.p = frame; + return event_data; +} + +/** Get a frame from the event data. + * + * \public \memberof mlt_event_data + * \param event_data an event data object + * \return a frame + */ + +mlt_frame mlt_event_data_to_frame(mlt_event_data event_data) +{ + return (mlt_frame) event_data.u.p; +} + +/** Initialize event data with opaque data. + * + * \public \memberof mlt_event_data + * \param value the pointer with which to initialize the event data + * \return an event data object + */ + +mlt_event_data mlt_event_data_from_object(void *value) +{ + mlt_event_data event_data; + event_data.u.p = value; + return event_data; +} + +/** Get a pointer from the event data. + * + * \public \memberof mlt_event_data + * \param event_data an event data object + * \return a pointer + */ + +void *mlt_event_data_to_object(mlt_event_data event_data) +{ + return event_data.u.p; +} diff --git a/src/framework/mlt_events.h b/src/framework/mlt_events.h index f2637595f..9c643f928 100644 --- a/src/framework/mlt_events.h +++ b/src/framework/mlt_events.h @@ -3,7 +3,7 @@ * \brief event handling * \see mlt_events_struct * - * Copyright (C) 2004-2014 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -25,29 +25,36 @@ #include "mlt_types.h" -#if GCC_VERSION >= 40000 -typedef void ( *mlt_transmitter )( void *, ... ); -typedef void ( *mlt_listener )( void *, ... ); -#else -/** callback function to send an event message - * - */ -typedef void ( *mlt_transmitter )( ); +/** A container for data that may be supplied with an event */ +typedef struct { + union { + int i; + void *p; + } u; +} mlt_event_data; + +/** An event data structure to convey thread parameters */ +typedef struct { + void **thread; /**< a pointer to a thread object or handle as determined by you */ + int *priority; /**< a priority level for the thread */ + mlt_thread_function_t function; /**< a pointer to the function that thread will run */ + void *data; /**< an opaque data pointer to pass along */ +} mlt_event_data_thread; + /** event handler when receiving an event message * \param the properties object on which the event was registered - * \param an opaque pointer to a service or really an object - * \param variable args supplied by the transmitter + * \param an opaque pointer to the listener's data + * \param an event data object */ -typedef void ( *mlt_listener )( ); -#endif +typedef void ( *mlt_listener )( mlt_properties, void*, mlt_event_data ); extern void mlt_events_init( mlt_properties self ); -extern int mlt_events_register( mlt_properties self, const char *id, mlt_transmitter transmitter ); -extern int mlt_events_fire( mlt_properties self, const char *id, ... ); -extern mlt_event mlt_events_listen( mlt_properties self, void *service, const char *id, mlt_listener listener ); -extern void mlt_events_block( mlt_properties self, void *service ); -extern void mlt_events_unblock( mlt_properties self, void *service ); -extern void mlt_events_disconnect( mlt_properties self, void *service ); +extern int mlt_events_register( mlt_properties self, const char *id ); +extern int mlt_events_fire( mlt_properties self, const char *id, mlt_event_data ); +extern mlt_event mlt_events_listen( mlt_properties self, void *listener_data, const char *id, mlt_listener listener ); +extern void mlt_events_block( mlt_properties self, void *listener_data ); +extern void mlt_events_unblock( mlt_properties self, void *listener_data ); +extern void mlt_events_disconnect( mlt_properties self, void *listener_data ); extern mlt_event mlt_events_setup_wait_for( mlt_properties self, const char *id ); extern void mlt_events_wait_for( mlt_properties self, mlt_event event ); @@ -58,5 +65,14 @@ extern void mlt_event_block( mlt_event self ); extern void mlt_event_unblock( mlt_event self ); extern void mlt_event_close( mlt_event self ); -#endif +extern mlt_event_data mlt_event_data_none(); +extern mlt_event_data mlt_event_data_from_int(int value); +extern int mlt_event_data_to_int(mlt_event_data); +extern mlt_event_data mlt_event_data_from_string(const char *value); +extern const char* mlt_event_data_to_string(mlt_event_data); +extern mlt_event_data mlt_event_data_from_frame(mlt_frame); +extern mlt_frame mlt_event_data_to_frame(mlt_event_data); +extern mlt_event_data mlt_event_data_from_object(void*); +extern void* mlt_event_data_to_object(mlt_event_data); +#endif diff --git a/src/framework/mlt_factory.c b/src/framework/mlt_factory.c index 4867faca2..6a0e211e3 100644 --- a/src/framework/mlt_factory.c +++ b/src/framework/mlt_factory.c @@ -2,7 +2,7 @@ * \file mlt_factory.c * \brief the factory method interfaces * - * Copyright (C) 2003-2019 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -69,36 +69,6 @@ static mlt_properties event_object = NULL; /** for tracking the unique_id set on each constructed service */ static int unique_id = 0; -/* Event transmitters. */ - -/** the -create-request event transmitter - * - * \param listener - * \param owner - * \param self - * \param args - */ - -static void mlt_factory_create_request( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener != NULL ) - listener( owner, self, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service * )args[ 2 ] ); -} - -/** the -create-done event transmitter - * - * \param listener - * \param owner - * \param self - * \param args - */ - -static void mlt_factory_create_done( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener != NULL ) - listener( owner, self, ( char * )args[ 0 ], ( char * )args[ 1 ], ( mlt_service )args[ 2 ] ); -} - #if defined(_WIN32) || (defined(__APPLE__) && defined(RELOCATABLE)) // Replacement for buggy dirname() on some systems. // https://github.com/mltframework/mlt/issues/285 @@ -218,14 +188,14 @@ mlt_repository mlt_factory_init( const char *directory ) // Create and set up the events object event_object = mlt_properties_new( ); mlt_events_init( event_object ); - mlt_events_register( event_object, "producer-create-request", ( mlt_transmitter )mlt_factory_create_request ); - mlt_events_register( event_object, "producer-create-done", ( mlt_transmitter )mlt_factory_create_done ); - mlt_events_register( event_object, "filter-create-request", ( mlt_transmitter )mlt_factory_create_request ); - mlt_events_register( event_object, "filter-create-done", ( mlt_transmitter )mlt_factory_create_done ); - mlt_events_register( event_object, "transition-create-request", ( mlt_transmitter )mlt_factory_create_request ); - mlt_events_register( event_object, "transition-create-done", ( mlt_transmitter )mlt_factory_create_done ); - mlt_events_register( event_object, "consumer-create-request", ( mlt_transmitter )mlt_factory_create_request ); - mlt_events_register( event_object, "consumer-create-done", ( mlt_transmitter )mlt_factory_create_done ); + mlt_events_register( event_object, "producer-create-request" ); + mlt_events_register( event_object, "producer-create-done" ); + mlt_events_register( event_object, "filter-create-request" ); + mlt_events_register( event_object, "filter-create-done" ); + mlt_events_register( event_object, "transition-create-request" ); + mlt_events_register( event_object, "transition-create-done" ); + mlt_events_register( event_object, "consumer-create-request" ); + mlt_events_register( event_object, "consumer-create-done" ); // Create the repository of services repository = mlt_repository_init( mlt_directory ); @@ -354,13 +324,18 @@ mlt_producer mlt_factory_producer( mlt_profile profile, const char *service, con service = mlt_environment( "MLT_PRODUCER" ); // Offer the application the chance to 'create' - mlt_events_fire( event_object, "producer-create-request", service, resource, &obj, NULL ); + mlt_factory_event_data data = { + .name = service, + .input = resource, + .service = &obj + }; + mlt_events_fire( event_object, "producer-create-request", mlt_event_data_from_object(&data) ); // Try to instantiate via the specified service if ( obj == NULL ) { obj = mlt_repository_create( repository, profile, mlt_service_producer_type, service, resource ); - mlt_events_fire( event_object, "producer-create-done", service, resource, obj, NULL ); + mlt_events_fire( event_object, "producer-create-done", mlt_event_data_from_object(&data) ); if ( obj != NULL ) { mlt_properties properties = MLT_PRODUCER_PROPERTIES( obj ); @@ -391,12 +366,17 @@ mlt_filter mlt_factory_filter( mlt_profile profile, const char *service, const v mlt_filter obj = NULL; // Offer the application the chance to 'create' - mlt_events_fire( event_object, "filter-create-request", service, input, &obj, NULL ); + mlt_factory_event_data data = { + .name = service, + .input = input, + .service = &obj + }; + mlt_events_fire( event_object, "filter-create-request", mlt_event_data_from_object(&data) ); if ( obj == NULL ) { obj = mlt_repository_create( repository, profile, mlt_service_filter_type, service, input ); - mlt_events_fire( event_object, "filter-create-done", service, input, obj, NULL ); + mlt_events_fire( event_object, "filter-create-done", mlt_event_data_from_object(&data) ); } if ( obj != NULL ) @@ -419,12 +399,17 @@ mlt_link mlt_factory_link( const char *service, const void *input ) mlt_link obj = NULL; // Offer the application the chance to 'create' - mlt_events_fire( event_object, "link-create-request", service, input, &obj, NULL ); + mlt_factory_event_data data = { + .name = service, + .input = input, + .service = &obj + }; + mlt_events_fire( event_object, "link-create-request", mlt_event_data_from_object(&data) ); if ( obj == NULL ) { obj = mlt_repository_create( repository, NULL, mlt_service_link_type, service, input ); - mlt_events_fire( event_object, "link-create-done", service, input, obj, NULL ); + mlt_events_fire( event_object, "link-create-done", mlt_event_data_from_object(&data) ); } if ( obj != NULL ) @@ -448,12 +433,17 @@ mlt_transition mlt_factory_transition( mlt_profile profile, const char *service, mlt_transition obj = NULL; // Offer the application the chance to 'create' - mlt_events_fire( event_object, "transition-create-request", service, input, &obj, NULL ); + mlt_factory_event_data data = { + .name = service, + .input = input, + .service = &obj + }; + mlt_events_fire( event_object, "transition-create-request", mlt_event_data_from_object(&data) ); if ( obj == NULL ) { obj = mlt_repository_create( repository, profile, mlt_service_transition_type, service, input ); - mlt_events_fire( event_object, "transition-create-done", service, input, obj, NULL ); + mlt_events_fire( event_object, "transition-create-done", mlt_event_data_from_object(&data) ); } if ( obj != NULL ) @@ -480,7 +470,12 @@ mlt_consumer mlt_factory_consumer( mlt_profile profile, const char *service, con service = mlt_environment( "MLT_CONSUMER" ); // Offer the application the chance to 'create' - mlt_events_fire( event_object, "consumer-create-request", service, input, &obj, NULL ); + mlt_factory_event_data data = { + .name = service, + .input = input, + .service = &obj + }; + mlt_events_fire( event_object, "consumer-create-request",mlt_event_data_from_object(&data) ); if ( obj == NULL ) { @@ -504,7 +499,7 @@ mlt_consumer mlt_factory_consumer( mlt_profile profile, const char *service, con if ( obj != NULL ) { mlt_properties properties = MLT_CONSUMER_PROPERTIES( obj ); - mlt_events_fire( event_object, "consumer-create-done", service, input, obj, NULL ); + mlt_events_fire( event_object, "consumer-create-done", mlt_event_data_from_object(&data) ); set_common_properties( properties, profile, "consumer", service ); } return obj; diff --git a/src/framework/mlt_factory.h b/src/framework/mlt_factory.h index 0861411a4..5ae7f53f1 100644 --- a/src/framework/mlt_factory.h +++ b/src/framework/mlt_factory.h @@ -2,7 +2,7 @@ * \file mlt_factory.h * \brief the factory method interfaces * - * Copyright (C) 2003-2018 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -35,14 +35,26 @@ * \envvar \em MLT_REPOSITORY overrides the default location of the plugin modules, defaults to \p PREFIX_LIB. * MLT_REPOSITORY is ignored on Windows and OS X relocatable builds. * \envvar \em MLT_PRESETS_PATH overrides the default full path to the properties preset files, defaults to \p MLT_DATA/presets - * \event \em producer-create-request fired when mlt_factory_producer is called - * \event \em producer-create-done fired when a producer registers itself - * \event \em filter-create-request fired when mlt_factory_filter is called - * \event \em filter-create-done fired when a filter registers itself - * \event \em transition-create-request fired when mlt_factory_transition is called - * \event \em transition-create-done fired when a transition registers itself - * \event \em consumer-create-request fired when mlt_factory_consumer is called - * \event \em consumer-create-done fired when a consumer registers itself + * \event \em producer-create-request fired when mlt_factory_producer is called; + * the event data is a pointer to mlt_factory_event_data + * \event \em producer-create-done fired when a producer registers itself; + * the event data is a pointer to mlt_factory_event_data + * \event \em filter-create-request fired when mlt_factory_filter is called; + * the event data is a pointer to mlt_factory_event_data + * \event \em filter-create-done fired when a filter registers itself; + * the event data is a pointer to mlt_factory_event_data + * \event \em transition-create-request fired when mlt_factory_transition is called; + * the event data is a pointer to mlt_factory_event_data + * \event \em transition-create-done fired when a transition registers itself; + * the event data is a pointer to mlt_factory_event_data + * \event \em consumer-create-request fired when mlt_factory_consumer is called; + * the event data is a pointer to mlt_factory_event_data + * \event \em consumer-create-done fired when a consumer registers itself; + * the event data is a pointer to mlt_factory_event_data + * \event \em link-create-request fired when mlt_factory_link is called; + * the event data is a pointer to mlt_factory_event_data + * \event \em link-create-done fired when a link registers itself; + * the event data is a pointer to mlt_factory_event_data */ extern mlt_repository mlt_factory_init( const char *directory ); @@ -60,4 +72,12 @@ extern void mlt_factory_register_for_clean_up( void *ptr, mlt_destructor destruc extern void mlt_factory_close( ); extern mlt_properties mlt_global_properties( ); +/** The event data for all factory-related events */ + +typedef struct { + const char *name; /**< the name of the service requested */ + const void *input; /**< an argument supplied to initialize the service, typically a string */ + void *service; /**< the service being created */ +} mlt_factory_event_data; + #endif diff --git a/src/framework/mlt_field.c b/src/framework/mlt_field.c index 79ff773a5..4e3425e71 100644 --- a/src/framework/mlt_field.c +++ b/src/framework/mlt_field.c @@ -183,7 +183,7 @@ int mlt_field_plant_filter( mlt_field self, mlt_filter that, int track ) mlt_tractor_connect( self->tractor, self->producer ); // Fire an event - mlt_events_fire( mlt_field_properties( self ), "service-changed", NULL ); + mlt_events_fire( mlt_field_properties( self ), "service-changed", mlt_event_data_none() ); } return result; @@ -214,7 +214,7 @@ int mlt_field_plant_transition( mlt_field self, mlt_transition that, int a_track mlt_tractor_connect( self->tractor, self->producer ); // Fire an event - mlt_events_fire( mlt_field_properties( self ), "service-changed", NULL ); + mlt_events_fire( mlt_field_properties( self ), "service-changed", mlt_event_data_none() ); } return result; @@ -265,5 +265,5 @@ void mlt_field_disconnect_service( mlt_field self, mlt_service service ) default: break; } - mlt_events_fire( mlt_field_properties( self ), "service-changed", NULL ); + mlt_events_fire( mlt_field_properties( self ), "service-changed", mlt_event_data_none() ); } diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c index a13e5c25b..0359ab167 100644 --- a/src/framework/mlt_playlist.c +++ b/src/framework/mlt_playlist.c @@ -3,7 +3,7 @@ * \brief playlist service class * \see mlt_playlist_s * - * Copyright (C) 2003-2017 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -52,7 +52,6 @@ struct playlist_entry_s static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ); static int mlt_playlist_unmix( mlt_playlist self, int clip ); static int mlt_playlist_resize_mix( mlt_playlist self, int clip, int in, int out ); -static void mlt_playlist_next( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ); /** Construct a playlist. * @@ -99,7 +98,7 @@ mlt_playlist mlt_playlist_init( ) self->list = calloc( self->size, sizeof( playlist_entry * ) ); if ( self->list == NULL ) goto error2; - mlt_events_register( MLT_PLAYLIST_PROPERTIES( self ), "playlist-next", (mlt_transmitter) mlt_playlist_next ); + mlt_events_register( MLT_PLAYLIST_PROPERTIES( self ), "playlist-next" ); } return self; @@ -395,24 +394,6 @@ static mlt_producer mlt_playlist_locate( mlt_playlist self, mlt_position *positi return producer; } -/** The transmitter for the producer-next event - * - * Invokes the listener. - * - * \private \memberof mlt_playlist_s - * \param listener a function pointer that will be invoked - * \param owner the events object that will be passed to \p listener - * \param self a service that will be passed to \p listener - * \param args an array of pointers. - */ - -static void mlt_playlist_next( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener ) - listener( owner, self, args[ 0 ] ); -} - - /** Seek in the virtual playlist. * * This gets the producer at the current position and seeks on the producer @@ -501,8 +482,9 @@ static mlt_service mlt_playlist_virtual_seek( mlt_playlist self, int *progressiv } // Determine if we have moved to the next entry in the playlist. - if ( original == total - 2 ) - mlt_events_fire( properties, "playlist-next", i, NULL ); + if ( original == total - 2 ) { + mlt_events_fire(properties, "playlist-next", mlt_event_data_from_int(i)); + } return MLT_PRODUCER_SERVICE( producer ); } diff --git a/src/framework/mlt_playlist.h b/src/framework/mlt_playlist.h index b5d813345..784e517dd 100644 --- a/src/framework/mlt_playlist.h +++ b/src/framework/mlt_playlist.h @@ -66,7 +66,7 @@ typedef struct playlist_entry_s playlist_entry; * 2 to hide the audio (make it a video-only track), or 3 to hide audio and video (hidden track). * This property only applies when using a multitrack or transition. * \event \em playlist-next The playlist fires this when it moves to the next item in the list. - * The listener receives one argument that is the index of the entry that just completed. + * The event data is an integer of the index of the entry that just completed. */ struct mlt_playlist_s diff --git a/src/framework/mlt_producer.c b/src/framework/mlt_producer.c index 582e112ab..5a82f6a51 100644 --- a/src/framework/mlt_producer.c +++ b/src/framework/mlt_producer.c @@ -3,7 +3,7 @@ * \brief abstraction for all producer services * \see mlt_producer_s * - * Copyright (C) 2003-2019 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -38,7 +38,7 @@ /* Forward references. */ static int producer_get_frame( mlt_service self, mlt_frame_ptr frame, int index ); -static void mlt_producer_property_changed( mlt_service owner, mlt_producer self, char *name ); +static void mlt_producer_property_changed(mlt_service owner, mlt_producer self, mlt_event_data ); static void mlt_producer_service_changed( mlt_service owner, mlt_producer self ); /* for debugging */ @@ -108,7 +108,7 @@ int mlt_producer_init( mlt_producer self, void *child ) mlt_events_listen( properties, self, "service-changed", ( mlt_listener )mlt_producer_service_changed ); mlt_events_listen( properties, self, "property-changed", ( mlt_listener )mlt_producer_property_changed ); - mlt_events_register( properties, "producer-changed", NULL ); + mlt_events_register( properties, "producer-changed" ); } } @@ -125,10 +125,12 @@ int mlt_producer_init( mlt_producer self, void *child ) * \param name the property that changed */ -static void mlt_producer_property_changed( mlt_service owner, mlt_producer self, char *name ) +static void mlt_producer_property_changed( mlt_service owner, mlt_producer self, mlt_event_data event_data) { + const char *name = mlt_event_data_to_string(event_data); + if (!name) return; if ( !strcmp( name, "in" ) || !strcmp( name, "out" ) || !strcmp( name, "length" ) ) - mlt_events_fire( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( self ) ), "producer-changed", NULL ); + mlt_events_fire( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( self ) ), "producer-changed", mlt_event_data_none() ); } /** Listener for service changes. @@ -142,7 +144,7 @@ static void mlt_producer_property_changed( mlt_service owner, mlt_producer self, static void mlt_producer_service_changed( mlt_service owner, mlt_producer self ) { - mlt_events_fire( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( self ) ), "producer-changed", NULL ); + mlt_events_fire( MLT_PRODUCER_PROPERTIES( mlt_producer_cut_parent( self ) ), "producer-changed", mlt_event_data_none() ); } /** Create and initialize a new producer. diff --git a/src/framework/mlt_properties.c b/src/framework/mlt_properties.c index f3e419b57..c8ac9faed 100644 --- a/src/framework/mlt_properties.c +++ b/src/framework/mlt_properties.c @@ -3,7 +3,7 @@ * \brief Properties class definition * \see mlt_properties_s * - * Copyright (C) 2003-2020 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -597,6 +597,11 @@ static mlt_property mlt_properties_fetch( mlt_properties self, const char *name return property; } +static void fire_property_changed(mlt_properties self, const char *name) +{ + mlt_events_fire(self, "property-changed", mlt_event_data_from_string(name)); +} + /** Copy a property to another properties list. * * \public \memberof mlt_properties_s @@ -614,7 +619,7 @@ void mlt_properties_pass_property( mlt_properties self, mlt_properties that, con return; mlt_property_pass( mlt_properties_fetch( self, name ), that_prop ); - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); } /** Copy all properties specified in a comma-separated list to another properties list. @@ -786,7 +791,7 @@ int mlt_properties_set( mlt_properties self, const char *name, const char *value mlt_properties_preset( self, value ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -848,7 +853,7 @@ int mlt_properties_set_string( mlt_properties self, const char *name, const char mlt_properties_preset( self, value ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -1051,7 +1056,7 @@ int mlt_properties_set_int( mlt_properties self, const char *name, int value ) mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -1095,7 +1100,7 @@ int mlt_properties_set_int64( mlt_properties self, const char *name, int64_t val mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -1147,7 +1152,7 @@ int mlt_properties_set_double( mlt_properties self, const char *name, double val mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -1199,7 +1204,7 @@ int mlt_properties_set_position( mlt_properties self, const char *name, mlt_posi mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -1245,7 +1250,7 @@ int mlt_properties_set_data( mlt_properties self, const char *name, void *value, if ( property != NULL ) error = mlt_property_set_data( property, value, length, destroy, serialise ); - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -2244,7 +2249,7 @@ void mlt_properties_clear( mlt_properties self, const char *name ) if ( property ) mlt_property_clear( property ); - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); } /** Check if a property exists. @@ -2405,7 +2410,7 @@ int mlt_properties_set_color( mlt_properties self, const char *name, mlt_color c mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -2467,7 +2472,7 @@ int mlt_properties_anim_set( mlt_properties self, const char *name, const char * mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -2525,7 +2530,7 @@ int mlt_properties_anim_set_int( mlt_properties self, const char *name, int valu mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -2583,7 +2588,7 @@ int mlt_properties_anim_set_double( mlt_properties self, const char *name, doubl mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -2627,7 +2632,7 @@ extern int mlt_properties_set_rect( mlt_properties self, const char *name, mlt_r mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } @@ -2681,7 +2686,7 @@ extern int mlt_properties_anim_set_rect( mlt_properties self, const char *name, mlt_properties_do_mirror( self, name ); } - mlt_events_fire( self, "property-changed", name, NULL ); + fire_property_changed(self, name); return error; } diff --git a/src/framework/mlt_properties.h b/src/framework/mlt_properties.h index 15772935b..0e2bdf437 100644 --- a/src/framework/mlt_properties.h +++ b/src/framework/mlt_properties.h @@ -31,6 +31,9 @@ * * Properties is a combination list/dictionary of name/::mlt_property pairs. * It is also a base class for many of the other MLT classes. + * + * \event \em property-changed a property's value changed; + * the event data is a string for the name of the property */ struct mlt_properties_s diff --git a/src/framework/mlt_service.c b/src/framework/mlt_service.c index 26c1e43c9..d7bad47b3 100644 --- a/src/framework/mlt_service.c +++ b/src/framework/mlt_service.c @@ -3,7 +3,7 @@ * \brief interface definition for all service classes * \see mlt_service_s * - * Copyright (C) 2003-2016 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -65,7 +65,6 @@ mlt_service_base; static void mlt_service_disconnect( mlt_service self ); static void mlt_service_connect( mlt_service self, mlt_service that ); static int service_get_frame( mlt_service self, mlt_frame_ptr frame, int index ); -static void mlt_service_property_changed( mlt_listener, mlt_properties owner, mlt_service self, void **args ); /** Initialize a service. * @@ -99,31 +98,14 @@ int mlt_service_init( mlt_service self, void *child ) self->parent.close_object = self; mlt_events_init( &self->parent ); - mlt_events_register( &self->parent, "service-changed", NULL ); - mlt_events_register( &self->parent, "property-changed", ( mlt_transmitter )mlt_service_property_changed ); + mlt_events_register( &self->parent, "service-changed" ); + mlt_events_register( &self->parent, "property-changed" ); pthread_mutex_init( &( ( mlt_service_base * )self->local )->mutex, NULL ); } return error; } -/** The transmitter for property changes. - * - * Invokes the listener. - * - * \private \memberof mlt_service_s - * \param listener a function pointer that will be invoked - * \param owner a properties list that will be passed to \p listener - * \param self a service that will be passed to \p listener - * \param args an array of pointers - the first entry is passed as a string to \p listener - */ - -static void mlt_service_property_changed( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener != NULL ) - listener( owner, self, ( char * )args[ 0 ] ); -} - /** Acquire a mutual exclusion lock on this service. * * \public \memberof mlt_service_s @@ -660,7 +642,7 @@ int mlt_service_get_frame( mlt_service self, mlt_frame_ptr frame, int index ) static void mlt_service_filter_changed( mlt_service owner, mlt_service self ) { - mlt_events_fire( MLT_SERVICE_PROPERTIES( self ), "service-changed", NULL ); + mlt_events_fire( MLT_SERVICE_PROPERTIES( self ), "service-changed", mlt_event_data_none() ); } /** The property-changed event handler. @@ -671,9 +653,9 @@ static void mlt_service_filter_changed( mlt_service owner, mlt_service self ) * \param name the name of the property that changed */ -static void mlt_service_filter_property_changed( mlt_service owner, mlt_service self, char *name ) +static void mlt_service_filter_property_changed( mlt_service owner, mlt_service self, mlt_event_data event_data ) { - mlt_events_fire( MLT_SERVICE_PROPERTIES( self ), "property-changed", name, NULL ); + mlt_events_fire(MLT_SERVICE_PROPERTIES(self), "property-changed", event_data); } /** Attach a filter. @@ -711,11 +693,11 @@ int mlt_service_attach( mlt_service self, mlt_filter filter ) mlt_properties_inc_ref( MLT_FILTER_PROPERTIES( filter ) ); base->filters[ base->filter_count ++ ] = filter; mlt_properties_set_data( props, "service", self, 0, NULL, NULL ); - mlt_events_fire( properties, "service-changed", NULL ); - mlt_events_fire( props, "service-changed", NULL ); + mlt_events_fire( properties, "service-changed", mlt_event_data_none() ); + mlt_events_fire( props, "service-changed", mlt_event_data_none() ); mlt_service cp = mlt_properties_get_data( properties, "_cut_parent", NULL ); if ( cp ) - mlt_events_fire( MLT_SERVICE_PROPERTIES(cp), "service-changed", NULL ); + mlt_events_fire( MLT_SERVICE_PROPERTIES(cp), "service-changed", mlt_event_data_none() ); mlt_events_listen( props, self, "service-changed", ( mlt_listener )mlt_service_filter_changed ); mlt_events_listen( props, self, "property-changed", ( mlt_listener )mlt_service_filter_property_changed ); } @@ -757,7 +739,7 @@ int mlt_service_detach( mlt_service self, mlt_filter filter ) base->filter_count --; mlt_events_disconnect( MLT_FILTER_PROPERTIES( filter ), self ); mlt_filter_close( filter ); - mlt_events_fire( properties, "service-changed", NULL ); + mlt_events_fire( properties, "service-changed", mlt_event_data_none() ); } } return error; @@ -815,7 +797,7 @@ int mlt_service_move_filter( mlt_service self, int from, int to ) base->filters[i] = base->filters[i + 1]; } base->filters[to] = filter; - mlt_events_fire( MLT_SERVICE_PROPERTIES(self), "service-changed", NULL ); + mlt_events_fire( MLT_SERVICE_PROPERTIES(self), "service-changed", mlt_event_data_none() ); error = 0; } } diff --git a/src/framework/mlt_service.h b/src/framework/mlt_service.h index 7442a7ee5..2d8934da3 100644 --- a/src/framework/mlt_service.h +++ b/src/framework/mlt_service.h @@ -39,7 +39,7 @@ * a filter graph or what gstreamer calls an element pipeline. * * \event \em service-changed a filter was attached or detached or a transition was connected or disconnected - * \event \em property-changed + * \event \em property-changed a property's value changed; the event data is a string for the name of the property * \properties \em mlt_type identifies the subclass * \properties \em _mlt_service_hidden a flag that indicates whether to hide the mlt_service * \properties \em mlt_service is the name of the implementation of the service diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index 3ac907e21..ced9099c4 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -234,6 +234,7 @@ typedef struct mlt_chain_s *mlt_chain; /**< pointer to Chain ob typedef void ( *mlt_destructor )( void * ); /**< pointer to destructor function */ typedef char *( *mlt_serialiser )( void *, int length );/**< pointer to serialization function */ +typedef void *( *mlt_thread_function_t )( void* ); /**< generic thread function pointer */ #define MLT_SERVICE(x) ( ( mlt_service )( x ) ) /**< Cast to a Service pointer */ #define MLT_PRODUCER(x) ( ( mlt_producer )( x ) ) /**< Cast to a Producer pointer */ diff --git a/src/melt/melt.c b/src/melt/melt.c index 667ecbfb2..f77aefeea 100644 --- a/src/melt/melt.c +++ b/src/melt/melt.c @@ -57,6 +57,11 @@ static void abnormal_exit_handler(int signum) raise( signum ); } +static void fire_jack_seek_event(mlt_properties jack, int position) +{ + mlt_events_fire(jack, "jack-seek", mlt_event_data_from_int(position)); +} + static void transport_action( mlt_producer producer, char *value ) { mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); @@ -74,14 +79,14 @@ static void transport_action( mlt_producer producer, char *value ) case 'q': case 'Q': mlt_properties_set_int( properties, "done", 1 ); - mlt_events_fire( jack, "jack-stop", NULL ); + mlt_events_fire( jack, "jack-stop", mlt_event_data_none() ); break; case '0': position = 0; mlt_producer_set_speed( producer, 1 ); mlt_producer_seek( producer, position ); mlt_consumer_purge( consumer ); - mlt_events_fire( jack, "jack-seek", &position, NULL ); + fire_jack_seek_event(jack, position); break; case '1': mlt_producer_set_speed( producer, -10 ); @@ -99,14 +104,14 @@ static void transport_action( mlt_producer producer, char *value ) mlt_producer_set_speed( producer, 0 ); mlt_consumer_purge( consumer ); mlt_producer_seek( producer, mlt_consumer_position( consumer ) + 1 ); - mlt_events_fire( jack, "jack-stop", NULL ); + mlt_events_fire( jack, "jack-stop", mlt_event_data_none() ); break; case '6': case ' ': if ( !jack || mlt_producer_get_speed( producer ) != 0 ) mlt_producer_set_speed( producer, 1 ); mlt_consumer_purge( consumer ); - mlt_events_fire( jack, "jack-start", NULL ); + mlt_events_fire( jack, "jack-start", mlt_event_data_none() ); break; case '7': mlt_producer_set_speed( producer, 2 ); @@ -140,7 +145,7 @@ static void transport_action( mlt_producer producer, char *value ) position = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 0 ); mlt_producer_seek( producer, position ); mlt_consumer_purge( consumer ); - mlt_events_fire( jack, "jack-seek", &position, NULL ); + fire_jack_seek_event(jack, position); } break; case 'H': @@ -149,7 +154,7 @@ static void transport_action( mlt_producer producer, char *value ) position -= mlt_producer_get_fps( producer ) * 60; mlt_consumer_purge( consumer ); mlt_producer_seek( producer, position ); - mlt_events_fire( jack, "jack-seek", &position, NULL ); + fire_jack_seek_event(jack, position); } break; case 'h': @@ -159,8 +164,8 @@ static void transport_action( mlt_producer producer, char *value ) mlt_producer_set_speed( producer, 0 ); mlt_consumer_purge( consumer ); mlt_producer_seek( producer, position ); - mlt_events_fire( jack, "jack-stop", NULL ); - mlt_events_fire( jack, "jack-seek", &position, NULL ); + mlt_events_fire( jack, "jack-stop", mlt_event_data_none() ); + fire_jack_seek_event(jack, position); } break; case 'j': @@ -169,7 +174,7 @@ static void transport_action( mlt_producer producer, char *value ) position = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, 1 ); mlt_consumer_purge( consumer ); mlt_producer_seek( producer, position ); - mlt_events_fire( jack, "jack-seek", &position, NULL ); + fire_jack_seek_event(jack, position); } break; case 'k': @@ -178,7 +183,7 @@ static void transport_action( mlt_producer producer, char *value ) position = mlt_multitrack_clip( multitrack, mlt_whence_relative_current, -1 ); mlt_consumer_purge( consumer ); mlt_producer_seek( producer, position ); - mlt_events_fire( jack, "jack-seek", &position, NULL ); + fire_jack_seek_event(jack, position); } break; case 'l': @@ -189,12 +194,12 @@ static void transport_action( mlt_producer producer, char *value ) if ( mlt_producer_get_speed( producer ) != 0 ) { mlt_producer_set_speed( producer, 0 ); - mlt_events_fire( jack, "jack-stop", NULL ); + mlt_events_fire( jack, "jack-stop", mlt_event_data_none() ); } else { mlt_producer_seek( producer, position ); - mlt_events_fire( jack, "jack-seek", &position, NULL ); + fire_jack_seek_event(jack, position); } } break; @@ -204,7 +209,7 @@ static void transport_action( mlt_producer producer, char *value ) position += mlt_producer_get_fps( producer ) * 60; mlt_consumer_purge( consumer ); mlt_producer_seek( producer, position ); - mlt_events_fire( jack, "jack-seek", &position, NULL ); + fire_jack_seek_event(jack, position); } break; } @@ -215,7 +220,7 @@ static void transport_action( mlt_producer producer, char *value ) mlt_properties_set_int( properties, "stats_off", 0 ); } -static void on_jack_started( mlt_properties owner, mlt_consumer consumer, mlt_position *position ) +static void on_jack_started( mlt_properties owner, mlt_consumer consumer, mlt_event_data event_data ) { mlt_producer producer = mlt_properties_get_data( MLT_CONSUMER_PROPERTIES(consumer), "transport_producer", NULL ); if ( producer ) @@ -223,26 +228,28 @@ static void on_jack_started( mlt_properties owner, mlt_consumer consumer, mlt_po if ( mlt_producer_get_speed( producer ) != 0 ) { mlt_properties jack = mlt_properties_get_data( MLT_CONSUMER_PROPERTIES( consumer ), "jack_filter", NULL ); - mlt_events_fire( jack, "jack-stop", NULL ); + mlt_events_fire( jack, "jack-stop", mlt_event_data_none() ); } else { + mlt_position position = mlt_event_data_to_int(event_data); mlt_producer_set_speed( producer, 1 ); mlt_consumer_purge( consumer ); - mlt_producer_seek( producer, *position ); + mlt_producer_seek( producer, position ); mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( consumer ), "refresh", 1 ); } } } -static void on_jack_stopped( mlt_properties owner, mlt_consumer consumer, mlt_position *position ) +static void on_jack_stopped( mlt_properties owner, mlt_consumer consumer, mlt_event_data event_data ) { mlt_producer producer = mlt_properties_get_data( MLT_CONSUMER_PROPERTIES(consumer), "transport_producer", NULL ); if ( producer ) { + mlt_position position = mlt_event_data_to_int(event_data); mlt_producer_set_speed( producer, 0 ); mlt_consumer_purge( consumer ); - mlt_producer_seek( producer, *position ); + mlt_producer_seek( producer, position ); mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( consumer ), "refresh", 1 ); } } @@ -1084,7 +1091,7 @@ int main( int argc, char **argv ) error = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( consumer ), "melt_error" ); mlt_consumer_connect( consumer, NULL ); if ( !is_abort ) - mlt_events_fire( MLT_CONSUMER_PROPERTIES(consumer), "consumer-cleanup", NULL); + mlt_events_fire( MLT_CONSUMER_PROPERTIES(consumer), "consumer-cleanup", mlt_event_data_none()); } if ( is_abort ) diff --git a/src/mlt++/MltEvent.cpp b/src/mlt++/MltEvent.cpp index e9f81b43d..c395f64c3 100644 --- a/src/mlt++/MltEvent.cpp +++ b/src/mlt++/MltEvent.cpp @@ -1,7 +1,6 @@ /** * MltEvent.cpp - MLT Wrapper - * Copyright (C) 2004-2015 Meltytech, LLC - * Author: Charles Yates + * Copyright (C) 2004-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,6 +18,7 @@ */ #include "MltEvent.h" +#include "MltFrame.h" using namespace Mlt; @@ -59,3 +59,49 @@ void Event::unblock( ) mlt_event_unblock( get_event( ) ); } + +EventData::EventData(mlt_event_data data) + : instance(data) +{ +} + +EventData::EventData(EventData& data) + : instance(data.get_event_data()) +{ +} + +EventData::EventData(const EventData& data) + : instance(data.get_event_data()) +{ +} + +EventData& EventData::operator=(const EventData& data) +{ + instance = data.get_event_data(); + return *this; +} + +mlt_event_data EventData::get_event_data() const +{ + return instance; +} + +int EventData::to_int() const +{ + return mlt_event_data_to_int(instance); +} + +const char* EventData::to_string() const +{ + return mlt_event_data_to_string(instance); +} + +Frame EventData::to_frame() const +{ + return Frame(mlt_event_data_to_frame(instance)); +} + +void* EventData::to_object() const +{ + return mlt_event_data_to_object(instance); +} diff --git a/src/mlt++/MltEvent.h b/src/mlt++/MltEvent.h index e79dc1f19..6fd543658 100644 --- a/src/mlt++/MltEvent.h +++ b/src/mlt++/MltEvent.h @@ -1,7 +1,6 @@ /** * MltEvent.h - MLT Wrapper - * Copyright (C) 2004-2015 Meltytech, LLC - * Author: Charles Yates + * Copyright (C) 2004-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -27,7 +26,9 @@ namespace Mlt { - class MLTPP_DECLSPEC Event + class Frame; + + class MLTPP_DECLSPEC Event { private: mlt_event instance; @@ -40,6 +41,23 @@ namespace Mlt void block( ); void unblock( ); }; + + class MLTPP_DECLSPEC EventData + { + private: + mlt_event_data instance; + public: + EventData(mlt_event_data); + EventData(EventData&); + EventData(const EventData&); + EventData& operator=(const EventData&); + ~EventData() {}; + mlt_event_data get_event_data() const; + int to_int() const; + const char* to_string() const; + Frame to_frame() const; + void* to_object() const; + }; } #endif diff --git a/src/mlt++/MltProperties.cpp b/src/mlt++/MltProperties.cpp index c377f900d..5114baeeb 100644 --- a/src/mlt++/MltProperties.cpp +++ b/src/mlt++/MltProperties.cpp @@ -1,6 +1,6 @@ /** * MltProperties.cpp - MLT Wrapper - * Copyright (C) 2004-2020 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -120,7 +120,7 @@ void Properties::unblock( void *object ) int Properties::fire_event( const char *event ) { - return mlt_events_fire( get_properties( ), event, NULL ); + return mlt_events_fire( get_properties( ), event, mlt_event_data_none() ); } bool Properties::is_valid( ) @@ -271,24 +271,12 @@ int Properties::save( const char *file ) return mlt_properties_save( get_properties( ), file ); } -#if defined( __APPLE__ ) && GCC_VERSION < 40000 - -Event *Properties::listen( const char *id, void *object, void (*listener)( ... ) ) -{ - mlt_event event = mlt_events_listen( get_properties( ), object, id, ( mlt_listener )listener ); - return new Event( event ); -} - -#else - Event *Properties::listen( const char *id, void *object, mlt_listener listener ) { mlt_event event = mlt_events_listen( get_properties( ), object, id, listener ); return new Event( event ); } -#endif - Event *Properties::setup_wait_for( const char *id ) { return new Event( mlt_events_setup_wait_for( get_properties( ), id ) ); diff --git a/src/mlt++/MltProperties.h b/src/mlt++/MltProperties.h index 626b553f6..e0a2341fc 100644 --- a/src/mlt++/MltProperties.h +++ b/src/mlt++/MltProperties.h @@ -1,6 +1,6 @@ /** * MltProperties.h - MLT Wrapper - * Copyright (C) 2004-2020 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -85,11 +85,7 @@ namespace Mlt void debug( const char *title = "Object", FILE *output = stderr ); void load( const char *file ); int save( const char *file ); - #if defined( __APPLE__ ) && GCC_VERSION < 40000 - Event *listen( const char *id, void *object, void (*)( ... ) ); - #else Event *listen( const char *id, void *object, mlt_listener ); - #endif static void delete_event( Event * ); Event *setup_wait_for( const char *id ); void wait_for( Event *, bool destroy = true ); diff --git a/src/mlt++/mlt++.vers b/src/mlt++/mlt++.vers index 5c8be125a..da4f6f4d2 100644 --- a/src/mlt++/mlt++.vers +++ b/src/mlt++/mlt++.vers @@ -671,5 +671,17 @@ MLTPP_7.0.0 { "Mlt::Image::init_alpha()"; "Mlt::Image::plane(int)"; "Mlt::Image::stride(int)"; + "Mlt::Properties::listen(char const*, void*, void (*)(mlt_properties_s*, void*, mlt_event_data))"; + "typeinfo name for Mlt::EventData"; + "vtable for Mlt::EventData"; + "Mlt::EventData::EventData(mlt_event_data)"; + "Mlt::EventData::EventData(Mlt::EventData&)"; + "Mlt::EventData::EventData(Mlt::EventData const&)"; + "Mlt::EventData::operator=(Mlt::EventData const&)"; + "Mlt::EventData::get_event_data() const"; + "Mlt::EventData::to_int() const"; + "Mlt::EventData::to_string() const"; + "Mlt::EventData::to_frame() const"; + "Mlt::EventData::to_object() const"; }; } MLTPP_6.22.0; diff --git a/src/modules/avformat/consumer_avformat.c b/src/modules/avformat/consumer_avformat.c index 125e0a59d..58ca8a29b 100644 --- a/src/modules/avformat/consumer_avformat.c +++ b/src/modules/avformat/consumer_avformat.c @@ -213,7 +213,7 @@ static int init_vaapi(mlt_properties properties, AVCodecContext *codec_context) #endif // Forward references. -static void property_changed( mlt_properties owner, mlt_consumer self, char *name ); +static void property_changed(mlt_properties owner, mlt_consumer self, mlt_event_data ); static int consumer_start( mlt_consumer consumer ); static int consumer_stop( mlt_consumer consumer ); static int consumer_is_stopped( mlt_consumer consumer ); @@ -267,7 +267,7 @@ mlt_consumer consumer_avformat_init( mlt_profile profile, char *arg ) consumer->stop = consumer_stop; consumer->is_stopped = consumer_is_stopped; - mlt_events_register( properties, "consumer-fatal-error", NULL ); + mlt_events_register( properties, "consumer-fatal-error" ); mlt_event event = mlt_events_listen( properties, consumer, "property-changed", ( mlt_listener )property_changed ); mlt_properties_set_data( properties, "property-changed event", event, 0, NULL, NULL ); } @@ -352,11 +352,12 @@ static void color_primaries_from_colorspace( mlt_properties properties ) } } -static void property_changed( mlt_properties owner, mlt_consumer self, char *name ) +static void property_changed( mlt_properties owner, mlt_consumer self, mlt_event_data event_data ) { mlt_properties properties = MLT_CONSUMER_PROPERTIES( self ); + const char *name = mlt_event_data_to_string(event_data); - if ( !strcmp( name, "s" ) ) + if ( name && !strcmp( name, "s" ) ) { // Obtain the size property char *size = mlt_properties_get( properties, "s" ); @@ -1189,19 +1190,19 @@ static inline long time_difference( struct timeval *time1 ) return time2.tv_sec * 1000000 + time2.tv_usec - time1->tv_sec * 1000000 - time1->tv_usec; } +typedef struct { + uint8_t *data; + size_t size; +} buffer_t; + static int mlt_write(void *h, uint8_t *buf, int size) { mlt_properties properties = (mlt_properties) h; - mlt_events_fire( properties, "avformat-write", buf, &size, NULL ); + buffer_t buffer = { buf, size }; + mlt_events_fire( properties, "avformat-write", mlt_event_data_from_object(&buffer) ); return 0; } -static void write_transmitter( mlt_listener listener, mlt_properties owner, mlt_service service, void **args ) -{ - int *p_size = (int*) args[1]; - listener( owner, service, (uint8_t*) args[0], *p_size ); -} - typedef struct encode_ctx_desc { mlt_consumer consumer; @@ -1426,7 +1427,7 @@ static int encode_audio(encode_ctx_t* ctx) if ( av_interleaved_write_frame( ctx->oc, &pkt ) ) { mlt_log_fatal( MLT_CONSUMER_SERVICE( ctx->consumer ), "error writing audio frame\n" ); - mlt_events_fire( ctx->properties, "consumer-fatal-error", NULL ); + mlt_events_fire( ctx->properties, "consumer-fatal-error", mlt_event_data_none() ); return -1; } ctx->error_count = 0; @@ -1775,7 +1776,7 @@ static void *consumer_thread( void *arg ) enc_ctx->oc->flags |= AVFMT_FLAG_CUSTOM_IO; mlt_properties_set_data( properties, "avio_buffer", buffer, buffer_size, av_free, NULL ); mlt_properties_set_data( properties, "avio_context", io, 0, av_free, NULL ); - mlt_events_register( properties, "avformat-write", (mlt_transmitter) write_transmitter ); + mlt_events_register( properties, "avformat-write" ); } else { @@ -1789,7 +1790,7 @@ static void *consumer_thread( void *arg ) if ( avio_open( &enc_ctx->oc->pb, filename, AVIO_FLAG_WRITE ) < 0 ) { mlt_log_error( MLT_CONSUMER_SERVICE( consumer ), "Could not open '%s'\n", filename ); - mlt_events_fire( properties, "consumer-fatal-error", NULL ); + mlt_events_fire( properties, "consumer-fatal-error", mlt_event_data_none() ); goto on_fatal_error; } } @@ -1799,7 +1800,7 @@ static void *consumer_thread( void *arg ) // Last check - need at least one stream if ( !enc_ctx->audio_st[0] && !enc_ctx->video_st ) { - mlt_events_fire( properties, "consumer-fatal-error", NULL ); + mlt_events_fire( properties, "consumer-fatal-error", mlt_event_data_none() ); goto on_fatal_error; } @@ -1815,7 +1816,7 @@ static void *consumer_thread( void *arg ) converted_avframe = alloc_picture( pix_fmt, width, height ); if ( !converted_avframe ) { mlt_log_error( MLT_CONSUMER_SERVICE( consumer ), "failed to allocate video AVFrame\n" ); - mlt_events_fire( properties, "consumer-fatal-error", NULL ); + mlt_events_fire( properties, "consumer-fatal-error", mlt_event_data_none() ); goto on_fatal_error; } } @@ -1834,7 +1835,7 @@ static void *consumer_thread( void *arg ) #endif } else { mlt_log_error( MLT_CONSUMER_SERVICE(consumer), "failed to allocate audio AVFrame\n" ); - mlt_events_fire( properties, "consumer-fatal-error", NULL ); + mlt_events_fire( properties, "consumer-fatal-error", mlt_event_data_none() ); goto on_fatal_error; } } @@ -1875,7 +1876,7 @@ static void *consumer_thread( void *arg ) if ( avformat_write_header( enc_ctx->oc, NULL ) < 0 ) { mlt_log_error( MLT_CONSUMER_SERVICE( consumer ), "Could not write header '%s'\n", filename ); - mlt_events_fire( properties, "consumer-fatal-error", NULL ); + mlt_events_fire( properties, "consumer-fatal-error", mlt_event_data_none() ); goto on_fatal_error; } @@ -1914,8 +1915,9 @@ static void *consumer_thread( void *arg ) sample_fifo_append( enc_ctx->fifo, pcm, samples * enc_ctx->channels * enc_ctx->sample_bytes ); total_time += ( samples * 1000000 ) / enc_ctx->frequency; } - if ( !enc_ctx->video_st ) - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + if ( !enc_ctx->video_st ) { + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); + } } // Encode the image @@ -1979,7 +1981,7 @@ static void *consumer_thread( void *arg ) converted_avframe->data, converted_avframe->linesize); sws_freeContext( context ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); // Apply the alpha if applicable if ( !mlt_properties_get( properties, "mlt_image_format" ) || @@ -2142,7 +2144,7 @@ static void *consumer_thread( void *arg ) if ( ret ) { mlt_log_fatal( MLT_CONSUMER_SERVICE(consumer), "error writing video frame: %d\n", ret ); - mlt_events_fire( properties, "consumer-fatal-error", NULL ); + mlt_events_fire( properties, "consumer-fatal-error", mlt_event_data_none() ); goto on_fatal_error; } mlt_frame_close( frame ); @@ -2252,7 +2254,7 @@ static void *consumer_thread( void *arg ) if ( av_interleaved_write_frame( enc_ctx->oc, &pkt ) != 0 ) { mlt_log_fatal( MLT_CONSUMER_SERVICE(consumer), "error writing flushed video frame\n" ); - mlt_events_fire( properties, "consumer-fatal-error", NULL ); + mlt_events_fire( properties, "consumer-fatal-error", mlt_event_data_none() ); goto on_fatal_error; } } diff --git a/src/modules/avformat/filter_avfilter.c b/src/modules/avformat/filter_avfilter.c index aef4d1e3b..9a1063a8e 100644 --- a/src/modules/avformat/filter_avfilter.c +++ b/src/modules/avformat/filter_avfilter.c @@ -1,7 +1,6 @@ /* * filter_avfilter.c -- provide various filters based on libavfilter - * Copyright (C) 2016-2020 Meltytech, LLC - * Author: Brian Matherly + * Copyright (C) 2016-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -54,9 +53,10 @@ typedef struct int reset; } private_data; -static void property_changed( mlt_service owner, mlt_filter filter, char *name ) +static void property_changed( mlt_service owner, mlt_filter filter, mlt_event_data event_data ) { - if( strncmp( PARAM_PREFIX, name, PARAM_PREFIX_LEN ) == 0 ) { + const char *name = mlt_event_data_to_string(event_data); + if( name && strncmp( PARAM_PREFIX, name, PARAM_PREFIX_LEN ) == 0 ) { private_data* pdata = (private_data*)filter->child; if( pdata->avfilter ) { diff --git a/src/modules/core/consumer_multi.c b/src/modules/core/consumer_multi.c index edebf9bed..bc1b07e52 100644 --- a/src/modules/core/consumer_multi.c +++ b/src/modules/core/consumer_multi.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011-2019 Meltytech, LLC + * Copyright (C) 2011-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -157,9 +157,9 @@ static void attach_normalisers( mlt_profile profile, mlt_service service ) create_filter( profile, service, "audioconvert", &created ); } -static void on_frame_show( void *dummy, mlt_properties properties, mlt_frame frame ) +static void on_frame_show( void *dummy, mlt_properties properties, mlt_event_data event_data ) { - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", event_data ); } static mlt_consumer generate_consumer( mlt_consumer consumer, mlt_properties props, int index ) diff --git a/src/modules/core/consumer_null.c b/src/modules/core/consumer_null.c index 9ab2ce56c..540abf08b 100644 --- a/src/modules/core/consumer_null.c +++ b/src/modules/core/consumer_null.c @@ -1,6 +1,6 @@ /* * consumer_null.c -- a null consumer - * Copyright (C) 2003-2014 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -153,7 +153,7 @@ static void *consumer_thread( void *arg ) if ( frame != NULL ) { // Close the frame - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); mlt_frame_close( frame ); } } diff --git a/src/modules/core/producer_consumer.c b/src/modules/core/producer_consumer.c index 4e2debdb9..14283c09a 100644 --- a/src/modules/core/producer_consumer.c +++ b/src/modules/core/producer_consumer.c @@ -1,6 +1,6 @@ /* * producer_consumer.c -- produce as a consumer of an encapsulated producer - * Copyright (C) 2008-2020 Meltytech, LLC + * Copyright (C) 2008-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -104,7 +104,7 @@ static int get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, return result; } -static void property_changed( mlt_properties owner, mlt_consumer self, char *name ) +static void property_changed( mlt_properties owner, mlt_consumer self, mlt_event_data event_data ) { mlt_properties properties = MLT_PRODUCER_PROPERTIES(self); context cx = mlt_properties_get_data( properties, "context", NULL ); @@ -112,11 +112,12 @@ static void property_changed( mlt_properties owner, mlt_consumer self, char *nam if ( !cx ) return; - if ( name == strstr( name, CONSUMER_PROPERTIES_PREFIX ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && name == strstr( name, CONSUMER_PROPERTIES_PREFIX ) ) mlt_properties_set(MLT_CONSUMER_PROPERTIES( cx->consumer ), name + strlen( CONSUMER_PROPERTIES_PREFIX ), mlt_properties_get( properties, name )); - if ( name == strstr( name, PRODUCER_PROPERTIES_PREFIX ) ) + if ( name && name == strstr( name, PRODUCER_PROPERTIES_PREFIX ) ) mlt_properties_set(MLT_PRODUCER_PROPERTIES( cx->producer ), name + strlen( PRODUCER_PROPERTIES_PREFIX ), mlt_properties_get( properties, name )); } diff --git a/src/modules/core/producer_timewarp.c b/src/modules/core/producer_timewarp.c index e3dcf943f..02b4a8e6e 100644 --- a/src/modules/core/producer_timewarp.c +++ b/src/modules/core/producer_timewarp.c @@ -1,7 +1,6 @@ /* * producer_timewarp.c -- modify speed and direction of a clip - * Copyright (C) 2015-2020 Meltytech, LLC - * Author: Brian Matherly + * Copyright (C) 2015-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -39,9 +38,11 @@ typedef struct // Private Functions -static void timewarp_property_changed( mlt_service owner, mlt_producer producer, char *name ) +static void timewarp_property_changed( mlt_service owner, mlt_producer producer, mlt_event_data event_data ) { private_data* pdata = (private_data*)producer->child; + const char *name = mlt_event_data_to_string(event_data); + if ( mlt_properties_get_int( pdata->clip_parameters, name ) || !strcmp( name, "length" ) || !strcmp( name, "in" ) || @@ -60,9 +61,11 @@ static void timewarp_property_changed( mlt_service owner, mlt_producer producer, } } -static void clip_property_changed( mlt_service owner, mlt_producer producer, char *name ) +static void clip_property_changed( mlt_service owner, mlt_producer producer, mlt_event_data event_data ) { private_data* pdata = (private_data*)producer->child; + const char *name = mlt_event_data_to_string(event_data); + if ( mlt_properties_get_int( pdata->clip_parameters, name ) || !strcmp( name, "length" ) || !strcmp( name, "in" ) || diff --git a/src/modules/decklink/consumer_decklink.cpp b/src/modules/decklink/consumer_decklink.cpp index 6f79f0130..cea9e279a 100644 --- a/src/modules/decklink/consumer_decklink.cpp +++ b/src/modules/decklink/consumer_decklink.cpp @@ -1,6 +1,6 @@ /* * consumer_decklink.cpp -- output through Blackmagic Design DeckLink - * Copyright (C) 2010-2018 Meltytech, LLC + * Copyright (C) 2010-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -851,7 +851,7 @@ class DeckLinkConsumer render( frame ); mlt_log_timings_end( NULL, "render" ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); // terminate on pause if ( m_terminate_on_pause && @@ -929,8 +929,9 @@ static void close( mlt_consumer consumer ) extern "C" { // Listen for the list_devices property to be set -static void on_property_changed( void*, mlt_properties properties, const char *name ) +static void on_property_changed( void*, mlt_properties properties, mlt_event_data event_data ) { + const char *name = mlt_event_data_to_string(event_data); IDeckLinkIterator* decklinkIterator = NULL; IDeckLink* decklink = NULL; IDeckLinkInput* decklinkOutput = NULL; diff --git a/src/modules/decklink/producer_decklink.cpp b/src/modules/decklink/producer_decklink.cpp index 089c05521..10e1287f6 100644 --- a/src/modules/decklink/producer_decklink.cpp +++ b/src/modules/decklink/producer_decklink.cpp @@ -1,6 +1,6 @@ /* * producer_decklink.c -- input from Blackmagic Design DeckLink - * Copyright (C) 2011-2019 Meltytech, LLC + * Copyright (C) 2011-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -793,8 +793,9 @@ static void producer_close( mlt_producer producer ) extern "C" { // Listen for the list_devices property to be set -static void on_property_changed( void*, mlt_properties properties, const char *name ) +static void on_property_changed( void*, mlt_properties properties, mlt_event_data event_data ) { + const char *name = mlt_event_data_to_string(event_data); IDeckLinkIterator* decklinkIterator = NULL; IDeckLink* decklink = NULL; IDeckLinkInput* decklinkInput = NULL; diff --git a/src/modules/gdk/producer_pango.c b/src/modules/gdk/producer_pango.c index ead6e9123..d0f0a1908 100644 --- a/src/modules/gdk/producer_pango.c +++ b/src/modules/gdk/producer_pango.c @@ -180,7 +180,7 @@ mlt_producer producer_pango_init( const char *filename ) // Get the properties interface mlt_properties properties = MLT_PRODUCER_PROPERTIES( &self->parent ); - mlt_events_register( properties, "fontmap-reload", NULL ); + mlt_events_register( properties, "fontmap-reload" ); mlt_events_listen( properties, producer, "fontmap-reload", (mlt_listener) on_fontmap_reload ); // Set the default properties diff --git a/src/modules/gdk/producer_pango.yml b/src/modules/gdk/producer_pango.yml index 5ea0dc945..d270e4423 100644 --- a/src/modules/gdk/producer_pango.yml +++ b/src/modules/gdk/producer_pango.yml @@ -33,7 +33,7 @@ notes: > { mlt_profile profile = mlt_profile_init("dv_pal"); mlt_producer producer = mlt_factory_producer(profile, "pango", NULL); - mlt_events_fire(mlt_producer_properties(producer), "fontmap-reload", NULL, NULL ); + mlt_events_fire(mlt_producer_properties(producer), "fontmap-reload", NULL ); mlt_producer_close(producer); mlt_profile_close(profile); }; diff --git a/src/modules/gdk/producer_pixbuf.c b/src/modules/gdk/producer_pixbuf.c index 1ff7ca48c..bfa74ec73 100644 --- a/src/modules/gdk/producer_pixbuf.c +++ b/src/modules/gdk/producer_pixbuf.c @@ -1,6 +1,6 @@ /* * producer_pixbuf.c -- raster image loader based upon gdk-pixbuf - * Copyright (C) 2003-2018 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -82,9 +82,10 @@ static void refresh_length( mlt_properties properties, producer_pixbuf self ) } } -static void on_property_changed( mlt_service owner, mlt_producer producer, char *name ) +static void on_property_changed( mlt_service owner, mlt_producer producer, mlt_event_data event_data ) { - if ( !strcmp( name, "ttl" ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && !strcmp( name, "ttl" ) ) refresh_length( MLT_PRODUCER_PROPERTIES(producer), producer->child ); } diff --git a/src/modules/jackrack/consumer_jack.c b/src/modules/jackrack/consumer_jack.c index ac65db749..ba12a182e 100644 --- a/src/modules/jackrack/consumer_jack.c +++ b/src/modules/jackrack/consumer_jack.c @@ -1,6 +1,6 @@ /* * consumer_jack.c -- a JACK audio consumer - * Copyright (C) 2011-2020 Meltytech, LLC + * Copyright (C) 2011-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -64,7 +64,7 @@ static int consumer_stop( mlt_consumer parent ); static int consumer_is_stopped( mlt_consumer parent ); static void consumer_close( mlt_consumer parent ); static void *consumer_thread( void * ); -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, char *name ); +static void consumer_refresh_cb(mlt_consumer sdl, mlt_consumer parent, mlt_event_data ); static int jack_process( jack_nframes_t frames, void * data ); /** Constructor @@ -140,8 +140,9 @@ mlt_consumer consumer_jack_init( mlt_profile profile, mlt_service_type type, con return NULL; } -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, char *name ) +static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, mlt_event_data event_data ) { + const char *name = mlt_event_data_to_string(event_data); if ( !strcmp( name, "refresh" ) ) { consumer_jack self = parent->child; @@ -362,8 +363,9 @@ static int consumer_play_video( consumer_jack self, mlt_frame frame ) { // Get the properties of this consumer mlt_properties properties = MLT_CONSUMER_PROPERTIES( &self->parent ); - if ( self->running && !mlt_consumer_is_stopped( &self->parent ) ) - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + if ( self->running && !mlt_consumer_is_stopped( &self->parent ) ) { + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); + } return 0; } diff --git a/src/modules/jackrack/filter_jackrack.c b/src/modules/jackrack/filter_jackrack.c index 91b7b2139..a8eee502c 100644 --- a/src/modules/jackrack/filter_jackrack.c +++ b/src/modules/jackrack/filter_jackrack.c @@ -1,6 +1,6 @@ /* * filter_jackrack.c -- filter audio through Jack and/or LADSPA plugins - * Copyright (C) 2004-2014 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * 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 @@ -34,22 +34,6 @@ extern pthread_mutex_t g_activate_mutex; #define BUFFER_LEN 204800 * 6 - -static void jack_started_transmitter( mlt_listener listener, mlt_properties owner, mlt_service service, void **args ) -{ - listener( owner, service, (mlt_position*) args[0] ); -} - -static void jack_stopped_transmitter( mlt_listener listener, mlt_properties owner, mlt_service service, void **args ) -{ - listener( owner, service, (mlt_position*) args[0] ); -} - -static void jack_seek_transmitter( mlt_listener listener, mlt_properties owner, mlt_service service, void **args ) -{ - listener( owner, service, (mlt_position*) args[0] ); -} - #define JACKSTATE(x) (x==JackTransportStopped?"stopped":x==JackTransportStarting?"starting":x==JackTransportRolling?"rolling":"unknown") static int jack_sync( jack_transport_state_t state, jack_position_t *jack_pos, void *arg ) @@ -65,7 +49,7 @@ static int jack_sync( jack_transport_state_t state, jack_position_t *jack_pos, v mlt_properties_get_position( properties, "_last_pos" ) ); if ( state == JackTransportStopped ) { - mlt_events_fire( properties, "jack-stopped", &position, NULL ); + mlt_events_fire( properties, "jack-stopped", mlt_event_data_from_int(position) ); mlt_properties_set_int( properties, "_sync_guard", 0 ); } else if ( state == JackTransportStarting ) @@ -74,7 +58,7 @@ static int jack_sync( jack_transport_state_t state, jack_position_t *jack_pos, v if ( !mlt_properties_get_int( properties, "_sync_guard" ) ) { mlt_properties_set_int( properties, "_sync_guard", 1 ); - mlt_events_fire( properties, "jack-started", &position, NULL ); + mlt_events_fire( properties, "jack-started", mlt_event_data_from_int(position) ); } else if ( position >= mlt_properties_get_position( properties, "_last_pos" ) - 2 ) { @@ -104,15 +88,16 @@ static void on_jack_stop( mlt_properties owner, mlt_properties properties ) jack_transport_stop( jack_client ); } -static void on_jack_seek( mlt_properties owner, mlt_filter filter, mlt_position *position ) +static void on_jack_seek( mlt_properties owner, mlt_filter filter, mlt_event_data event_data ) { + mlt_position position = mlt_event_data_to_int(event_data); mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - mlt_log_verbose( MLT_FILTER_SERVICE(filter), "%s: %d\n", __FUNCTION__, *position ); + mlt_log_verbose( MLT_FILTER_SERVICE(filter), "%s: %d\n", __FUNCTION__, position ); mlt_properties_set_int( properties, "_sync_guard", 1 ); mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) ); jack_client_t *jack_client = mlt_properties_get_data( properties, "jack_client", NULL ); jack_nframes_t jack_frame = jack_get_sample_rate( jack_client ); - jack_frame *= *position / mlt_profile_fps( profile ); + jack_frame *= position / mlt_profile_fps( profile ); jack_transport_locate( jack_client, jack_frame ); } @@ -461,11 +446,11 @@ mlt_filter filter_jackrack_init( mlt_profile profile, mlt_service_type type, con mlt_properties_set_int( properties, "_sync", 1 ); mlt_properties_set_int( properties, "channels", 2 ); - mlt_events_register( properties, "jack-started", (mlt_transmitter) jack_started_transmitter ); - mlt_events_register( properties, "jack-stopped", (mlt_transmitter) jack_stopped_transmitter ); - mlt_events_register( properties, "jack-start", NULL ); - mlt_events_register( properties, "jack-stop", NULL ); - mlt_events_register( properties, "jack-seek", (mlt_transmitter) jack_seek_transmitter ); + mlt_events_register( properties, "jack-started" ); + mlt_events_register( properties, "jack-stopped" ); + mlt_events_register( properties, "jack-start" ); + mlt_events_register( properties, "jack-stop" ); + mlt_events_register( properties, "jack-seek" ); mlt_events_listen( properties, properties, "jack-start", (mlt_listener) on_jack_start ); mlt_events_listen( properties, properties, "jack-stop", (mlt_listener) on_jack_stop ); mlt_events_listen( properties, this, "jack-seek", (mlt_listener) on_jack_seek ); diff --git a/src/modules/ndi/consumer_ndi.c b/src/modules/ndi/consumer_ndi.c index 012ea3fc9..df3003de0 100644 --- a/src/modules/ndi/consumer_ndi.c +++ b/src/modules/ndi/consumer_ndi.c @@ -238,7 +238,7 @@ static void* consumer_ndi_feeder( void* p ) last = frame; } - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); } NDIlib_send_destroy( ndi_send ); diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index b28cdb5ca..1e82f865a 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -39,11 +39,13 @@ typedef struct } private_data; -static void property_changed( mlt_service owner, mlt_filter filter, char *name ) +static void property_changed( mlt_service owner, mlt_filter filter, mlt_event_data event_data ) { private_data* pdata = (private_data*)filter->child; mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - if ( !strcmp( name, "results" ) ) + const char *name = mlt_event_data_to_string(event_data); + + if ( name && !strcmp( name, "results" ) ) { mlt_properties_anim_get_int( filter_properties, "results", 0, -1 ); mlt_animation anim = mlt_properties_get_animation( filter_properties, "results" ); diff --git a/src/modules/opengl/consumer_xgl.c b/src/modules/opengl/consumer_xgl.c index 76f7a16e3..3c6af4f42 100644 --- a/src/modules/opengl/consumer_xgl.c +++ b/src/modules/opengl/consumer_xgl.c @@ -220,7 +220,7 @@ static void show_frame() glEnd(); glBindFramebuffer( GL_FRAMEBUFFER, 0 ); - mlt_events_fire( MLT_CONSUMER_PROPERTIES(&xgl->parent), "consumer-frame-show", new_frame.mlt_frame_ref, NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES(&xgl->parent), "consumer-frame-show", mlt_event_data_from_frame(new_frame.mlt_frame_ref) ); mlt_frame_close( new_frame.mlt_frame_ref ); new_frame.mlt_frame_ref = NULL; @@ -524,7 +524,7 @@ static void on_consumer_thread_started( mlt_properties owner, HiddenContext* con { // Initialize this thread's OpenGL state glXMakeCurrent( context->dpy, context->win, context->ctx ); - mlt_events_fire( MLT_FILTER_PROPERTIES(glsl_manager), "init glsl", NULL ); + mlt_events_fire( MLT_FILTER_PROPERTIES(glsl_manager), "init glsl", mlt_event_data_none() ); } /** Forward references to static functions. diff --git a/src/modules/opengl/filter_glsl_manager.cpp b/src/modules/opengl/filter_glsl_manager.cpp index f2f4ec61e..0ce8bfd2d 100644 --- a/src/modules/opengl/filter_glsl_manager.cpp +++ b/src/modules/opengl/filter_glsl_manager.cpp @@ -70,8 +70,8 @@ GlslManager::GlslManager() filter->child = this; add_ref(mlt_global_properties()); - mlt_events_register( get_properties(), "init glsl", NULL ); - mlt_events_register( get_properties(), "close glsl", NULL ); + mlt_events_register( get_properties(), "init glsl" ); + mlt_events_register( get_properties(), "close glsl" ); initEvent = listen("init glsl", this, (mlt_listener) GlslManager::onInit); closeEvent = listen("close glsl", this, (mlt_listener) GlslManager::onClose); } @@ -235,7 +235,7 @@ void GlslManager::cleanupContext() unlock(); } -void GlslManager::onInit( mlt_properties owner, GlslManager* filter ) +void GlslManager::onInit( mlt_properties owner, GlslManager* filter, mlt_event_data ) { mlt_log_debug( filter->get_service(), "%s\n", __FUNCTION__ ); #ifdef _WIN32 @@ -249,7 +249,7 @@ void GlslManager::onInit( mlt_properties owner, GlslManager* filter ) filter->set( "glsl_supported", success ); } -void GlslManager::onClose( mlt_properties owner, GlslManager *filter ) +void GlslManager::onClose( mlt_properties owner, GlslManager *filter, mlt_event_data ) { filter->cleanupContext(); } diff --git a/src/modules/opengl/filter_glsl_manager.h b/src/modules/opengl/filter_glsl_manager.h index 0c365ef8b..f416cfbcb 100644 --- a/src/modules/opengl/filter_glsl_manager.h +++ b/src/modules/opengl/filter_glsl_manager.h @@ -129,8 +129,8 @@ class GlslManager : public Mlt::Filter static void* get_frame_specific_data( mlt_service service, mlt_frame frame, const char *key, int *length ); static int set_frame_specific_data( mlt_service service, mlt_frame frame, const char *key, void *value, int length, mlt_destructor destroy, mlt_serialiser serialise ); - static void onInit( mlt_properties owner, GlslManager* filter ); - static void onClose( mlt_properties owner, GlslManager* filter ); + static void onInit(mlt_properties owner, GlslManager* filter, mlt_event_data ); + static void onClose( mlt_properties owner, GlslManager* filter, mlt_event_data ); static void onServiceChanged( mlt_properties owner, mlt_service service ); static void onPropertyChanged( mlt_properties owner, mlt_service service, const char* property ); movit::ResourcePool* resource_pool; diff --git a/src/modules/plus/consumer_blipflash.c b/src/modules/plus/consumer_blipflash.c index 7414df7fb..00aec25f4 100644 --- a/src/modules/plus/consumer_blipflash.c +++ b/src/modules/plus/consumer_blipflash.c @@ -387,7 +387,7 @@ static void *consumer_thread( void *arg ) report_results( stats, pos ); // Close the frame - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); mlt_frame_close( frame ); } } diff --git a/src/modules/plus/filter_dynamic_loudness.c b/src/modules/plus/filter_dynamic_loudness.c index 99c830514..85a02bd62 100644 --- a/src/modules/plus/filter_dynamic_loudness.c +++ b/src/modules/plus/filter_dynamic_loudness.c @@ -35,10 +35,11 @@ typedef struct mlt_position prev_o_pos; } private_data; -static void property_changed( mlt_service owner, mlt_filter filter, char *name ) +static void property_changed( mlt_service owner, mlt_filter filter, mlt_event_data event_data ) { + const char *name = mlt_event_data_to_string(event_data); private_data* pdata = (private_data*)filter->child; - if ( !strcmp( name, "window" ) ) + if ( name && pdata && !strcmp( name, "window" ) ) { pdata->reset = 1; } diff --git a/src/modules/plus/filter_loudness_meter.c b/src/modules/plus/filter_loudness_meter.c index 6c81d19f7..0247cc362 100644 --- a/src/modules/plus/filter_loudness_meter.c +++ b/src/modules/plus/filter_loudness_meter.c @@ -31,16 +31,17 @@ typedef struct mlt_position prev_pos; } private_data; -static void property_changed( mlt_service owner, mlt_filter filter, char *name ) +static void property_changed( mlt_service owner, mlt_filter filter, mlt_event_data event_data ) { + const char *name = mlt_event_data_to_string(event_data); private_data* pdata = (private_data*)filter->child; - if ( !strcmp( name, "reset" ) || + if ( name && pdata && ( !strcmp( name, "reset" ) || !strcmp( name, "calc_program" ) || !strcmp( name, "calc_shortterm" ) || !strcmp( name, "calc_momentary" ) || !strcmp( name, "calc_range" ) || !strcmp( name, "calc_peak" ) || - !strcmp( name, "calc_true_peak" ) ) + !strcmp( name, "calc_true_peak" ) ) ) { pdata->reset = 1; } diff --git a/src/modules/plus/filter_text.c b/src/modules/plus/filter_text.c index 71eb86e6a..1d6a888de 100644 --- a/src/modules/plus/filter_text.c +++ b/src/modules/plus/filter_text.c @@ -1,6 +1,6 @@ /* * filter_text.c -- text overlay filter - * Copyright (C) 2018-2019 Meltytech, LLC + * Copyright (C) 2018-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,8 +21,10 @@ #include #include -static void property_changed( mlt_service owner, mlt_filter filter, char *name ) +static void property_changed( mlt_service owner, mlt_filter filter, mlt_event_data event_data ) { + const char *name = mlt_event_data_to_string(event_data); + if (!name) return; if( !strcmp( "geometry", name ) || !strcmp( "family", name ) || !strcmp( "size", name ) || diff --git a/src/modules/plusgpl/consumer_cbrts.c b/src/modules/plusgpl/consumer_cbrts.c index 1e0e95281..9a9a64d20 100644 --- a/src/modules/plusgpl/consumer_cbrts.c +++ b/src/modules/plusgpl/consumer_cbrts.c @@ -132,8 +132,14 @@ typedef struct { uint8_t data[4096]; } ts_section; +typedef struct { + uint8_t *data; + size_t size; +} buffer_t; + static uint8_t null_packet[ TSP_BYTES ]; + /** Forward references to static functions. */ @@ -142,7 +148,7 @@ static int consumer_stop( mlt_consumer parent ); static int consumer_is_stopped( mlt_consumer parent ); static void consumer_close( mlt_consumer parent ); static void *consumer_thread( void * ); -static void on_data_received( mlt_properties properties, mlt_consumer consumer, uint8_t *buf, int size ); +static void on_data_received(mlt_properties properties, mlt_consumer consumer, mlt_event_data ); mlt_consumer consumer_cbrts_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) { @@ -993,8 +999,11 @@ static void filter_remux_or_write_packet( consumer_cbrts self, uint8_t *packet ) } } -static void on_data_received( mlt_properties properties, mlt_consumer consumer, uint8_t *buf, int size ) +static void on_data_received( mlt_properties properties, mlt_consumer consumer, mlt_event_data event_data ) { + buffer_t *buffer = mlt_event_data_to_object(event_data); + uint8_t *buf = buffer->data; + size_t size = buffer->size; if ( size > 0 ) { consumer_cbrts self = (consumer_cbrts) consumer->child; diff --git a/src/modules/plusgpl/filter_rotoscoping.c b/src/modules/plusgpl/filter_rotoscoping.c index fe05eb2ed..298c75b5a 100644 --- a/src/modules/plusgpl/filter_rotoscoping.c +++ b/src/modules/plusgpl/filter_rotoscoping.c @@ -64,9 +64,10 @@ static int stringValue( const char *string, const char **stringList, int max ) /** Sets "spline_is_dirty" to 1 if property "spline" was changed. * We then know when to parse the json stored in "spline" */ -static void rotoPropertyChanged( mlt_service owner, mlt_filter this, char *name ) +static void rotoPropertyChanged( mlt_service owner, mlt_filter this, mlt_event_data event_data ) { - if ( !strcmp( name, "spline" ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && !strcmp( name, "spline" ) ) mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "_spline_is_dirty", 1 ); } diff --git a/src/modules/qt/consumer_qglsl.cpp b/src/modules/qt/consumer_qglsl.cpp index ca0cf3833..592c2f231 100644 --- a/src/modules/qt/consumer_qglsl.cpp +++ b/src/modules/qt/consumer_qglsl.cpp @@ -1,6 +1,6 @@ /* * consumer_qglsl.cpp - * Copyright (C) 2012-2014 Dan Dennedy + * Copyright (C) 2012-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -123,19 +123,20 @@ class RenderThread : public QThread QOffscreenSurface* m_surface; }; -static void onThreadCreate(mlt_properties owner, mlt_consumer self, - RenderThread** thread, int* priority, thread_function_t function, void* data ) +static void onThreadCreate(mlt_properties owner, mlt_consumer self, mlt_event_data event_data ) { Q_UNUSED(owner) - Q_UNUSED(priority) - (*thread) = new RenderThread(function, data); - (*thread)->start(); + mlt_event_data_thread* t = (mlt_event_data_thread*) mlt_event_data_to_object(event_data); + auto thread = new RenderThread((thread_function_t) t->function, t->data); + *t->thread = thread; + thread->start(); } -static void onThreadJoin(mlt_properties owner, mlt_consumer self, RenderThread* thread) +static void onThreadJoin(mlt_properties owner, mlt_consumer self, mlt_event_data event_data) { Q_UNUSED(owner) Q_UNUSED(self) + auto thread = (RenderThread*) mlt_event_data_to_object(event_data); if (thread) { thread->quit(); thread->wait(); @@ -160,11 +161,11 @@ static void onThreadStarted(mlt_properties owner, mlt_consumer consumer) #else { #endif - mlt_events_fire(filter_properties, "init glsl", NULL); + mlt_events_fire(filter_properties, "init glsl", mlt_event_data_none()); if (!mlt_properties_get_int(filter_properties, "glsl_supported")) { mlt_log_fatal(service, "OpenGL Shading Language rendering is not supported on this machine.\n" ); - mlt_events_fire(properties, "consumer-fatal-error", NULL); + mlt_events_fire(properties, "consumer-fatal-error", mlt_event_data_none()); } } } @@ -173,7 +174,7 @@ static void onThreadStopped(mlt_properties owner, mlt_consumer consumer) { mlt_properties properties = MLT_CONSUMER_PROPERTIES(consumer); mlt_filter filter = (mlt_filter) mlt_properties_get_data(properties, "glslManager", NULL); - mlt_events_fire(MLT_FILTER_PROPERTIES(filter), "close glsl", NULL); + mlt_events_fire(MLT_FILTER_PROPERTIES(filter), "close glsl", mlt_event_data_none()); } static void onCleanup(mlt_properties owner, mlt_consumer consumer) @@ -196,7 +197,7 @@ mlt_consumer consumer_qglsl_init( mlt_profile profile, mlt_service_type type, co if (filter) { mlt_properties properties = MLT_CONSUMER_PROPERTIES(consumer); mlt_properties_set_data(properties, "glslManager", filter, 0, (mlt_destructor) mlt_filter_close, NULL); - mlt_events_register( properties, "consumer-cleanup", NULL ); + mlt_events_register( properties, "consumer-cleanup" ); mlt_events_listen(properties, consumer, "consumer-thread-started", (mlt_listener) onThreadStarted); mlt_events_listen(properties, consumer, "consumer-thread-stopped", (mlt_listener) onThreadStopped); mlt_events_listen(properties, consumer, "consumer-cleanup", (mlt_listener) onCleanup); diff --git a/src/modules/qt/filter_audiowaveform.cpp b/src/modules/qt/filter_audiowaveform.cpp index c1d44ac41..bdaf634ad 100644 --- a/src/modules/qt/filter_audiowaveform.cpp +++ b/src/modules/qt/filter_audiowaveform.cpp @@ -1,7 +1,6 @@ /* * filter_audiowaveform.cpp -- audio waveform visualization filter - * Copyright (c) 2015-2020 Meltytech, LLC - * Author: Brian Matherly + * Copyright (c) 2015-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -69,9 +68,10 @@ static void destory_save_buffer( void* ptr ) free( buff ); } -static void property_changed( mlt_service owner, mlt_filter filter, char *name ) +static void property_changed( mlt_service owner, mlt_filter filter, mlt_event_data event_data ) { - if ( !strcmp( name, "window" ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && !strcmp( name, "window" ) ) { private_data* pdata = (private_data*)filter->child; pdata->reset_window = 1; diff --git a/src/modules/qt/producer_qimage.c b/src/modules/qt/producer_qimage.c index fe5077467..0815a5cf8 100644 --- a/src/modules/qt/producer_qimage.c +++ b/src/modules/qt/producer_qimage.c @@ -1,5 +1,6 @@ /* * producer_image.c -- a QT/QImage based producer for MLT + * Copyright (C) 2006-2021 Meltytech, LLC * * 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 @@ -45,9 +46,10 @@ static void refresh_length( mlt_properties properties, producer_qimage self ) } } -static void on_property_changed( mlt_service owner, mlt_producer producer, char *name ) +static void on_property_changed( mlt_service owner, mlt_producer producer, mlt_event_data event_data ) { - if ( !strcmp( name, "ttl" ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && !strcmp( name, "ttl" ) ) refresh_length( MLT_PRODUCER_PROPERTIES(producer), producer->child ); } diff --git a/src/modules/qt/qimage_wrapper.cpp b/src/modules/qt/qimage_wrapper.cpp index 8cf5838c1..01b2b8a0b 100644 --- a/src/modules/qt/qimage_wrapper.cpp +++ b/src/modules/qt/qimage_wrapper.cpp @@ -1,5 +1,6 @@ /* * qimage_wrapper.cpp -- a QT/QImage based producer for MLT + * Copyright (C) 2006-2021 Meltytech, LLC * * 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 diff --git a/src/modules/qt/qimage_wrapper.h b/src/modules/qt/qimage_wrapper.h index cfb0860e1..d15fdee56 100644 --- a/src/modules/qt/qimage_wrapper.h +++ b/src/modules/qt/qimage_wrapper.h @@ -1,5 +1,6 @@ /* * qimage_wrapper.h -- a QT/QImage based producer for MLT + * Copyright (C) 2006-2021 Meltytech, LLC * * 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 diff --git a/src/modules/rtaudio/consumer_rtaudio.cpp b/src/modules/rtaudio/consumer_rtaudio.cpp index 722362383..1cc147c39 100644 --- a/src/modules/rtaudio/consumer_rtaudio.cpp +++ b/src/modules/rtaudio/consumer_rtaudio.cpp @@ -1,6 +1,6 @@ /* * consumer_rtaudio.c -- output through RtAudio audio wrapper - * Copyright (C) 2011-2020 Meltytech, LLC + * Copyright (C) 2011-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,7 +28,7 @@ #include #endif -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer consumer, char *name ); +static void consumer_refresh_cb(mlt_consumer sdl, mlt_consumer consumer, mlt_event_data ); static int rtaudio_callback( void *outputBuffer, void *inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void *userData ); static void *consumer_thread_proxy( void *arg ); @@ -665,8 +665,9 @@ class RtAudioConsumer { // Get the properties of this consumer mlt_properties properties = MLT_CONSUMER_PROPERTIES( getConsumer() ); - if ( running && !mlt_consumer_is_stopped( getConsumer() ) ) - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + if ( running && !mlt_consumer_is_stopped( getConsumer() ) ) { + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); + } return 0; } @@ -760,9 +761,10 @@ class RtAudioConsumer }; -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer consumer, char *name ) +static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer consumer, mlt_event_data event_data ) { - if ( !strcmp( name, "refresh" ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && !strcmp( name, "refresh" ) ) { RtAudioConsumer* rtaudio = (RtAudioConsumer*) consumer->child; pthread_mutex_lock( &rtaudio->refresh_mutex ); diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index c24bc2116..c1ded3cf0 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -1,6 +1,6 @@ /* * consumer_sdl.c -- A Simple DirectMedia Layer consumer - * Copyright (C) 2003-2019 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -156,7 +156,7 @@ mlt_consumer consumer_sdl_init( mlt_profile profile, mlt_service_type type, cons parent->purge = consumer_purge; // Register specific events - mlt_events_register( self->properties, "consumer-sdl-event", ( mlt_transmitter )consumer_sdl_event ); + mlt_events_register( self->properties, "consumer-sdl-event" ); // Return the consumer produced return parent; @@ -169,12 +169,6 @@ mlt_consumer consumer_sdl_init( mlt_profile profile, mlt_service_type type, cons return NULL; } -static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener != NULL ) - listener( owner, self, ( SDL_Event * )args[ 0 ] ); -} - int consumer_start( mlt_consumer parent ) { consumer_sdl self = parent->child; @@ -551,7 +545,7 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) while ( SDL_PollEvent( &event ) ) { - mlt_events_fire( self->properties, "consumer-sdl-event", &event, NULL ); + mlt_events_fire( self->properties, "consumer-sdl-event", mlt_event_data_from_object(&event) ); switch( event.type ) { @@ -692,14 +686,14 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) sdl_unlock_display(); mlt_cocoa_autorelease_close( pool ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); } else if ( self->running ) { vfmt = preview_format == mlt_image_none ? mlt_image_rgb24a : preview_format; if ( !video_off ) mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); } return 0; diff --git a/src/modules/sdl/consumer_sdl_audio.c b/src/modules/sdl/consumer_sdl_audio.c index 350bd4a9b..c847cbdf7 100644 --- a/src/modules/sdl/consumer_sdl_audio.c +++ b/src/modules/sdl/consumer_sdl_audio.c @@ -1,6 +1,6 @@ /* * consumer_sdl_audio.c -- A Simple DirectMedia Layer audio-only consumer - * Copyright (C) 2009-2020 Meltytech, LLC + * Copyright (C) 2009-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -69,7 +69,7 @@ static int consumer_is_stopped( mlt_consumer parent ); static void consumer_purge( mlt_consumer parent ); static void consumer_close( mlt_consumer parent ); static void *consumer_thread( void * ); -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer self, char *name ); +static void consumer_refresh_cb(mlt_consumer sdl, mlt_consumer self, mlt_event_data ); /** This is what will be called by the factory - anything can be passed in via the argument, but keep it simple. @@ -144,9 +144,10 @@ mlt_consumer consumer_sdl_audio_init( mlt_profile profile, mlt_service_type type return NULL; } -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, char *name ) +static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, mlt_event_data event_data ) { - if ( !strcmp( name, "refresh" ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && !strcmp( name, "refresh" ) ) { consumer_sdl self = parent->child; pthread_mutex_lock( &self->refresh_mutex ); @@ -420,7 +421,7 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) { // Get the properties of this consumer mlt_properties properties = self->properties; - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); return 0; } diff --git a/src/modules/sdl/consumer_sdl_preview.c b/src/modules/sdl/consumer_sdl_preview.c index 0f41c6a0d..1ce26424f 100644 --- a/src/modules/sdl/consumer_sdl_preview.c +++ b/src/modules/sdl/consumer_sdl_preview.c @@ -1,6 +1,6 @@ /* * consumer_sdl_preview.c -- A Simple DirectMedia Layer consumer - * Copyright (C) 2004-2014 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -61,9 +61,9 @@ static int consumer_is_stopped( mlt_consumer parent ); static void consumer_purge( mlt_consumer parent ); static void consumer_close( mlt_consumer parent ); static void *consumer_thread( void * ); -static void consumer_frame_show_cb( mlt_consumer sdl, mlt_consumer self, mlt_frame frame ); -static void consumer_sdl_event_cb( mlt_consumer sdl, mlt_consumer self, SDL_Event *event ); -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer self, char *name ); +static void consumer_frame_show_cb( mlt_consumer sdl, mlt_consumer self, mlt_event_data ); +static void consumer_sdl_event_cb( mlt_consumer sdl, mlt_consumer self, mlt_event_data ); +static void consumer_refresh_cb(mlt_consumer sdl, mlt_consumer self, mlt_event_data ); mlt_consumer consumer_sdl_preview_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) { @@ -108,29 +108,33 @@ mlt_consumer consumer_sdl_preview_init( mlt_profile profile, mlt_service_type ty pthread_cond_init( &self->refresh_cond, NULL ); pthread_mutex_init( &self->refresh_mutex, NULL ); mlt_events_listen( MLT_CONSUMER_PROPERTIES( parent ), self, "property-changed", ( mlt_listener )consumer_refresh_cb ); - mlt_events_register( properties, "consumer-sdl-paused", NULL ); + mlt_events_register( properties, "consumer-sdl-paused" ); return parent; } free( self ); return NULL; } -void consumer_frame_show_cb( mlt_consumer sdl, mlt_consumer parent, mlt_frame frame ) +void consumer_frame_show_cb(mlt_consumer sdl, mlt_consumer parent, mlt_event_data event_data ) { + mlt_frame frame = mlt_event_data_to_frame(event_data); consumer_sdl self = parent->child; - self->last_speed = mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ); - self->last_position = mlt_frame_get_position( frame ); - mlt_events_fire( MLT_CONSUMER_PROPERTIES( parent ), "consumer-frame-show", frame, NULL ); + if (frame && self) { + self->last_speed = mlt_properties_get_double( MLT_FRAME_PROPERTIES( frame ), "_speed" ); + self->last_position = mlt_frame_get_position( frame ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES( parent ), "consumer-frame-show", event_data ); + } } -static void consumer_sdl_event_cb( mlt_consumer sdl, mlt_consumer parent, SDL_Event *event ) +static void consumer_sdl_event_cb( mlt_consumer sdl, mlt_consumer parent, mlt_event_data event_data ) { - mlt_events_fire( MLT_CONSUMER_PROPERTIES( parent ), "consumer-sdl-event", event, NULL ); + mlt_events_fire( MLT_CONSUMER_PROPERTIES( parent ), "consumer-sdl-event", event_data ); } -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, char *name ) +static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, mlt_event_data event_data ) { - if ( !strcmp( name, "refresh" ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && !strcmp( name, "refresh" ) ) { consumer_sdl self = parent->child; pthread_mutex_lock( &self->refresh_mutex ); @@ -421,7 +425,7 @@ static void *consumer_thread( void *arg ) } if ( pause && speed == 0.0 ) { - mlt_events_fire( properties, "consumer-sdl-paused", NULL ); + mlt_events_fire( properties, "consumer-sdl-paused", mlt_event_data_none() ); } } // Allow a little grace time before switching consumers on speed changes @@ -462,7 +466,7 @@ static void *consumer_thread( void *arg ) pthread_mutex_lock( &self->refresh_mutex ); if ( self->running && speed == 0 && self->refresh_count <= 0 ) { - mlt_events_fire( properties, "consumer-sdl-paused", NULL ); + mlt_events_fire( properties, "consumer-sdl-paused", mlt_event_data_none() ); pthread_cond_wait( &self->refresh_cond, &self->refresh_mutex ); } self->refresh_count --; diff --git a/src/modules/sdl/consumer_sdl_still.c b/src/modules/sdl/consumer_sdl_still.c index cc1fe285c..87a99f862 100644 --- a/src/modules/sdl/consumer_sdl_still.c +++ b/src/modules/sdl/consumer_sdl_still.c @@ -1,6 +1,6 @@ /* * consumer_sdl_still.c -- A Simple DirectMedia Layer consumer - * Copyright (C) 2003-2019 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -123,7 +123,7 @@ mlt_consumer consumer_sdl_still_init( mlt_profile profile, mlt_service_type type parent->is_stopped = consumer_is_stopped; // Register specific events - mlt_events_register( this->properties, "consumer-sdl-event", ( mlt_transmitter )consumer_sdl_event ); + mlt_events_register( this->properties, "consumer-sdl-event" ); // Return the consumer produced return parent; @@ -136,12 +136,6 @@ mlt_consumer consumer_sdl_still_init( mlt_profile profile, mlt_service_type type return NULL; } -static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service this, void **args ) -{ - if ( listener != NULL ) - listener( owner, this, ( SDL_Event * )args[ 0 ] ); -} - static int consumer_start( mlt_consumer parent ) { consumer_sdl this = parent->child; @@ -397,7 +391,7 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame ) while ( SDL_PollEvent( &event ) ) { - mlt_events_fire( this->properties, "consumer-sdl-event", &event, NULL ); + mlt_events_fire( this->properties, "consumer-sdl-event", mlt_event_data_from_object(&event) ); switch( event.type ) { @@ -528,7 +522,7 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame ) sdl_unlock_display(); mlt_cocoa_autorelease_close( pool ); if ( unlock != NULL ) unlock( ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); return 1; } @@ -576,7 +570,7 @@ static void *consumer_thread( void *arg ) mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "format", vfmt ); - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); } mlt_frame_close( frame ); } diff --git a/src/modules/sdl2/consumer_sdl2.c b/src/modules/sdl2/consumer_sdl2.c index 82b614685..44c8b8c3f 100644 --- a/src/modules/sdl2/consumer_sdl2.c +++ b/src/modules/sdl2/consumer_sdl2.c @@ -1,6 +1,6 @@ /* * consumer_sdl.c -- A Simple DirectMedia Layer consumer - * Copyright (C) 2017-2019 Meltytech, LLC + * Copyright (C) 2017-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -84,7 +84,6 @@ static int consumer_is_stopped( mlt_consumer parent ); static void consumer_purge( mlt_consumer parent ); static void consumer_close( mlt_consumer parent ); static void *consumer_thread( void * ); -static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ); static int setup_sdl_video( consumer_sdl self ); /** This is what will be called by the factory - anything can be passed in @@ -156,7 +155,7 @@ mlt_consumer consumer_sdl2_init( mlt_profile profile, mlt_service_type type, con parent->purge = consumer_purge; // Register specific events - mlt_events_register( self->properties, "consumer-sdl-event", ( mlt_transmitter )consumer_sdl_event ); + mlt_events_register( self->properties, "consumer-sdl-event" ); // Return the consumer produced return parent; @@ -169,12 +168,6 @@ mlt_consumer consumer_sdl2_init( mlt_profile profile, mlt_service_type type, con return NULL; } -static void consumer_sdl_event( mlt_listener listener, mlt_properties owner, mlt_service self, void **args ) -{ - if ( listener != NULL ) - listener( owner, self, ( SDL_Event * )args[ 0 ] ); -} - int consumer_start( mlt_consumer parent ) { consumer_sdl self = parent->child; @@ -682,7 +675,7 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) SDL_RenderPresent( self->sdl_renderer ); } - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); } else if ( self->running ) { @@ -691,7 +684,7 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) vfmt = preview_format == mlt_image_none ? mlt_image_rgb24a : preview_format; mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); } - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); } return 0; diff --git a/src/modules/sdl2/consumer_sdl2_audio.c b/src/modules/sdl2/consumer_sdl2_audio.c index e8527d2b8..fc658fd4e 100644 --- a/src/modules/sdl2/consumer_sdl2_audio.c +++ b/src/modules/sdl2/consumer_sdl2_audio.c @@ -1,6 +1,6 @@ /* * consumer_sdl2_audio.c -- A Simple DirectMedia Layer audio-only consumer - * Copyright (C) 2009-2020 Meltytech, LLC + * Copyright (C) 2009-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -75,7 +75,7 @@ static int consumer_is_stopped( mlt_consumer parent ); static void consumer_purge( mlt_consumer parent ); static void consumer_close( mlt_consumer parent ); static void *consumer_thread( void * ); -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer self, char *name ); +static void consumer_refresh_cb(mlt_consumer sdl, mlt_consumer self, mlt_event_data ); /** This is what will be called by the factory - anything can be passed in via the argument, but keep it simple. @@ -147,9 +147,10 @@ mlt_consumer consumer_sdl2_audio_init( mlt_profile profile, mlt_service_type typ return NULL; } -static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, char *name ) +static void consumer_refresh_cb( mlt_consumer sdl, mlt_consumer parent, mlt_event_data event_data ) { - if ( !strcmp( name, "refresh" ) ) + const char *name = mlt_event_data_to_string(event_data); + if ( name && !strcmp( name, "refresh" ) ) { consumer_sdl self = parent->child; pthread_mutex_lock( &self->refresh_mutex ); @@ -444,7 +445,7 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) { // Get the properties of this consumer mlt_properties properties = self->properties; - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); return 0; } diff --git a/src/modules/xml/consumer_xml.c b/src/modules/xml/consumer_xml.c index 8992569d0..694fda413 100644 --- a/src/modules/xml/consumer_xml.c +++ b/src/modules/xml/consumer_xml.c @@ -1,6 +1,6 @@ /* * consumer_xml.c -- a libxml2 serialiser of mlt service networks - * Copyright (C) 2003-2020 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1084,7 +1084,7 @@ static void *consumer_thread( void *arg ) mlt_frame_get_audio( frame, (void**) &buffer, &aformat, &frequency, &channels, &samples ); // Close the frame - mlt_events_fire( properties, "consumer-frame-show", frame, NULL ); + mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); mlt_frame_close( frame ); } } diff --git a/src/swig/mlt.i b/src/swig/mlt.i index 58b3d62e2..ca8e85a12 100644 --- a/src/swig/mlt.i +++ b/src/swig/mlt.i @@ -1,7 +1,6 @@ /** * mlt.i - Swig Bindings for mlt++ - * Copyright (C) 2004-2015 Meltytech, LLC - * Author: Charles Yates + * Copyright (C) 2004-2021 Meltytech, LLC * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published @@ -160,7 +159,7 @@ void markRubyListener( void* p ) o->mark( ); } -static void on_playlist_next( mlt_properties owner, void *object, int i ); +static void on_playlist_next( mlt_properties owner, void *object, mlt_event_data ); class PlaylistNextListener : RubyListener { @@ -168,8 +167,8 @@ class PlaylistNextListener : RubyListener Mlt::Event *event; public: - PlaylistNextListener( Mlt::Properties *properties, VALUE proc ) - : RubyListener( proc ) + PlaylistNextListener( Mlt::Properties *properties, VALUE callback ) + : RubyListener( callback ) { event = properties->listen( "playlist-next", this, ( mlt_listener )on_playlist_next ); } @@ -179,17 +178,18 @@ class PlaylistNextListener : RubyListener delete event; } - void yield( int i ) + void yield(const Mlt::EventData& eventData) { ID method = rb_intern( "call" ); - rb_funcall( callback, method, 1, INT2FIX( i ) ); + rb_funcall( callback, method, 1, INT2FIX( eventData.to_int() ) ); } }; -static void on_playlist_next( mlt_properties owner, void *object, int i ) +static void on_playlist_next( mlt_properties owner, void *object, mlt_event_data event_data ) { PlaylistNextListener *o = static_cast< PlaylistNextListener * >( object ); - o->yield( i ); + Mlt::EventData data(event_data); + o->yield(data); } %} diff --git a/src/swig/ruby/play.rb b/src/swig/ruby/play.rb index fda7d5b0f..9f1c0d2c8 100755 --- a/src/swig/ruby/play.rb +++ b/src/swig/ruby/play.rb @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # Import required modules -require 'mlt' +require './mlt' # Create the mlt system Mlt::Factory::init diff --git a/src/swig/ruby/playlist.rb b/src/swig/ruby/playlist.rb index 99bb341f8..7b794e36f 100755 --- a/src/swig/ruby/playlist.rb +++ b/src/swig/ruby/playlist.rb @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # Import required modules -require 'mlt' +require './mlt' # Create the mlt system Mlt::Factory::init @@ -29,7 +29,7 @@ pls.append(producer2) # Create the consumer -consumer = Mlt::Consumer.new( profile, "sdl" ) +consumer = Mlt::Consumer.new( profile, "sdl2" ) raise "Unable to open sdl consumer" if !consumer.is_valid # Turn off the default rescaling @@ -55,6 +55,8 @@ # Wait until the user stops the consumer consumer.wait_for( event ) +puts "Done and closing" + # Clean up consumer consumer.stop diff --git a/src/swig/ruby/thumbs.rb b/src/swig/ruby/thumbs.rb index 1b132e882..51293a085 100755 --- a/src/swig/ruby/thumbs.rb +++ b/src/swig/ruby/thumbs.rb @@ -1,7 +1,7 @@ #!/usr/bin/env ruby # Required modules -require 'mlt' +require './mlt' # Create the mlt system Mlt::Factory::init diff --git a/src/tests/test_events/test_events.cpp b/src/tests/test_events/test_events.cpp index b4625d495..134223242 100644 --- a/src/tests/test_events/test_events.cpp +++ b/src/tests/test_events/test_events.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 Meltytech, LLC + * Copyright (C) 2019-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -44,10 +44,10 @@ class TestEvents : public QObject QVERIFY(owner == m_properties); } - static void onPropertyChanged(mlt_properties owner, TestEvents* self, char* name) + static void onPropertyChanged(mlt_properties owner, TestEvents* self, mlt_event_data data) { QVERIFY(self != nullptr); - QCOMPARE(name, "foo"); + QCOMPARE(Mlt::EventData(data).to_string(), "foo"); self->checkOwner(owner); } @@ -58,7 +58,7 @@ private Q_SLOTS: Profile profile; Producer producer(profile, "noise"); QVERIFY(producer.is_valid()); - Event* event = producer.listen("property-changed", this, (mlt_transmitter) onPropertyChanged); + Event* event = producer.listen("property-changed", this, (mlt_listener) onPropertyChanged); QVERIFY(event != nullptr); QVERIFY(event->is_valid()); m_properties = producer.get_properties(); @@ -71,7 +71,7 @@ private Q_SLOTS: Profile profile; Producer producer(profile, "noise"); m_properties = nullptr; - Event* event = producer.listen("property-changed", nullptr, (mlt_transmitter) onPropertyChanged); + Event* event = producer.listen("property-changed", nullptr, (mlt_listener) onPropertyChanged); QVERIFY(event != nullptr); QVERIFY(event->is_valid()); event->block(); @@ -84,7 +84,7 @@ private Q_SLOTS: Profile profile; Producer producer(profile, "noise"); m_properties = producer.get_properties(); - Event* event = producer.listen("property-changed", this, (mlt_transmitter) onPropertyChanged); + Event* event = producer.listen("property-changed", this, (mlt_listener) onPropertyChanged); QVERIFY(event != nullptr); QVERIFY(event->is_valid()); event->block(); From b5b9b60cf81aa838ac6162491585c3f620b8986b Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 14 Mar 2021 17:47:56 -0500 Subject: [PATCH 068/122] Rename mlt_image_rgb24* to mlt_image_rgb* --- src/framework/mlt_frame.c | 6 +++--- src/framework/mlt_image.c | 16 ++++++++-------- src/framework/mlt_types.h | 4 ++-- src/modules/avformat/consumer_avformat.c | 14 +++++++------- src/modules/avformat/filter_avcolour_space.c | 8 ++++---- src/modules/avformat/filter_avfilter.c | 12 ++++++------ src/modules/avformat/filter_swscale.c | 8 ++++---- src/modules/avformat/producer_avformat.c | 16 ++++++++-------- src/modules/core/filter_brightness.c | 2 +- src/modules/core/filter_crop.c | 2 +- src/modules/core/filter_imageconvert.c | 6 +++--- src/modules/core/filter_mask_apply.c | 2 +- src/modules/core/filter_rescale.c | 4 ++-- src/modules/core/filter_resize.c | 6 +++--- src/modules/core/producer_colour.c | 12 ++++++------ src/modules/decklink/consumer_decklink.cpp | 2 +- src/modules/frei0r/filter_frei0r.c | 2 +- src/modules/frei0r/producer_frei0r.c | 2 +- src/modules/frei0r/transition_frei0r.c | 2 +- src/modules/gdk/filter_rescale.c | 6 +++--- src/modules/gdk/producer_pango.c | 4 ++-- src/modules/gdk/producer_pixbuf.c | 2 +- src/modules/kdenlive/filter_boxblur.c | 2 +- src/modules/ndi/consumer_ndi.c | 2 +- src/modules/ndi/producer_ndi.c | 2 +- src/modules/opencv/filter_opencv_tracker.cpp | 2 +- src/modules/opengl/filter_movit_convert.cpp | 8 ++++---- src/modules/plus/filter_affine.c | 2 +- src/modules/plus/filter_lift_gamma_gain.c | 8 ++++---- src/modules/plus/filter_lumakey.c | 2 +- src/modules/plus/filter_pillar_echo.c | 2 +- src/modules/plus/filter_rgblut.c | 2 +- src/modules/plus/filter_spot_remover.c | 12 ++++++------ src/modules/plus/filter_strobe.c | 2 +- src/modules/plus/producer_blipflash.c | 6 +++--- src/modules/plus/producer_count.c | 2 +- src/modules/plus/transition_affine.c | 6 +++--- src/modules/plusgpl/filter_burn.c | 2 +- src/modules/plusgpl/filter_lumaliftgaingamma.c | 2 +- src/modules/plusgpl/filter_rotoscoping.c | 10 +++++----- src/modules/qt/common.cpp | 2 +- src/modules/qt/filter_audiospectrum.cpp | 2 +- src/modules/qt/filter_audiowaveform.cpp | 2 +- src/modules/qt/filter_lightshow.cpp | 2 +- src/modules/qt/filter_qtblend.cpp | 4 ++-- src/modules/qt/filter_qtcrop.cpp | 4 ++-- src/modules/qt/filter_qtext.cpp | 2 +- src/modules/qt/kdenlivetitle_wrapper.cpp | 6 +++--- src/modules/qt/producer_qtext.cpp | 2 +- src/modules/qt/qimage_wrapper.cpp | 6 +++--- src/modules/qt/transition_qtblend.cpp | 4 ++-- src/modules/qt/transition_vqm.cpp | 2 +- src/modules/sdl/consumer_sdl.c | 2 +- src/modules/sdl/consumer_sdl_still.c | 4 ++-- src/modules/sdl/producer_sdl_image.c | 4 ++-- src/modules/sdl2/consumer_sdl2.c | 6 +++--- src/tests/test_filter/test_filter.cpp | 2 +- src/tests/test_image/test_image.cpp | 10 +++++----- 58 files changed, 139 insertions(+), 139 deletions(-) diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 2bc351dfe..3b0de3c84 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -429,8 +429,8 @@ static int generate_test_image( mlt_properties properties, uint8_t **buffer, ml *height = *height == 0 ? 576 : *height; switch( *format ) { - case mlt_image_rgb24: - case mlt_image_rgb24a: + case mlt_image_rgb: + case mlt_image_rgba: case mlt_image_yuv422: case mlt_image_yuv422p16: case mlt_image_yuv420p: @@ -815,7 +815,7 @@ void mlt_frame_write_ppm( mlt_frame frame ) { int width = 0; int height = 0; - mlt_image_format format = mlt_image_rgb24; + mlt_image_format format = mlt_image_rgb; uint8_t *image; if ( mlt_frame_get_image( frame, &image, &format, &width, &height, 0 ) == 0 ) diff --git a/src/framework/mlt_image.c b/src/framework/mlt_image.c index 0013cd3f8..081d44522 100644 --- a/src/framework/mlt_image.c +++ b/src/framework/mlt_image.c @@ -174,9 +174,9 @@ int mlt_image_calculate_size( mlt_image self ) { switch ( self->format ) { - case mlt_image_rgb24: + case mlt_image_rgb: return self->width * self->height * 3; - case mlt_image_rgb24a: + case mlt_image_rgba: return self->width * self->height * 4; case mlt_image_yuv422: return self->width * self->height * 2; @@ -204,8 +204,8 @@ const char * mlt_image_format_name( mlt_image_format format ) switch ( format ) { case mlt_image_none: return "none"; - case mlt_image_rgb24: return "rgb24"; - case mlt_image_rgb24a: return "rgb24a"; + case mlt_image_rgb: return "rgb"; + case mlt_image_rgba: return "rgba"; case mlt_image_yuv422: return "yuv422"; case mlt_image_yuv420p: return "yuv420p"; case mlt_image_glsl: return "glsl"; @@ -251,8 +251,8 @@ void mlt_image_fill_black( mlt_image self ) case mlt_image_glsl: case mlt_image_glsl_texture: return; - case mlt_image_rgb24: - case mlt_image_rgb24a: + case mlt_image_rgb: + case mlt_image_rgba: { int size = mlt_image_calculate_size( self ); memset( self->planes[0], 255, size ); @@ -318,10 +318,10 @@ int mlt_image_format_size( mlt_image_format format, int width, int height, int * { switch ( format ) { - case mlt_image_rgb24: + case mlt_image_rgb: if ( bpp ) *bpp = 3; return width * height * 3; - case mlt_image_rgb24a: + case mlt_image_rgba: if ( bpp ) *bpp = 4; return width * height * 4; case mlt_image_yuv422: diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index ced9099c4..ce6b44d35 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -45,8 +45,8 @@ extern "C" typedef enum { mlt_image_none = 0,/**< image not available */ - mlt_image_rgb24, /**< 8-bit RGB */ - mlt_image_rgb24a, /**< 8-bit RGB with alpha channel */ + mlt_image_rgb, /**< 8-bit RGB */ + mlt_image_rgba, /**< 8-bit RGB with alpha channel */ mlt_image_yuv422, /**< 8-bit YUV 4:2:2 packed */ mlt_image_yuv420p, /**< 8-bit YUV 4:2:0 planar */ mlt_image_glsl, /**< for opengl module internal use only */ diff --git a/src/modules/avformat/consumer_avformat.c b/src/modules/avformat/consumer_avformat.c index 58ca8a29b..a88abdb21 100644 --- a/src/modules/avformat/consumer_avformat.c +++ b/src/modules/avformat/consumer_avformat.c @@ -582,9 +582,9 @@ static enum AVPixelFormat pick_pix_fmt( mlt_image_format img_fmt ) { switch ( img_fmt ) { - case mlt_image_rgb24: + case mlt_image_rgb: return AV_PIX_FMT_RGB24; - case mlt_image_rgb24a: + case mlt_image_rgba: return AV_PIX_FMT_RGBA; case mlt_image_yuv420p: return AV_PIX_FMT_YUV420P; @@ -1674,12 +1674,12 @@ static void *consumer_thread( void *arg ) if ( !strcmp( pix_fmt_name, "rgba" ) || !strcmp( pix_fmt_name, "argb" ) || !strcmp( pix_fmt_name, "bgra" ) ) { - mlt_properties_set( properties, "mlt_image_format", "rgb24a" ); - img_fmt = mlt_image_rgb24a; + mlt_properties_set( properties, "mlt_image_format", "rgba" ); + img_fmt = mlt_image_rgba; } else if ( strstr( pix_fmt_name, "rgb" ) || strstr( pix_fmt_name, "bgr" ) ) { - mlt_properties_set( properties, "mlt_image_format", "rgb24" ); - img_fmt = mlt_image_rgb24; + mlt_properties_set( properties, "mlt_image_format", "rgb" ); + img_fmt = mlt_image_rgb; } } } @@ -1985,7 +1985,7 @@ static void *consumer_thread( void *arg ) // Apply the alpha if applicable if ( !mlt_properties_get( properties, "mlt_image_format" ) || - strcmp( mlt_properties_get( properties, "mlt_image_format" ), "rgb24a" ) ) + strcmp( mlt_properties_get( properties, "mlt_image_format" ), "rgba" ) ) if ( c->pix_fmt == AV_PIX_FMT_RGBA || c->pix_fmt == AV_PIX_FMT_ARGB || c->pix_fmt == AV_PIX_FMT_BGRA ) diff --git a/src/modules/avformat/filter_avcolour_space.c b/src/modules/avformat/filter_avcolour_space.c index 6dc203aaa..b1bef701d 100644 --- a/src/modules/avformat/filter_avcolour_space.c +++ b/src/modules/avformat/filter_avcolour_space.c @@ -51,10 +51,10 @@ static int convert_mlt_to_av_cs( mlt_image_format format ) switch( format ) { - case mlt_image_rgb24: + case mlt_image_rgb: value = AV_PIX_FMT_RGB24; break; - case mlt_image_rgb24a: + case mlt_image_rgba: value = AV_PIX_FMT_RGBA; break; case mlt_image_yuv422: @@ -149,7 +149,7 @@ static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *fo uint8_t *output = mlt_pool_alloc( size ); if (out_width == width && out_height == height) { - if ( *format == mlt_image_rgb24a ) + if ( *format == mlt_image_rgba ) { register int len = width * height; uint8_t *alpha = mlt_pool_alloc( len ); @@ -201,7 +201,7 @@ static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *fo mlt_properties_set_int(properties, "height", out_height); if (out_width == width && out_height == height) - if ( output_format == mlt_image_rgb24a ) + if ( output_format == mlt_image_rgba ) { register int len = width * height; int alpha_size = 0; diff --git a/src/modules/avformat/filter_avfilter.c b/src/modules/avformat/filter_avfilter.c index 9a1063a8e..ba9311364 100644 --- a/src/modules/avformat/filter_avfilter.c +++ b/src/modules/avformat/filter_avfilter.c @@ -79,9 +79,9 @@ static int mlt_to_av_image_format( mlt_image_format format ) { case mlt_image_none: return AV_PIX_FMT_NONE; - case mlt_image_rgb24: + case mlt_image_rgb: return AV_PIX_FMT_RGB24; - case mlt_image_rgb24a: + case mlt_image_rgba: return AV_PIX_FMT_RGBA; case mlt_image_yuv422: return AV_PIX_FMT_YUYV422; @@ -97,10 +97,10 @@ static mlt_image_format get_supported_image_format( mlt_image_format format ) { switch( format ) { - case mlt_image_rgb24a: - return mlt_image_rgb24a; - case mlt_image_rgb24: - return mlt_image_rgb24; + case mlt_image_rgba: + return mlt_image_rgba; + case mlt_image_rgb: + return mlt_image_rgb; case mlt_image_yuv420p: return mlt_image_yuv420p; default: diff --git a/src/modules/avformat/filter_swscale.c b/src/modules/avformat/filter_swscale.c index 8fe7f8795..1df8edd98 100644 --- a/src/modules/avformat/filter_swscale.c +++ b/src/modules/avformat/filter_swscale.c @@ -39,10 +39,10 @@ static inline int convert_mlt_to_av_cs( mlt_image_format format ) switch( format ) { - case mlt_image_rgb24: + case mlt_image_rgb: value = AV_PIX_FMT_RGB24; break; - case mlt_image_rgb24a: + case mlt_image_rgba: value = AV_PIX_FMT_RGBA; break; case mlt_image_yuv422: @@ -97,8 +97,8 @@ static int filter_scale( mlt_frame frame, uint8_t **image, mlt_image_format *for switch ( *format ) { case mlt_image_yuv422: - case mlt_image_rgb24: - case mlt_image_rgb24a: + case mlt_image_rgb: + case mlt_image_rgba: break; default: // XXX: we only know how to rescale packed formats diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index d736da3a6..5c00d9473 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -1259,7 +1259,7 @@ static mlt_image_format pick_image_format( enum AVPixelFormat pix_fmt ) case AV_PIX_FMT_RGBA: case AV_PIX_FMT_ABGR: case AV_PIX_FMT_BGRA: - return mlt_image_rgb24a; + return mlt_image_rgba; case AV_PIX_FMT_YUV420P: case AV_PIX_FMT_YUVJ420P: case AV_PIX_FMT_YUVA420P: @@ -1273,7 +1273,7 @@ static mlt_image_format pick_image_format( enum AVPixelFormat pix_fmt ) case AV_PIX_FMT_BGR8: #if defined(FFUDIV) case AV_PIX_FMT_BAYER_RGGB16LE: - return mlt_image_rgb24; + return mlt_image_rgb; #endif default: return mlt_image_yuv422; @@ -1459,7 +1459,7 @@ static int convert_image( producer_avformat self, AVFrame *frame, uint8_t *buffe || pix_fmt == AV_PIX_FMT_YUVA444P #endif ) && - *format != mlt_image_rgb24a && + *format != mlt_image_rgba && frame->data[3] && frame->linesize[3] ) { int i; @@ -1505,7 +1505,7 @@ static int convert_image( producer_avformat self, AVFrame *frame, uint8_t *buffe out_data, out_stride); sws_freeContext( context ); } - else if ( *format == mlt_image_rgb24 ) + else if ( *format == mlt_image_rgb ) { int flags = mlt_get_sws_flags(width, height, src_pix_fmt, width, height, AV_PIX_FMT_RGB24); struct SwsContext *context = sws_getContext( width, height, src_pix_fmt, @@ -1519,7 +1519,7 @@ static int convert_image( producer_avformat self, AVFrame *frame, uint8_t *buffe out_data, out_stride); sws_freeContext( context ); } - else if ( *format == mlt_image_rgb24a ) + else if ( *format == mlt_image_rgba ) { int flags = mlt_get_sws_flags(width, height, src_pix_fmt, width, height, AV_PIX_FMT_RGBA); struct SwsContext *context = sws_getContext( width, height, src_pix_fmt, @@ -1779,8 +1779,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form else if ( codec_params->format == AV_PIX_FMT_BAYER_RGGB16LE ) { if ( *format == mlt_image_yuv422 ) *format = mlt_image_yuv420p; - else if ( *format == mlt_image_rgb24a ) - *format = mlt_image_rgb24; + else if ( *format == mlt_image_rgba ) + *format = mlt_image_rgb; } #endif else if ( codec_params->format == AV_PIX_FMT_YUVA444P10LE @@ -1789,7 +1789,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form || codec_params->format == AV_PIX_FMT_GBRAP12LE #endif ) - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; // Duplicate the last image if necessary if ( self->video_frame && self->video_frame->linesize[0] diff --git a/src/modules/core/filter_brightness.c b/src/modules/core/filter_brightness.c index 8f43f0f31..a7f632e6e 100644 --- a/src/modules/core/filter_brightness.c +++ b/src/modules/core/filter_brightness.c @@ -123,7 +123,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format double alpha = mlt_properties_get(properties, "alpha")? MIN(mlt_properties_anim_get_double(properties, "alpha", position, length), 1.0) : 1.0; struct sliced_desc desc = { .image = *image, - .rgba = (*format == mlt_image_rgb24a), + .rgba = (*format == mlt_image_rgba), .width = *width, .height = *height, .level = (*format == mlt_image_yuv422)? level : 1.0, diff --git a/src/modules/core/filter_crop.c b/src/modules/core/filter_crop.c index 80e3ac473..b1ba219c3 100644 --- a/src/modules/core/filter_crop.c +++ b/src/modules/core/filter_crop.c @@ -88,7 +88,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // Subsampled YUV is messy and less precise. if (*format == mlt_image_yuv422 && frame->convert_image && (left & 1 || right & 1)) { - mlt_image_format requested_format = mlt_image_rgb24; + mlt_image_format requested_format = mlt_image_rgb; frame->convert_image( frame, image, format, requested_format ); } diff --git a/src/modules/core/filter_imageconvert.c b/src/modules/core/filter_imageconvert.c index 8b78de53a..3993266b4 100644 --- a/src/modules/core/filter_imageconvert.c +++ b/src/modules/core/filter_imageconvert.c @@ -323,9 +323,9 @@ static int convert_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *f int size = width * height * bpp_table[ requested_format - 1 ]; int alpha_size = width * height; uint8_t *image = mlt_pool_alloc( size ); - uint8_t *alpha = ( *format == mlt_image_rgb24a ) + uint8_t *alpha = ( *format == mlt_image_rgba ) ? mlt_pool_alloc( width * height ) : NULL; - if ( requested_format == mlt_image_rgb24a ) + if ( requested_format == mlt_image_rgba ) { if ( alpha ) mlt_pool_release( alpha ); @@ -336,7 +336,7 @@ static int convert_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *f if ( !( error = converter( *buffer, image, alpha, width, height ) ) ) { mlt_frame_set_image( frame, image, size, mlt_pool_release ); - if ( alpha && *format == mlt_image_rgb24a ) + if ( alpha && *format == mlt_image_rgba ) mlt_frame_set_alpha( frame, alpha, alpha_size, mlt_pool_release ); *buffer = image; *format = requested_format; diff --git a/src/modules/core/filter_mask_apply.c b/src/modules/core/filter_mask_apply.c index 89953e467..90e6413b0 100644 --- a/src/modules/core/filter_mask_apply.c +++ b/src/modules/core/filter_mask_apply.c @@ -106,7 +106,7 @@ mlt_filter filter_mask_apply_init(mlt_profile profile, mlt_service_type type, co mlt_filter filter = mlt_filter_new( ); if (filter) { mlt_properties_set(MLT_FILTER_PROPERTIES(filter), "transition", arg? arg : "frei0r.composition"); - mlt_properties_set(MLT_FILTER_PROPERTIES(filter), "mlt_image_format", "rgb24a"); + mlt_properties_set(MLT_FILTER_PROPERTIES(filter), "mlt_image_format", "rgba"); filter->process = process; } return filter; diff --git a/src/modules/core/filter_rescale.c b/src/modules/core/filter_rescale.c index f0db5b835..cb1722fbc 100644 --- a/src/modules/core/filter_rescale.c +++ b/src/modules/core/filter_rescale.c @@ -229,8 +229,8 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format iwidth, iheight, owidth, oheight, mlt_image_format_name( *format ), interps ); // If valid colorspace - if ( *format == mlt_image_yuv422 || *format == mlt_image_rgb24 || - *format == mlt_image_rgb24a ) + if ( *format == mlt_image_yuv422 || *format == mlt_image_rgb || + *format == mlt_image_rgba ) { // Call the virtual function scaler_method( frame, image, format, iwidth, iheight, owidth, oheight ); diff --git a/src/modules/core/filter_resize.c b/src/modules/core/filter_resize.c index fcbdd75d3..236651cdc 100644 --- a/src/modules/core/filter_resize.c +++ b/src/modules/core/filter_resize.c @@ -85,7 +85,7 @@ static void resize_image( uint8_t *output, int owidth, int oheight, uint8_t *inp return; } - if ( format == mlt_image_rgb24a ) + if ( format == mlt_image_rgba ) { memset(p, 0, size * bpp); if (alpha_value != 0) { @@ -160,7 +160,7 @@ static uint8_t *frame_resize_image( mlt_frame frame, int owidth, int oheight, ml mlt_frame_set_image( frame, output, owidth * ( oheight + 1 ) * bpp, mlt_pool_release ); // We should resize the alpha too - if ( format != mlt_image_rgb24a && alpha && alpha_size >= iwidth * iheight ) + if ( format != mlt_image_rgba && alpha && alpha_size >= iwidth * iheight ) { alpha = resize_alpha( alpha, owidth, oheight, iwidth, iheight, alpha_value ); if ( alpha ) @@ -215,7 +215,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // after the deinterlace filter, which only operates in YUV to avoid a YUV->RGB->YUV->?. // Instead, it will go YUV->RGB->?. if ( mlt_properties_get_int( properties, "force_full_luma" ) ) - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; // Hmmm... char *rescale = mlt_properties_get( properties, "rescale.interp" ); diff --git a/src/modules/core/producer_colour.c b/src/modules/core/producer_colour.c index 3c670f778..58ceb1837 100644 --- a/src/modules/core/producer_colour.c +++ b/src/modules/core/producer_colour.c @@ -92,15 +92,15 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form // Choose suitable out values if nothing specific requested if ( *format == mlt_image_none || *format == mlt_image_glsl ) - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; if ( *width <= 0 ) *width = mlt_service_profile( MLT_PRODUCER_SERVICE(producer) )->width; if ( *height <= 0 ) *height = mlt_service_profile( MLT_PRODUCER_SERVICE(producer) )->height; // Choose default image format if specific request is unsupported - if (*format!=mlt_image_yuv420p && *format!=mlt_image_yuv422 && *format!=mlt_image_rgb24 && *format!= mlt_image_glsl && *format!= mlt_image_glsl_texture) - *format = mlt_image_rgb24a; + if (*format!=mlt_image_yuv420p && *format!=mlt_image_yuv422 && *format!=mlt_image_rgb && *format!= mlt_image_glsl && *format!= mlt_image_glsl_texture) + *format = mlt_image_rgba; // See if we need to regenerate if ( !now || ( then && strcmp( now, then ) ) || *width != current_width || *height != current_height || *format != current_format ) @@ -163,7 +163,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form mlt_properties_set_int( properties, "colorspace", 601 ); break; } - case mlt_image_rgb24: + case mlt_image_rgb: while ( --i ) { *p ++ = color.r; @@ -175,7 +175,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form case mlt_image_glsl_texture: memset(p, 0, size); break; - case mlt_image_rgb24a: + case mlt_image_rgba: while ( --i ) { *p ++ = color.r; @@ -199,7 +199,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form uint8_t *alpha = NULL; // Initialise the alpha - if (color.a < 255 || *format == mlt_image_rgb24a) { + if (color.a < 255 || *format == mlt_image_rgba) { alpha_size = *width * *height; alpha = mlt_pool_alloc( alpha_size ); if ( alpha ) diff --git a/src/modules/decklink/consumer_decklink.cpp b/src/modules/decklink/consumer_decklink.cpp index cea9e279a..f2cd0313e 100644 --- a/src/modules/decklink/consumer_decklink.cpp +++ b/src/modules/decklink/consumer_decklink.cpp @@ -512,7 +512,7 @@ class DeckLinkConsumer void renderVideo( mlt_frame frame ) { HRESULT hr; - mlt_image_format format = m_isKeyer? mlt_image_rgb24a : mlt_image_yuv422; + mlt_image_format format = m_isKeyer? mlt_image_rgba : mlt_image_yuv422; uint8_t* image = 0; int rendered = mlt_properties_get_int( MLT_FRAME_PROPERTIES(frame), "rendered"); mlt_properties consumer_properties = MLT_CONSUMER_PROPERTIES( getConsumer() ); diff --git a/src/modules/frei0r/filter_frei0r.c b/src/modules/frei0r/filter_frei0r.c index 3daad1219..4bc37ea13 100644 --- a/src/modules/frei0r/filter_frei0r.c +++ b/src/modules/frei0r/filter_frei0r.c @@ -27,7 +27,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format { mlt_filter filter = mlt_frame_pop_service( frame ); - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; mlt_log_debug( MLT_FILTER_SERVICE( filter ), "frei0r %dx%d\n", *width, *height ); int error = mlt_frame_get_image( frame, image, format, width, height, 0 ); diff --git a/src/modules/frei0r/producer_frei0r.c b/src/modules/frei0r/producer_frei0r.c index 6a9e6a320..5d74a260c 100644 --- a/src/modules/frei0r/producer_frei0r.c +++ b/src/modules/frei0r/producer_frei0r.c @@ -36,7 +36,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form *height = mlt_service_profile( MLT_PRODUCER_SERVICE(producer) )->height; // Allocate the image - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; int size = mlt_image_format_size( *format, *width, *height, NULL ); // Allocate the image diff --git a/src/modules/frei0r/transition_frei0r.c b/src/modules/frei0r/transition_frei0r.c index df9527e45..dce41057a 100644 --- a/src/modules/frei0r/transition_frei0r.c +++ b/src/modules/frei0r/transition_frei0r.c @@ -46,7 +46,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f int error = 0; // Get the B-frame. - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; error = mlt_frame_get_image( b_frame, &images[1], format, width, height, 0 ); if ( error ) return error; diff --git a/src/modules/gdk/filter_rescale.c b/src/modules/gdk/filter_rescale.c index 1f3355bd6..01b3cf95d 100644 --- a/src/modules/gdk/filter_rescale.c +++ b/src/modules/gdk/filter_rescale.c @@ -70,15 +70,15 @@ static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format *form *image = output; break; } - case mlt_image_rgb24: - case mlt_image_rgb24a: + case mlt_image_rgb: + case mlt_image_rgba: { if ( strcmp( interps, "none" ) && ( iwidth != owidth || iheight != oheight ) ) { // Create the output image uint8_t *output = mlt_pool_alloc( size ); GdkPixbuf *pixbuf = gdk_pixbuf_new_from_data( *image, GDK_COLORSPACE_RGB, - ( *format == mlt_image_rgb24a ), 8, iwidth, iheight, + ( *format == mlt_image_rgba ), 8, iwidth, iheight, iwidth * bpp, NULL, NULL ); GdkPixbuf *scaled = gdk_pixbuf_scale_simple( pixbuf, owidth, oheight, interp ); g_object_unref( pixbuf ); diff --git a/src/modules/gdk/producer_pango.c b/src/modules/gdk/producer_pango.c index d0f0a1908..c91b7e713 100644 --- a/src/modules/gdk/producer_pango.c +++ b/src/modules/gdk/producer_pango.c @@ -614,12 +614,12 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form cached = mlt_pool_alloc( sizeof( struct pango_cached_image_s )); cached->width = self->width; cached->height = self->height; - cached->format = gdk_pixbuf_get_has_alpha( self->pixbuf ) ? mlt_image_rgb24a : mlt_image_rgb24; + cached->format = gdk_pixbuf_get_has_alpha( self->pixbuf ) ? mlt_image_rgba : mlt_image_rgb; cached->alpha = NULL; cached->image = NULL; src_stride = gdk_pixbuf_get_rowstride( self->pixbuf ); - dst_stride = self->width * ( mlt_image_rgb24a == cached->format ? 4 : 3 ); + dst_stride = self->width * ( mlt_image_rgba == cached->format ? 4 : 3 ); size = mlt_image_format_size( cached->format, cached->width, cached->height, &bpp ); buf = mlt_pool_alloc( size ); diff --git a/src/modules/gdk/producer_pixbuf.c b/src/modules/gdk/producer_pixbuf.c index bfa74ec73..29b7a58a0 100644 --- a/src/modules/gdk/producer_pixbuf.c +++ b/src/modules/gdk/producer_pixbuf.c @@ -606,7 +606,7 @@ static void refresh_image( producer_pixbuf self, mlt_frame frame, mlt_image_form int has_alpha = gdk_pixbuf_get_has_alpha( pixbuf ); int src_stride = gdk_pixbuf_get_rowstride( pixbuf ); int dst_stride = self->width * ( has_alpha ? 4 : 3 ); - self->format = has_alpha ? mlt_image_rgb24a : mlt_image_rgb24; + self->format = has_alpha ? mlt_image_rgba : mlt_image_rgb; int image_size = mlt_image_format_size( self->format, width, height, NULL ); self->image = mlt_pool_alloc( image_size ); self->alpha = NULL; diff --git a/src/modules/kdenlive/filter_boxblur.c b/src/modules/kdenlive/filter_boxblur.c index 6374fe722..94b027a62 100644 --- a/src/modules/kdenlive/filter_boxblur.c +++ b/src/modules/kdenlive/filter_boxblur.c @@ -126,7 +126,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format else { // Get the image - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); // Only process if we have no error and a valid colour space diff --git a/src/modules/ndi/consumer_ndi.c b/src/modules/ndi/consumer_ndi.c index df3003de0..cd4064ab9 100644 --- a/src/modules/ndi/consumer_ndi.c +++ b/src/modules/ndi/consumer_ndi.c @@ -102,7 +102,7 @@ static void* consumer_ndi_feeder( void* p ) int m_isKeyer = 0, width = profile->width, height = profile->height; uint8_t* image = 0; mlt_frame frm = m_isKeyer ? frame : last; - mlt_image_format format = 0 ? mlt_image_rgb24a : mlt_image_yuv422; + mlt_image_format format = 0 ? mlt_image_rgba : mlt_image_yuv422; int rendered = mlt_properties_get_int( MLT_FRAME_PROPERTIES( frm ), "rendered" ); if ( rendered && !mlt_frame_get_image( frm, &image, &format, &width, &height, 0 ) ) diff --git a/src/modules/ndi/producer_ndi.c b/src/modules/ndi/producer_ndi.c index d27b2532f..74bd517b4 100644 --- a/src/modules/ndi/producer_ndi.c +++ b/src/modules/ndi/producer_ndi.c @@ -295,7 +295,7 @@ static int get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *forma else if ( NDIlib_FourCC_type_RGBA == video->FourCC || NDIlib_FourCC_type_RGBX == video->FourCC ) { dst_stride = 4 * video->xres; - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; } else *format = mlt_image_none; diff --git a/src/modules/opencv/filter_opencv_tracker.cpp b/src/modules/opencv/filter_opencv_tracker.cpp index 1e82f865a..3917974c1 100644 --- a/src/modules/opencv/filter_opencv_tracker.cpp +++ b/src/modules/opencv/filter_opencv_tracker.cpp @@ -303,7 +303,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format } else { - *format = mlt_image_rgb24; + *format = mlt_image_rgb; error = mlt_frame_get_image( frame, image, format, width, height, 1 ); cvFrame = cv::Mat( *height, *width, CV_8UC3, *image ); } diff --git a/src/modules/opengl/filter_movit_convert.cpp b/src/modules/opengl/filter_movit_convert.cpp index 2b767ae1a..6913dca62 100644 --- a/src/modules/opengl/filter_movit_convert.cpp +++ b/src/modules/opengl/filter_movit_convert.cpp @@ -459,8 +459,8 @@ static int movit_render( EffectChain *chain, mlt_frame frame, mlt_image_format * } else { error = glsl->render_frame_rgba( chain, frame, width, height, image ); - if ( !error && output_format != mlt_image_rgb24a ) { - *format = mlt_image_rgb24a; + if ( !error && output_format != mlt_image_rgba ) { + *format = mlt_image_rgba; error = convert_on_cpu( frame, image, format, output_format ); } } @@ -476,11 +476,11 @@ static MltInput* create_input( mlt_properties properties, mlt_image_format forma } MltInput* input = new MltInput( format ); - if ( format == mlt_image_rgb24a ) { + if ( format == mlt_image_rgba ) { // TODO: Get the color space if available. input->useFlatInput( FORMAT_RGBA_POSTMULTIPLIED_ALPHA, width, height ); } - else if ( format == mlt_image_rgb24 ) { + else if ( format == mlt_image_rgb ) { // TODO: Get the color space if available. input->useFlatInput( FORMAT_RGB, width, height ); } diff --git a/src/modules/plus/filter_affine.c b/src/modules/plus/filter_affine.c index bade559bf..5b1e667c1 100644 --- a/src/modules/plus/filter_affine.c +++ b/src/modules/plus/filter_affine.c @@ -40,7 +40,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // Get the image int error = 0; - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); diff --git a/src/modules/plus/filter_lift_gamma_gain.c b/src/modules/plus/filter_lift_gamma_gain.c index 6d79ae27a..9d1132184 100644 --- a/src/modules/plus/filter_lift_gamma_gain.c +++ b/src/modules/plus/filter_lift_gamma_gain.c @@ -125,7 +125,7 @@ static void apply_lut( mlt_filter filter, uint8_t* image, mlt_image_format forma switch( format ) { - case mlt_image_rgb24: + case mlt_image_rgb: while( --total ) { *sample = rlut[ *sample ]; @@ -136,7 +136,7 @@ static void apply_lut( mlt_filter filter, uint8_t* image, mlt_image_format forma sample++; } break; - case mlt_image_rgb24a: + case mlt_image_rgba: while( --total ) { *sample = rlut[ *sample ]; @@ -169,9 +169,9 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); // Make sure the format is acceptable - if( *format != mlt_image_rgb24 && *format != mlt_image_rgb24a ) + if( *format != mlt_image_rgb && *format != mlt_image_rgba ) { - *format = mlt_image_rgb24; + *format = mlt_image_rgb; } // Get the image diff --git a/src/modules/plus/filter_lumakey.c b/src/modules/plus/filter_lumakey.c index be724d196..987a7c551 100644 --- a/src/modules/plus/filter_lumakey.c +++ b/src/modules/plus/filter_lumakey.c @@ -69,7 +69,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_position position = mlt_filter_get_position( filter, frame ); mlt_position length = mlt_filter_get_length2( filter, frame ); - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; int error = mlt_frame_get_image( frame, image, format, width, height, 0 ); // Only process if we have no error and a valid colour space diff --git a/src/modules/plus/filter_pillar_echo.c b/src/modules/plus/filter_pillar_echo.c index 9ddf528d0..7016d19a9 100644 --- a/src/modules/plus/filter_pillar_echo.c +++ b/src/modules/plus/filter_pillar_echo.c @@ -396,7 +396,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format return mlt_frame_get_image( frame, image, format, width, height, writable ); } - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; error = mlt_frame_get_image( frame, image, format, width, height, 1 ); if (error) return error; diff --git a/src/modules/plus/filter_rgblut.c b/src/modules/plus/filter_rgblut.c index 3f268d472..41c598423 100644 --- a/src/modules/plus/filter_rgblut.c +++ b/src/modules/plus/filter_rgblut.c @@ -65,7 +65,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // Get the image mlt_filter filter = mlt_frame_pop_service( frame ); - *format = mlt_image_rgb24; + *format = mlt_image_rgb; int error = mlt_frame_get_image( frame, image, format, width, height, 0 ); // Only process if we have no error and a valid colour space diff --git a/src/modules/plus/filter_spot_remover.c b/src/modules/plus/filter_spot_remover.c index c266bbc97..c03813c78 100644 --- a/src/modules/plus/filter_spot_remover.c +++ b/src/modules/plus/filter_spot_remover.c @@ -155,14 +155,14 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format switch( *format ) { - case mlt_image_rgb24a: - case mlt_image_rgb24: + case mlt_image_rgba: + case mlt_image_rgb: case mlt_image_yuv422: case mlt_image_yuv420p: // These formats are all supported break; default: - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; break; } error = mlt_frame_get_image( frame, image, format, width, height, 1 ); @@ -174,13 +174,13 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format int i; switch( *format ) { - case mlt_image_rgb24a: + case mlt_image_rgba: for ( i = 0; i < 4; i++ ) { remove_spot_channel( img.planes[0] + i, img.width, 4, rect ); } break; - case mlt_image_rgb24: + case mlt_image_rgb: for ( i = 0; i < 3; i++ ) { remove_spot_channel( img.planes[0] + i, img.width, 3, rect ); @@ -211,7 +211,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format } uint8_t *alpha = mlt_frame_get_alpha( frame ); - if ( alpha && *format != mlt_image_rgb24a ) + if ( alpha && *format != mlt_image_rgba ) { remove_spot_channel( alpha, *width, 1, rect ); } diff --git a/src/modules/plus/filter_strobe.c b/src/modules/plus/filter_strobe.c index f00abff8d..25aa16081 100644 --- a/src/modules/plus/filter_strobe.c +++ b/src/modules/plus/filter_strobe.c @@ -73,7 +73,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format memset( alpha_buffer, 0, pixelCount ); } - if ( *format == mlt_image_rgb24a ) + if ( *format == mlt_image_rgba ) { uint8_t *bytes = *image; for ( size_t i=3; iwidth; diff --git a/src/modules/plus/producer_count.c b/src/modules/plus/producer_count.c index 6cd9bc753..b00a5f1e9 100644 --- a/src/modules/plus/producer_count.c +++ b/src/modules/plus/producer_count.c @@ -477,7 +477,7 @@ static void add_clock_to_frame( mlt_producer producer, mlt_frame frame, time_inf mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ); mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); uint8_t* image = NULL; - mlt_image_format format = mlt_image_rgb24a; + mlt_image_format format = mlt_image_rgba; int size = 0; int width = profile->width; int height = profile->height; diff --git a/src/modules/plus/transition_affine.c b/src/modules/plus/transition_affine.c index 9abccd2d2..1b4c28a43 100644 --- a/src/modules/plus/transition_affine.c +++ b/src/modules/plus/transition_affine.c @@ -447,7 +447,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // Image, format, width, height and image for the b frame uint8_t *b_image = NULL; - mlt_image_format b_format = mlt_image_rgb24a; + mlt_image_format b_format = mlt_image_rgba; int b_width = mlt_properties_get_int( b_props, "meta.media.width" ); int b_height = mlt_properties_get_int( b_props, "meta.media.height" ); double b_ar = mlt_frame_get_aspect_ratio( b_frame ); @@ -485,7 +485,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f } // Fetch the a frame image - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; int error = mlt_frame_get_image( a_frame, image, format, width, height, 1 ); if (error || !image) return error; @@ -621,7 +621,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f } // Check that both images are of the correct format and process - if ( *format == mlt_image_rgb24a && b_format == mlt_image_rgb24a ) + if ( *format == mlt_image_rgba && b_format == mlt_image_rgba ) { double sw, sh; // Get values from the transition diff --git a/src/modules/plusgpl/filter_burn.c b/src/modules/plusgpl/filter_burn.c index 6936d6dba..3641b68ce 100644 --- a/src/modules/plusgpl/filter_burn.c +++ b/src/modules/plusgpl/filter_burn.c @@ -79,7 +79,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_filter filter = mlt_frame_pop_service( frame ); // Get the image - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); // Only process if we have no error and a valid colour space diff --git a/src/modules/plusgpl/filter_lumaliftgaingamma.c b/src/modules/plusgpl/filter_lumaliftgaingamma.c index bc1e9d7ea..0cb00ed85 100644 --- a/src/modules/plusgpl/filter_lumaliftgaingamma.c +++ b/src/modules/plusgpl/filter_lumaliftgaingamma.c @@ -109,7 +109,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_position position = mlt_filter_get_position( filter, frame ); mlt_position length = mlt_filter_get_length2( filter, frame ); - *format = mlt_image_rgb24; + *format = mlt_image_rgb; int error = mlt_frame_get_image( frame, image, format, width, height, 0 ); // Only process if we have no error and a valid colour space diff --git a/src/modules/plusgpl/filter_rotoscoping.c b/src/modules/plusgpl/filter_rotoscoping.c index 298c75b5a..aedd7ec8b 100644 --- a/src/modules/plusgpl/filter_rotoscoping.c +++ b/src/modules/plusgpl/filter_rotoscoping.c @@ -327,7 +327,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // Get the image if ( mode == MODE_RGB ) - *format = mlt_image_rgb24; + *format = mlt_image_rgb; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); // Only process if we have no error and a valid colour space @@ -387,7 +387,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format switch ( mode ) { case MODE_RGB: - // *format == mlt_image_rgb24 + // *format == mlt_image_rgb while ( p != q ) { if ( !map[i++] ) @@ -398,8 +398,8 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format case MODE_LUMA: switch ( *format ) { - case mlt_image_rgb24: - case mlt_image_rgb24a: + case mlt_image_rgb: + case mlt_image_rgba: while ( p != q ) { p[0] = p[1] = p[2] = map[i++]; @@ -425,7 +425,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format case MODE_ALPHA: switch ( *format ) { - case mlt_image_rgb24a: + case mlt_image_rgba: switch ( mlt_properties_get_int( unique, "alpha_operation" ) ) { case ALPHA_CLEAR: diff --git a/src/modules/qt/common.cpp b/src/modules/qt/common.cpp index 67bc456de..ec836b646 100644 --- a/src/modules/qt/common.cpp +++ b/src/modules/qt/common.cpp @@ -106,7 +106,7 @@ int create_image( mlt_frame frame, uint8_t **image, mlt_image_format *image_form int error = 0; mlt_properties frame_properties = MLT_FRAME_PROPERTIES( frame ); - *image_format = mlt_image_rgb24a; + *image_format = mlt_image_rgba; // Use the width and height suggested by the rescale filter. if( mlt_properties_get_int( frame_properties, "rescale_width" ) > 0 ) diff --git a/src/modules/qt/filter_audiospectrum.cpp b/src/modules/qt/filter_audiospectrum.cpp index 45fd9ac08..69c3a7fd0 100644 --- a/src/modules/qt/filter_audiospectrum.cpp +++ b/src/modules/qt/filter_audiospectrum.cpp @@ -255,7 +255,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format if( mlt_properties_get_data( frame_properties, pdata->fft_prop_name, NULL ) ) { // Get the current image - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; error = mlt_frame_get_image( frame, image, format, width, height, 1 ); // Draw the spectrum diff --git a/src/modules/qt/filter_audiowaveform.cpp b/src/modules/qt/filter_audiowaveform.cpp index bdaf634ad..0547cbc72 100644 --- a/src/modules/qt/filter_audiowaveform.cpp +++ b/src/modules/qt/filter_audiowaveform.cpp @@ -340,7 +340,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format if( audio ) { // Get the current image - *image_format = mlt_image_rgb24a; + *image_format = mlt_image_rgba; error = mlt_frame_get_image( frame, image, image_format, width, height, writable ); // Draw the waveforms diff --git a/src/modules/qt/filter_lightshow.cpp b/src/modules/qt/filter_lightshow.cpp index ff15ad36b..0e77718ed 100644 --- a/src/modules/qt/filter_lightshow.cpp +++ b/src/modules/qt/filter_lightshow.cpp @@ -208,7 +208,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_rect rect = mlt_properties_anim_get_rect( filter_properties, "rect", position, length ); // Get the current image - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; error = mlt_frame_get_image( frame, image, format, width, height, 1 ); if ( strchr( mlt_properties_get( filter_properties, "rect" ), '%' ) ) { diff --git a/src/modules/qt/filter_qtblend.cpp b/src/modules/qt/filter_qtblend.cpp index 4537c6981..b24cd3c2f 100644 --- a/src/modules/qt/filter_qtblend.cpp +++ b/src/modules/qt/filter_qtblend.cpp @@ -125,7 +125,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format if ( !hasAlpha ) { uint8_t *src_image = NULL; error = mlt_frame_get_image( frame, &src_image, format, &b_width, &b_height, 0 ); - if ( *format == mlt_image_rgb24a || mlt_frame_get_alpha( frame ) ) { + if ( *format == mlt_image_rgba || mlt_frame_get_alpha( frame ) ) { hasAlpha = true; } else { // Prepare output image @@ -137,7 +137,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format } // fetch image - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; uint8_t *src_image = NULL; // Adjust if consumer is scaling diff --git a/src/modules/qt/filter_qtcrop.cpp b/src/modules/qt/filter_qtcrop.cpp index d16b1d71a..43e6e2e22 100644 --- a/src/modules/qt/filter_qtcrop.cpp +++ b/src/modules/qt/filter_qtcrop.cpp @@ -37,11 +37,11 @@ static int get_image(mlt_frame frame, uint8_t **image, mlt_image_format *format, mlt_rect rect = mlt_properties_anim_get_rect(properties, "rect", position, length); // Get the current image - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; mlt_properties_set_int(MLT_FRAME_PROPERTIES(frame), "resize_alpha", 255); error = mlt_frame_get_image(frame, image, format, width, height, writable); - if (!error && *format == mlt_image_rgb24a) { + if (!error && *format == mlt_image_rgba) { QImage bgImage; convert_mlt_to_qimage_rgba(*image, &bgImage, *width, *height); diff --git a/src/modules/qt/filter_qtext.cpp b/src/modules/qt/filter_qtext.cpp index 8b8cb2b7c..afc20e7e2 100644 --- a/src/modules/qt/filter_qtext.cpp +++ b/src/modules/qt/filter_qtext.cpp @@ -297,7 +297,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_rect rect = mlt_properties_anim_get_rect( filter_properties, "geometry", position, length ); // Get the current image - *image_format = mlt_image_rgb24a; + *image_format = mlt_image_rgba; mlt_properties_set_int( MLT_FRAME_PROPERTIES(frame), "resize_alpha", 255 ); mlt_service_lock(MLT_FILTER_SERVICE(filter)); error = mlt_frame_get_image( frame, image, image_format, width, height, writable ); diff --git a/src/modules/qt/kdenlivetitle_wrapper.cpp b/src/modules/qt/kdenlivetitle_wrapper.cpp index 82337042e..5d12de061 100755 --- a/src/modules/qt/kdenlivetitle_wrapper.cpp +++ b/src/modules/qt/kdenlivetitle_wrapper.cpp @@ -812,7 +812,7 @@ void drawKdenliveTitle( producer_ktitle self, mlt_frame frame, mlt_image_format } } p1.end(); - self->format = mlt_image_rgb24a; + self->format = mlt_image_rgba; convert_qimage_to_mlt_rgba(&img, self->rgba_image, width, height); self->current_image = (uint8_t *) mlt_pool_alloc( image_size ); @@ -835,12 +835,12 @@ void drawKdenliveTitle( producer_ktitle self, mlt_frame frame, mlt_image_format if ( format != mlt_image_none && format != mlt_image_glsl && format != self->format ) { uint8_t *buffer = NULL; - if ( self->format != mlt_image_rgb24a ) { + if ( self->format != mlt_image_rgba ) { // Image buffer was previously converted, revert to original rgba buffer self->current_image = (uint8_t *) mlt_pool_alloc( image_size ); memcpy(self->current_image, self->rgba_image, image_size); mlt_properties_set_data( producer_props, "_cached_image", self->current_image, image_size, mlt_pool_release, NULL ); - self->format = mlt_image_rgb24a; + self->format = mlt_image_rgba; } // First, set the image so it can be converted when we get it diff --git a/src/modules/qt/producer_qtext.cpp b/src/modules/qt/producer_qtext.cpp index ff95a8e26..67075a57e 100644 --- a/src/modules/qt/producer_qtext.cpp +++ b/src/modules/qt/producer_qtext.cpp @@ -332,7 +332,7 @@ static int producer_get_image( mlt_frame frame, uint8_t** buffer, mlt_image_form generate_qimage( frame_properties ); } - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; *width = qImg->width(); *height = qImg->height(); diff --git a/src/modules/qt/qimage_wrapper.cpp b/src/modules/qt/qimage_wrapper.cpp index 01b2b8a0b..3a88838e0 100644 --- a/src/modules/qt/qimage_wrapper.cpp +++ b/src/modules/qt/qimage_wrapper.cpp @@ -280,7 +280,7 @@ void refresh_image( producer_qimage self, mlt_frame frame, mlt_image_format form #if QT_VERSION >= 0x050200 if ( has_alpha ) { - self->format = mlt_image_rgb24a; + self->format = mlt_image_rgba; scaled = scaled.convertToFormat( QImage::Format_RGBA8888 ); image_size = mlt_image_format_size(self->format, width, height, NULL); self->current_image = ( uint8_t * )mlt_pool_alloc( image_size ); @@ -288,7 +288,7 @@ void refresh_image( producer_qimage self, mlt_frame frame, mlt_image_format form } else { - self->format = mlt_image_rgb24; + self->format = mlt_image_rgb; scaled = scaled.convertToFormat( QImage::Format_RGB888 ); image_size = mlt_image_format_size(self->format, width, height, NULL); self->current_image = ( uint8_t * )mlt_pool_alloc( image_size ); @@ -298,7 +298,7 @@ void refresh_image( producer_qimage self, mlt_frame frame, mlt_image_format form } } #else - self->format = has_alpha? mlt_image_rgb24a : mlt_image_rgb24; + self->format = has_alpha? mlt_image_rgba : mlt_image_rgb; image_size = mlt_image_format_size( self->format, self->current_width, self->current_height, NULL ); self->current_image = ( uint8_t * )mlt_pool_alloc( image_size ); int y = self->current_height + 1; diff --git a/src/modules/qt/transition_qtblend.cpp b/src/modules/qt/transition_qtblend.cpp index 09283b012..f5f7d47f1 100644 --- a/src/modules/qt/transition_qtblend.cpp +++ b/src/modules/qt/transition_qtblend.cpp @@ -187,7 +187,7 @@ static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *form { // fetch image error = mlt_frame_get_image( b_frame, &b_image, format, width, height, 1 ); - if ( *format == mlt_image_rgb24a || mlt_frame_get_alpha( b_frame ) ) + if ( *format == mlt_image_rgba || mlt_frame_get_alpha( b_frame ) ) { hasAlpha = true; } @@ -201,7 +201,7 @@ static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *form return 0; } // Get RGBA image to process - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; error = mlt_frame_get_image( b_frame, &b_image, format, &b_width, &b_height, writable ); // Get bottom frame diff --git a/src/modules/qt/transition_vqm.cpp b/src/modules/qt/transition_vqm.cpp index 1fb7db4b0..0dba067f7 100644 --- a/src/modules/qt/transition_vqm.cpp +++ b/src/modules/qt/transition_vqm.cpp @@ -139,7 +139,7 @@ static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *form return 0; // get RGBA image for Qt drawing - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; mlt_frame_get_image( a_frame, image, format, width, height, 1 ); // convert mlt image to qimage diff --git a/src/modules/sdl/consumer_sdl.c b/src/modules/sdl/consumer_sdl.c index c1ded3cf0..fd71201ff 100644 --- a/src/modules/sdl/consumer_sdl.c +++ b/src/modules/sdl/consumer_sdl.c @@ -690,7 +690,7 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) } else if ( self->running ) { - vfmt = preview_format == mlt_image_none ? mlt_image_rgb24a : preview_format; + vfmt = preview_format == mlt_image_none ? mlt_image_rgba : preview_format; if ( !video_off ) mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); diff --git a/src/modules/sdl/consumer_sdl_still.c b/src/modules/sdl/consumer_sdl_still.c index 87a99f862..352392669 100644 --- a/src/modules/sdl/consumer_sdl_still.c +++ b/src/modules/sdl/consumer_sdl_still.c @@ -366,7 +366,7 @@ static int consumer_play_video( consumer_sdl this, mlt_frame frame ) // Get the properties of this consumer mlt_properties properties = this->properties; - mlt_image_format vfmt = mlt_image_rgb24a; + mlt_image_format vfmt = mlt_image_rgba; int height = this->height; int width = this->width; uint8_t *image = NULL; @@ -558,7 +558,7 @@ static void *consumer_thread( void *arg ) } else { - mlt_image_format vfmt = mlt_image_rgb24a; + mlt_image_format vfmt = mlt_image_rgba; int height = this->height; int width = this->width; uint8_t *image = NULL; diff --git a/src/modules/sdl/producer_sdl_image.c b/src/modules/sdl/producer_sdl_image.c index e889486fc..24742590e 100644 --- a/src/modules/sdl/producer_sdl_image.c +++ b/src/modules/sdl/producer_sdl_image.c @@ -59,13 +59,13 @@ static int producer_get_image( mlt_frame frame, uint8_t **image, mlt_image_forma switch( surface->format->BitsPerPixel ) { case 32: - *format = mlt_image_rgb24a; + *format = mlt_image_rgba; image_size = *width * *height * 4; *image = mlt_pool_alloc( image_size ); memcpy( *image, surface->pixels, image_size ); break; default: - *format = mlt_image_rgb24; + *format = mlt_image_rgb; *image = mlt_pool_alloc( image_size ); memcpy( *image, surface->pixels, image_size ); break; diff --git a/src/modules/sdl2/consumer_sdl2.c b/src/modules/sdl2/consumer_sdl2.c index 44c8b8c3f..d31eec999 100644 --- a/src/modules/sdl2/consumer_sdl2.c +++ b/src/modules/sdl2/consumer_sdl2.c @@ -518,10 +518,10 @@ static int setup_sdl_video( consumer_sdl self ) int image_format = mlt_properties_get_int( self->properties, "mlt_image_format" ); if ( image_format ) switch ( image_format ) { - case mlt_image_rgb24: + case mlt_image_rgb: texture_format = SDL_PIXELFORMAT_RGB24; break; - case mlt_image_rgb24a: + case mlt_image_rgba: texture_format = SDL_PIXELFORMAT_ABGR8888; break; case mlt_image_yuv420p: @@ -681,7 +681,7 @@ static int consumer_play_video( consumer_sdl self, mlt_frame frame ) { if ( !video_off ) { mlt_image_format preview_format = mlt_properties_get_int( properties, "preview_format" ); - vfmt = preview_format == mlt_image_none ? mlt_image_rgb24a : preview_format; + vfmt = preview_format == mlt_image_none ? mlt_image_rgba : preview_format; mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 ); } mlt_events_fire( properties, "consumer-frame-show", mlt_event_data_from_frame(frame) ); diff --git a/src/tests/test_filter/test_filter.cpp b/src/tests/test_filter/test_filter.cpp index 68f9112be..1fb354886 100644 --- a/src/tests/test_filter/test_filter.cpp +++ b/src/tests/test_filter/test_filter.cpp @@ -47,7 +47,7 @@ private Q_SLOTS: Filter filter(profile, "resize"); int width = 0; int height = 0; - mlt_image_format format = mlt_image_rgb24; + mlt_image_format format = mlt_image_rgb; // Get a frame from the producer Frame* frame = producer.get_frame(); diff --git a/src/tests/test_image/test_image.cpp b/src/tests/test_image/test_image.cpp index d6c8b755f..c2d74c4d6 100644 --- a/src/tests/test_image/test_image.cpp +++ b/src/tests/test_image/test_image.cpp @@ -50,13 +50,13 @@ private Q_SLOTS: void ConstructAndAlloc() { - Image i(1920, 1080, mlt_image_rgb24 ); + Image i(1920, 1080, mlt_image_rgb ); QVERIFY(i.plane(0) != nullptr); } void PlaneAndStrideRgb24() { - Image i(1920, 1080, mlt_image_rgb24 ); + Image i(1920, 1080, mlt_image_rgb ); QVERIFY(i.plane(0) != nullptr); QCOMPARE(i.stride(0), 1920 * 3); QVERIFY(i.plane(1) == nullptr); @@ -69,7 +69,7 @@ private Q_SLOTS: void PlaneAndStrideRgb24a() { - Image i(1920, 1080, mlt_image_rgb24a ); + Image i(1920, 1080, mlt_image_rgba ); QVERIFY(i.plane(0) != nullptr); QCOMPARE(i.stride(0), 1920 * 4); QVERIFY(i.plane(1) == nullptr); @@ -121,14 +121,14 @@ private Q_SLOTS: void GetSetColorspace() { - Image i(1920, 1080, mlt_image_rgb24 ); + Image i(1920, 1080, mlt_image_rgb ); i.set_colorspace(mlt_colorspace_bt709); QCOMPARE(i.colorspace(), mlt_colorspace_bt709); } void InitAlpha() { - Image i(1920, 1080, mlt_image_rgb24 ); + Image i(1920, 1080, mlt_image_rgb ); i.init_alpha(); QVERIFY(i.plane(3) != nullptr); } From 26d9472d19b211de9a39a5b4b512a02fcb5766a9 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 14 Mar 2021 18:11:29 -0500 Subject: [PATCH 069/122] Rename mlt_image_glsl as mlt_image_movit --- src/framework/mlt_consumer.c | 6 ++-- src/framework/mlt_frame.c | 4 +-- src/framework/mlt_image.c | 30 +++++++++---------- src/framework/mlt_types.h | 16 +++++----- src/modules/avformat/filter_avfilter.c | 4 +-- src/modules/avformat/producer_avformat.c | 2 +- src/modules/core/producer_colour.c | 8 ++--- src/modules/gdk/producer_pixbuf.c | 4 +-- src/modules/opengl/consumer_xgl.c | 2 +- src/modules/opengl/filter_movit_blur.cpp | 2 +- src/modules/opengl/filter_movit_convert.cpp | 12 ++++---- src/modules/opengl/filter_movit_crop.cpp | 6 ++-- .../filter_movit_deconvolution_sharpen.cpp | 2 +- src/modules/opengl/filter_movit_diffusion.cpp | 2 +- src/modules/opengl/filter_movit_flip.cpp | 2 +- src/modules/opengl/filter_movit_glow.cpp | 2 +- .../opengl/filter_movit_lift_gamma_gain.cpp | 2 +- src/modules/opengl/filter_movit_mirror.cpp | 2 +- src/modules/opengl/filter_movit_opacity.cpp | 2 +- src/modules/opengl/filter_movit_resample.cpp | 2 +- src/modules/opengl/filter_movit_resize.cpp | 2 +- .../opengl/filter_movit_saturation.cpp | 2 +- src/modules/opengl/filter_movit_vignette.cpp | 2 +- .../opengl/filter_movit_white_balance.cpp | 2 +- src/modules/opengl/transition_movit_luma.cpp | 4 +-- src/modules/opengl/transition_movit_mix.cpp | 2 +- .../opengl/transition_movit_overlay.cpp | 2 +- src/modules/qt/kdenlivetitle_wrapper.cpp | 2 +- src/modules/qt/qimage_wrapper.cpp | 4 +-- 29 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/framework/mlt_consumer.c b/src/framework/mlt_consumer.c index a57233ee6..43e69bbff 100644 --- a/src/framework/mlt_consumer.c +++ b/src/framework/mlt_consumer.c @@ -459,11 +459,11 @@ static void set_image_format( mlt_consumer self ) priv->image_format = mlt_image_format_id( format ); if ( mlt_image_invalid == priv->image_format ) priv->image_format = mlt_image_yuv422; - // mlt_image_glsl is for internal use only. + // mlt_image_movit is for internal use only. // Remapping it glsl_texture prevents breaking existing apps // using the legacy "glsl" name. - else if ( mlt_image_glsl == priv->image_format ) - priv->image_format = mlt_image_glsl_texture; + else if ( mlt_image_movit == priv->image_format ) + priv->image_format = mlt_image_opengl_texture; } } diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 3b0de3c84..e93d14934 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -436,8 +436,8 @@ static int generate_test_image( mlt_properties properties, uint8_t **buffer, ml case mlt_image_yuv420p: break; case mlt_image_none: - case mlt_image_glsl: - case mlt_image_glsl_texture: + case mlt_image_movit: + case mlt_image_opengl_texture: *format = mlt_image_yuv422; break; } diff --git a/src/framework/mlt_image.c b/src/framework/mlt_image.c index 081d44522..fd8a786f1 100644 --- a/src/framework/mlt_image.c +++ b/src/framework/mlt_image.c @@ -182,8 +182,8 @@ int mlt_image_calculate_size( mlt_image self ) return self->width * self->height * 2; case mlt_image_yuv420p: return self->width * self->height * 3 / 2; - case mlt_image_glsl: - case mlt_image_glsl_texture: + case mlt_image_movit: + case mlt_image_opengl_texture: return 4; case mlt_image_yuv422p16: return 4 * self->width * self->height; @@ -203,15 +203,15 @@ const char * mlt_image_format_name( mlt_image_format format ) { switch ( format ) { - case mlt_image_none: return "none"; - case mlt_image_rgb: return "rgb"; - case mlt_image_rgba: return "rgba"; - case mlt_image_yuv422: return "yuv422"; - case mlt_image_yuv420p: return "yuv420p"; - case mlt_image_glsl: return "glsl"; - case mlt_image_glsl_texture: return "glsl_texture"; - case mlt_image_yuv422p16: return "yuv422p16"; - case mlt_image_invalid: return "invalid"; + case mlt_image_none: return "none"; + case mlt_image_rgb: return "rgb"; + case mlt_image_rgba: return "rgba"; + case mlt_image_yuv422: return "yuv422"; + case mlt_image_yuv420p: return "yuv420p"; + case mlt_image_movit: return "glsl"; + case mlt_image_opengl_texture: return "opengl_texture"; + case mlt_image_yuv422p16: return "yuv422p16"; + case mlt_image_invalid: return "invalid"; } return "invalid"; } @@ -248,8 +248,8 @@ void mlt_image_fill_black( mlt_image self ) switch( self->format ) { case mlt_image_none: - case mlt_image_glsl: - case mlt_image_glsl_texture: + case mlt_image_movit: + case mlt_image_opengl_texture: return; case mlt_image_rgb: case mlt_image_rgba: @@ -330,8 +330,8 @@ int mlt_image_format_size( mlt_image_format format, int width, int height, int * case mlt_image_yuv420p: if ( bpp ) *bpp = 3 / 2; return width * height * 3 / 2; - case mlt_image_glsl: - case mlt_image_glsl_texture: + case mlt_image_movit: + case mlt_image_opengl_texture: if ( bpp ) *bpp = 0; return 4; case mlt_image_yuv422p16: diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index ce6b44d35..9e0db8510 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -44,14 +44,14 @@ extern "C" typedef enum { - mlt_image_none = 0,/**< image not available */ - mlt_image_rgb, /**< 8-bit RGB */ - mlt_image_rgba, /**< 8-bit RGB with alpha channel */ - mlt_image_yuv422, /**< 8-bit YUV 4:2:2 packed */ - mlt_image_yuv420p, /**< 8-bit YUV 4:2:0 planar */ - mlt_image_glsl, /**< for opengl module internal use only */ - mlt_image_glsl_texture, /**< an OpenGL texture name */ - mlt_image_yuv422p16, /**< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian */ + mlt_image_none = 0, /**< image not available */ + mlt_image_rgb, /**< 8-bit RGB */ + mlt_image_rgba, /**< 8-bit RGB with alpha channel */ + mlt_image_yuv422, /**< 8-bit YUV 4:2:2 packed */ + mlt_image_yuv420p, /**< 8-bit YUV 4:2:0 planar */ + mlt_image_movit, /**< for movit module internal use only */ + mlt_image_opengl_texture, /**< an OpenGL texture name */ + mlt_image_yuv422p16, /**< planar YUV 4:2:2, 32bpp, (1 Cr & Cb sample per 2x1 Y samples), little-endian */ mlt_image_invalid } mlt_image_format; diff --git a/src/modules/avformat/filter_avfilter.c b/src/modules/avformat/filter_avfilter.c index ba9311364..dc097e163 100644 --- a/src/modules/avformat/filter_avfilter.c +++ b/src/modules/avformat/filter_avfilter.c @@ -107,8 +107,8 @@ static mlt_image_format get_supported_image_format( mlt_image_format format ) mlt_log_error(NULL, "[filter_avfilter] Unknown image format requested: %d\n", format ); case mlt_image_none: case mlt_image_yuv422: - case mlt_image_glsl: - case mlt_image_glsl_texture: + case mlt_image_movit: + case mlt_image_opengl_texture: return mlt_image_yuv422; } } diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index 5c00d9473..620e4ea2b 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -1769,7 +1769,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form stream = context->streams[ self->video_index ]; codec_context = stream->codec; codec_params = stream->codecpar; - if ( *format == mlt_image_none || *format == mlt_image_glsl || + if ( *format == mlt_image_none || *format == mlt_image_movit || codec_params->format == AV_PIX_FMT_ARGB || codec_params->format == AV_PIX_FMT_RGBA || codec_params->format == AV_PIX_FMT_ABGR || diff --git a/src/modules/core/producer_colour.c b/src/modules/core/producer_colour.c index 58ceb1837..8e7897465 100644 --- a/src/modules/core/producer_colour.c +++ b/src/modules/core/producer_colour.c @@ -91,7 +91,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form *format = mlt_image_format_id( mlt_properties_get( producer_props, "mlt_image_format") ); // Choose suitable out values if nothing specific requested - if ( *format == mlt_image_none || *format == mlt_image_glsl ) + if ( *format == mlt_image_none || *format == mlt_image_movit ) *format = mlt_image_rgba; if ( *width <= 0 ) *width = mlt_service_profile( MLT_PRODUCER_SERVICE(producer) )->width; @@ -99,7 +99,7 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form *height = mlt_service_profile( MLT_PRODUCER_SERVICE(producer) )->height; // Choose default image format if specific request is unsupported - if (*format!=mlt_image_yuv420p && *format!=mlt_image_yuv422 && *format!=mlt_image_rgb && *format!= mlt_image_glsl && *format!= mlt_image_glsl_texture) + if (*format!=mlt_image_yuv420p && *format!=mlt_image_yuv422 && *format!=mlt_image_rgb && *format!= mlt_image_movit && *format!= mlt_image_opengl_texture) *format = mlt_image_rgba; // See if we need to regenerate @@ -171,8 +171,8 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form *p ++ = color.b; } break; - case mlt_image_glsl: - case mlt_image_glsl_texture: + case mlt_image_movit: + case mlt_image_opengl_texture: memset(p, 0, size); break; case mlt_image_rgba: diff --git a/src/modules/gdk/producer_pixbuf.c b/src/modules/gdk/producer_pixbuf.c index 29b7a58a0..3bdd70030 100644 --- a/src/modules/gdk/producer_pixbuf.c +++ b/src/modules/gdk/producer_pixbuf.c @@ -577,7 +577,7 @@ static void refresh_image( producer_pixbuf self, mlt_frame frame, mlt_image_form self->image, self->pixbuf, current_idx, self->image_idx, self->pixbuf_idx, width ); // If we have a pixbuf and we need an image - if ( self->pixbuf && ( !self->image || ( format != mlt_image_none && format != mlt_image_glsl && format != self->format ) ) ) + if ( self->pixbuf && ( !self->image || ( format != mlt_image_none && format != mlt_image_movit && format != self->format ) ) ) { char *interps = mlt_properties_get( properties, "rescale.interp" ); if ( interps ) interps = strdup( interps ); @@ -630,7 +630,7 @@ static void refresh_image( producer_pixbuf self, mlt_frame frame, mlt_image_form pthread_mutex_unlock( &g_mutex ); // Convert image to requested format - if ( format != mlt_image_none && format != mlt_image_glsl && format != self->format && frame->convert_image ) + if ( format != mlt_image_none && format != mlt_image_movit && format != self->format && frame->convert_image ) { // cache copies of the image and alpha buffers uint8_t *buffer = self->image; diff --git a/src/modules/opengl/consumer_xgl.c b/src/modules/opengl/consumer_xgl.c index 3c6af4f42..1bc539a35 100644 --- a/src/modules/opengl/consumer_xgl.c +++ b/src/modules/opengl/consumer_xgl.c @@ -264,7 +264,7 @@ void* video_thread( void *arg ) if ( mlt_properties_get_int( properties, "rendered" ) == 1 ) { // Get the image, width and height - mlt_image_format vfmt = mlt_image_glsl_texture; + mlt_image_format vfmt = mlt_image_opengl_texture; int width = 0, height = 0; GLuint *image = 0; int error = mlt_frame_get_image( next, (uint8_t**) &image, &vfmt, &width, &height, 0 ); diff --git a/src/modules/opengl/filter_movit_blur.cpp b/src/modules/opengl/filter_movit_blur.cpp index c7339bc0a..23dc958cf 100644 --- a/src/modules/opengl/filter_movit_blur.cpp +++ b/src/modules/opengl/filter_movit_blur.cpp @@ -36,7 +36,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_filter_get_length2( filter, frame ) ); mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter)); GlslManager::get_instance()->unlock_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_convert.cpp b/src/modules/opengl/filter_movit_convert.cpp index 6913dca62..cc974efd2 100644 --- a/src/modules/opengl/filter_movit_convert.cpp +++ b/src/modules/opengl/filter_movit_convert.cpp @@ -454,7 +454,7 @@ static int movit_render( EffectChain *chain, mlt_frame frame, mlt_image_format * GlslManager* glsl = GlslManager::get_instance(); int error; - if ( output_format == mlt_image_glsl_texture ) { + if ( output_format == mlt_image_opengl_texture ) { error = glsl->render_frame_texture( chain, frame, width, height, image ); } else { @@ -540,7 +540,7 @@ static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *fo return convert_on_cpu( frame, image, format, output_format ); // Do non-GL image conversions on a CPU-based image converter. - if ( *format != mlt_image_glsl && output_format != mlt_image_glsl && output_format != mlt_image_glsl_texture ) + if ( *format != mlt_image_movit && output_format != mlt_image_movit && output_format != mlt_image_opengl_texture ) return convert_on_cpu( frame, image, format, output_format ); int error = 0; @@ -556,7 +556,7 @@ static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *fo // If we're at the beginning of a series of Movit effects, store the input // sent into the chain. - if ( output_format == mlt_image_glsl ) { + if ( output_format == mlt_image_movit ) { mlt_producer producer = mlt_producer_cut_parent( mlt_frame_get_original_producer( frame ) ); mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ); MltInput *input = create_input( properties, *format, profile->width, profile->height, width, height ); @@ -580,7 +580,7 @@ static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *fo } // If we're at the _end_ of a series of Movit effects, render the chain. - if ( *format == mlt_image_glsl ) { + if ( *format == mlt_image_movit ) { mlt_service leaf_service = (mlt_service) *image; if ( leaf_service == (mlt_service) -1 ) { @@ -611,8 +611,8 @@ static int convert_image( mlt_frame frame, uint8_t **image, mlt_image_format *fo // If we've been asked to render some frame directly to a texture (without any // effects in-between), we create a new mini-chain to do so. - if ( *format != mlt_image_glsl && output_format == mlt_image_glsl_texture ) { - // We might already have a texture from a previous conversion from mlt_image_glsl. + if ( *format != mlt_image_movit && output_format == mlt_image_opengl_texture ) { + // We might already have a texture from a previous conversion from mlt_image_movit. glsl_texture texture = (glsl_texture) mlt_properties_get_data( properties, "movit.convert.texture", NULL ); // XXX: requires a special property set on the frame by the app for now // because we do not have reliable way to clear the texture property diff --git a/src/modules/opengl/filter_movit_crop.cpp b/src/modules/opengl/filter_movit_crop.cpp index 6e2d83906..04f4c8a26 100644 --- a/src/modules/opengl/filter_movit_crop.cpp +++ b/src/modules/opengl/filter_movit_crop.cpp @@ -60,7 +60,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format // Get the image as requested // *format = (mlt_image_format) mlt_properties_get_int( MLT_PRODUCER_PROPERTIES(producer), "_movit image_format" ); - // This is needed to prevent conversion to mlt_image_glsl after producer, + // This is needed to prevent conversion to mlt_image_movit after producer, // deinterlace, or fieldorder, The latter two can force output of // an image after it had already been converted to glsl. *format = mlt_image_none; @@ -71,10 +71,10 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format if ( requested_format == mlt_image_none ) return error; - if ( !error && *format != mlt_image_glsl && frame->convert_image ) { + if ( !error && *format != mlt_image_movit && frame->convert_image ) { // Pin the requested format to the first one returned. // mlt_properties_set_int( MLT_PRODUCER_PROPERTIES(producer), "_movit image_format", *format ); - error = frame->convert_image( frame, image, format, mlt_image_glsl ); + error = frame->convert_image( frame, image, format, mlt_image_movit ); } if ( !error ) { double left = mlt_properties_get_double( properties, "crop.left" ); diff --git a/src/modules/opengl/filter_movit_deconvolution_sharpen.cpp b/src/modules/opengl/filter_movit_deconvolution_sharpen.cpp index 045ac0977..b836dd095 100644 --- a/src/modules/opengl/filter_movit_deconvolution_sharpen.cpp +++ b/src/modules/opengl/filter_movit_deconvolution_sharpen.cpp @@ -55,7 +55,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_properties_set( properties, "_movit fingerprint", fingerprint ); GlslManager::get_instance()->unlock_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_diffusion.cpp b/src/modules/opengl/filter_movit_diffusion.cpp index 8f061a3bd..0b54c2887 100644 --- a/src/modules/opengl/filter_movit_diffusion.cpp +++ b/src/modules/opengl/filter_movit_diffusion.cpp @@ -39,7 +39,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_properties_set_double( properties, "_movit.parms.float.blurred_mix_amount", mlt_properties_anim_get_double( properties, "mix", position, length ) ); GlslManager::get_instance()->unlock_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_flip.cpp b/src/modules/opengl/filter_movit_flip.cpp index f62645030..77001b500 100644 --- a/src/modules/opengl/filter_movit_flip.cpp +++ b/src/modules/opengl/filter_movit_flip.cpp @@ -31,7 +31,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format { mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_glow.cpp b/src/modules/opengl/filter_movit_glow.cpp index 060b9e98b..2922dc694 100644 --- a/src/modules/opengl/filter_movit_glow.cpp +++ b/src/modules/opengl/filter_movit_glow.cpp @@ -42,7 +42,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_properties_set_double( properties, "_movit.parms.float.highlight_cutoff", mlt_properties_anim_get_double( properties, "highlight_cutoff", position, length ) ); GlslManager::get_instance()->unlock_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_lift_gamma_gain.cpp b/src/modules/opengl/filter_movit_lift_gamma_gain.cpp index b98c59c98..20e60baad 100644 --- a/src/modules/opengl/filter_movit_lift_gamma_gain.cpp +++ b/src/modules/opengl/filter_movit_lift_gamma_gain.cpp @@ -53,7 +53,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_properties_set_double( properties, "_movit.parms.vec3.gain[2]", mlt_properties_anim_get_double( properties, "gain_b", position, length ) ); GlslManager::get_instance()->unlock_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_mirror.cpp b/src/modules/opengl/filter_movit_mirror.cpp index b0103e53a..c6a03be7d 100644 --- a/src/modules/opengl/filter_movit_mirror.cpp +++ b/src/modules/opengl/filter_movit_mirror.cpp @@ -30,7 +30,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format { mlt_filter filter = (mlt_filter) mlt_frame_pop_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_opacity.cpp b/src/modules/opengl/filter_movit_opacity.cpp index 09f371b92..655029b00 100644 --- a/src/modules/opengl/filter_movit_opacity.cpp +++ b/src/modules/opengl/filter_movit_opacity.cpp @@ -41,7 +41,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_properties_set_double( properties, "_movit.parms.vec4.factor[2]", opacity ); mlt_properties_set_double( properties, "_movit.parms.vec4.factor[3]", alpha >= 0 ? alpha : opacity ); GlslManager::get_instance()->unlock_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_resample.cpp b/src/modules/opengl/filter_movit_resample.cpp index d73cda1b3..749253bcc 100644 --- a/src/modules/opengl/filter_movit_resample.cpp +++ b/src/modules/opengl/filter_movit_resample.cpp @@ -76,7 +76,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format // Get the image as requested if ( *format != mlt_image_none ) - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, &iwidth, &iheight, writable ); if (*width < 1 || *height < 1 || iwidth < 1 || iheight < 1 || owidth < 1 || oheight < 1) { diff --git a/src/modules/opengl/filter_movit_resize.cpp b/src/modules/opengl/filter_movit_resize.cpp index 883c0dac9..4742b30ba 100644 --- a/src/modules/opengl/filter_movit_resize.cpp +++ b/src/modules/opengl/filter_movit_resize.cpp @@ -150,7 +150,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_properties_set_int( properties, "distort", 0 ); // Now get the image - *format = mlt_image_glsl; + *format = mlt_image_movit; error = mlt_frame_get_image( frame, image, format, &owidth, &oheight, writable ); // Offset the position according to alignment diff --git a/src/modules/opengl/filter_movit_saturation.cpp b/src/modules/opengl/filter_movit_saturation.cpp index 5d80381f8..153150171 100644 --- a/src/modules/opengl/filter_movit_saturation.cpp +++ b/src/modules/opengl/filter_movit_saturation.cpp @@ -37,7 +37,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_properties_set_double( properties, "_movit.parms.float.saturation", mlt_properties_anim_get_double( properties, "saturation", position, length ) ); GlslManager::get_instance()->unlock_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_vignette.cpp b/src/modules/opengl/filter_movit_vignette.cpp index 6b6797c26..da881ed80 100644 --- a/src/modules/opengl/filter_movit_vignette.cpp +++ b/src/modules/opengl/filter_movit_vignette.cpp @@ -39,7 +39,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_properties_set_double( properties, "_movit.parms.float.inner_radius", mlt_properties_anim_get_double( properties, "inner_radius", position, length ) ); GlslManager::get_instance()->unlock_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/filter_movit_white_balance.cpp b/src/modules/opengl/filter_movit_white_balance.cpp index 9cc009732..83ce4facc 100644 --- a/src/modules/opengl/filter_movit_white_balance.cpp +++ b/src/modules/opengl/filter_movit_white_balance.cpp @@ -59,7 +59,7 @@ static int get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format mlt_properties_set_double( properties, "_movit.parms.float.output_color_temperature", output_color_temperature ); GlslManager::get_instance()->unlock_service( frame ); - *format = mlt_image_glsl; + *format = mlt_image_movit; int error = mlt_frame_get_image( frame, image, format, width, height, writable ); if (*width < 1 || *height < 1) { diff --git a/src/modules/opengl/transition_movit_luma.cpp b/src/modules/opengl/transition_movit_luma.cpp index f398d433a..0cf495387 100644 --- a/src/modules/opengl/transition_movit_luma.cpp +++ b/src/modules/opengl/transition_movit_luma.cpp @@ -69,7 +69,7 @@ static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *form uint8_t *a_image, *b_image, *c_image; // Get the images. - *format = mlt_image_glsl; + *format = mlt_image_movit; error = mlt_frame_get_image( a_frame, &a_image, format, width, height, writable ); error = mlt_frame_get_image( b_frame, &b_image, format, width, height, writable ); error = mlt_frame_get_image( c_frame, &c_image, format, width, height, writable ); @@ -96,7 +96,7 @@ static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *form uint8_t *a_image, *b_image; // Get the two images. - *format = mlt_image_glsl; + *format = mlt_image_movit; error = mlt_frame_get_image( a_frame, &a_image, format, width, height, writable ); error = mlt_frame_get_image( b_frame, &b_image, format, width, height, writable ); diff --git a/src/modules/opengl/transition_movit_mix.cpp b/src/modules/opengl/transition_movit_mix.cpp index 41b282fa7..bf4c6ad59 100644 --- a/src/modules/opengl/transition_movit_mix.cpp +++ b/src/modules/opengl/transition_movit_mix.cpp @@ -64,7 +64,7 @@ static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *form uint8_t *a_image, *b_image; // Get the two images. - *format = mlt_image_glsl; + *format = mlt_image_movit; error = mlt_frame_get_image( a_frame, &a_image, format, width, height, writable ); error = mlt_frame_get_image( b_frame, &b_image, format, width, height, writable ); diff --git a/src/modules/opengl/transition_movit_overlay.cpp b/src/modules/opengl/transition_movit_overlay.cpp index 2c1e883f9..535fd9143 100644 --- a/src/modules/opengl/transition_movit_overlay.cpp +++ b/src/modules/opengl/transition_movit_overlay.cpp @@ -45,7 +45,7 @@ static int get_image( mlt_frame a_frame, uint8_t **image, mlt_image_format *form uint8_t *a_image, *b_image; // Get the two images. - *format = mlt_image_glsl; + *format = mlt_image_movit; error = mlt_frame_get_image( a_frame, &a_image, format, width, height, writable ); error = mlt_frame_get_image( b_frame, &b_image, format, width, height, writable ); diff --git a/src/modules/qt/kdenlivetitle_wrapper.cpp b/src/modules/qt/kdenlivetitle_wrapper.cpp index 5d12de061..2f5cac303 100755 --- a/src/modules/qt/kdenlivetitle_wrapper.cpp +++ b/src/modules/qt/kdenlivetitle_wrapper.cpp @@ -832,7 +832,7 @@ void drawKdenliveTitle( producer_ktitle self, mlt_frame frame, mlt_image_format } // Convert image to requested format - if ( format != mlt_image_none && format != mlt_image_glsl && format != self->format ) + if ( format != mlt_image_none && format != mlt_image_movit && format != self->format ) { uint8_t *buffer = NULL; if ( self->format != mlt_image_rgba ) { diff --git a/src/modules/qt/qimage_wrapper.cpp b/src/modules/qt/qimage_wrapper.cpp index 3a88838e0..e0277ff0a 100644 --- a/src/modules/qt/qimage_wrapper.cpp +++ b/src/modules/qt/qimage_wrapper.cpp @@ -243,7 +243,7 @@ void refresh_image( producer_qimage self, mlt_frame frame, mlt_image_format form self->current_image = NULL; // If we have a qimage and need a new scaled image - if ( self->qimage && ( !self->current_image || ( format != mlt_image_none && format != mlt_image_glsl && format != self->format ) ) ) + if ( self->qimage && ( !self->current_image || ( format != mlt_image_none && format != mlt_image_movit && format != self->format ) ) ) { QString interps = mlt_properties_get( properties, "rescale.interp" ); bool interp = ( interps != "nearest" ) && ( interps != "none" ); @@ -334,7 +334,7 @@ void refresh_image( producer_qimage self, mlt_frame frame, mlt_image_format form #endif // Convert image to requested format - if ( format != mlt_image_none && format != mlt_image_glsl && format != self->format && enable_caching ) + if ( format != mlt_image_none && format != mlt_image_movit && format != self->format && enable_caching ) { uint8_t *buffer = NULL; From 56cf37a0fd67b08fc96fd5e089595131073f5919 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 14 Mar 2021 22:07:54 -0500 Subject: [PATCH 070/122] Rename opengl module to movit --- CMakeLists.txt | 8 ++++---- docs/install.txt | 4 ++-- src/modules/CMakeLists.txt | 4 ++-- src/modules/{opengl => movit}/CMakeLists.txt | 14 +++++++------- src/modules/{opengl => movit}/Makefile | 6 +++--- src/modules/{opengl => movit}/configure | 2 +- src/modules/{opengl => movit}/consumer_xgl.c | 0 src/modules/{opengl => movit}/factory.c | 2 +- .../{opengl => movit}/filter_glsl_manager.cpp | 0 .../{opengl => movit}/filter_glsl_manager.h | 0 .../{opengl => movit}/filter_movit_blur.cpp | 0 .../{opengl => movit}/filter_movit_blur.yml | 0 .../{opengl => movit}/filter_movit_convert.cpp | 0 .../{opengl => movit}/filter_movit_crop.cpp | 0 .../filter_movit_deconvolution_sharpen.cpp | 0 .../filter_movit_deconvolution_sharpen.yml | 0 .../{opengl => movit}/filter_movit_diffusion.cpp | 0 .../{opengl => movit}/filter_movit_diffusion.yml | 0 .../{opengl => movit}/filter_movit_flip.cpp | 0 .../{opengl => movit}/filter_movit_flip.yml | 0 .../{opengl => movit}/filter_movit_glow.cpp | 0 .../{opengl => movit}/filter_movit_glow.yml | 0 .../filter_movit_lift_gamma_gain.cpp | 0 .../filter_movit_lift_gamma_gain.yml | 0 .../{opengl => movit}/filter_movit_mirror.cpp | 0 .../{opengl => movit}/filter_movit_mirror.yml | 0 .../{opengl => movit}/filter_movit_opacity.cpp | 0 .../{opengl => movit}/filter_movit_opacity.yml | 0 .../{opengl => movit}/filter_movit_rect.cpp | 0 .../{opengl => movit}/filter_movit_rect.yml | 0 .../{opengl => movit}/filter_movit_resample.cpp | 0 .../{opengl => movit}/filter_movit_resize.cpp | 0 .../{opengl => movit}/filter_movit_saturation.cpp | 0 .../{opengl => movit}/filter_movit_saturation.yml | 0 .../{opengl => movit}/filter_movit_vignette.cpp | 0 .../{opengl => movit}/filter_movit_vignette.yml | 0 .../filter_movit_white_balance.cpp | 0 .../filter_movit_white_balance.yml | 0 src/modules/{opengl => movit}/mlt_flip_effect.h | 0 src/modules/{opengl => movit}/mlt_movit_input.cpp | 0 src/modules/{opengl => movit}/mlt_movit_input.h | 0 src/modules/{opengl => movit}/optional_effect.h | 0 .../{opengl => movit}/transition_movit_luma.cpp | 0 .../{opengl => movit}/transition_movit_luma.yml | 0 .../{opengl => movit}/transition_movit_mix.cpp | 0 .../{opengl => movit}/transition_movit_mix.yml | 0 .../{opengl => movit}/transition_movit_overlay.cpp | 0 .../{opengl => movit}/transition_movit_overlay.yml | 0 48 files changed, 20 insertions(+), 20 deletions(-) rename src/modules/{opengl => movit}/CMakeLists.txt (70%) rename src/modules/{opengl => movit}/Makefile (93%) rename src/modules/{opengl => movit}/configure (89%) rename src/modules/{opengl => movit}/consumer_xgl.c (100%) rename src/modules/{opengl => movit}/factory.c (98%) rename src/modules/{opengl => movit}/filter_glsl_manager.cpp (100%) rename src/modules/{opengl => movit}/filter_glsl_manager.h (100%) rename src/modules/{opengl => movit}/filter_movit_blur.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_blur.yml (100%) rename src/modules/{opengl => movit}/filter_movit_convert.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_crop.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_deconvolution_sharpen.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_deconvolution_sharpen.yml (100%) rename src/modules/{opengl => movit}/filter_movit_diffusion.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_diffusion.yml (100%) rename src/modules/{opengl => movit}/filter_movit_flip.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_flip.yml (100%) rename src/modules/{opengl => movit}/filter_movit_glow.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_glow.yml (100%) rename src/modules/{opengl => movit}/filter_movit_lift_gamma_gain.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_lift_gamma_gain.yml (100%) rename src/modules/{opengl => movit}/filter_movit_mirror.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_mirror.yml (100%) rename src/modules/{opengl => movit}/filter_movit_opacity.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_opacity.yml (100%) rename src/modules/{opengl => movit}/filter_movit_rect.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_rect.yml (100%) rename src/modules/{opengl => movit}/filter_movit_resample.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_resize.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_saturation.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_saturation.yml (100%) rename src/modules/{opengl => movit}/filter_movit_vignette.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_vignette.yml (100%) rename src/modules/{opengl => movit}/filter_movit_white_balance.cpp (100%) rename src/modules/{opengl => movit}/filter_movit_white_balance.yml (100%) rename src/modules/{opengl => movit}/mlt_flip_effect.h (100%) rename src/modules/{opengl => movit}/mlt_movit_input.cpp (100%) rename src/modules/{opengl => movit}/mlt_movit_input.h (100%) rename src/modules/{opengl => movit}/optional_effect.h (100%) rename src/modules/{opengl => movit}/transition_movit_luma.cpp (100%) rename src/modules/{opengl => movit}/transition_movit_luma.yml (100%) rename src/modules/{opengl => movit}/transition_movit_mix.cpp (100%) rename src/modules/{opengl => movit}/transition_movit_mix.yml (100%) rename src/modules/{opengl => movit}/transition_movit_overlay.cpp (100%) rename src/modules/{opengl => movit}/transition_movit_overlay.yml (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 751e7cf44..381541b05 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ option(MOD_NDI "Enable NDI module" OFF) option(MOD_NORMALIZE "Enable normalize module" ON) option(MOD_OLDFILM "Enable oldfilm module" ON) option(MOD_OPENCV "Enable OpenCV module" OFF) -option(MOD_OPENGL "Enable OpenGL module" ON) +option(MOD_MOVIT "Enable OpenGL module" ON) option(MOD_PLUS "Enable plus module" ON) option(MOD_PLUSGPL "Enable plus GPL module" ON) option(MOD_QT "Enable Qt module" ON) @@ -252,16 +252,16 @@ if(MOD_OPENCV) endif() endif() -if(MOD_OPENGL) +if(MOD_MOVIT) pkg_check_modules(movit IMPORTED_TARGET movit) find_package(OpenGL) if(TARGET PkgConfig::movit AND TARGET OpenGL::GL) if(UNIX AND NOT APPLE) find_package(X11 REQUIRED) endif() - list(APPEND MLT_SUPPORTED_COMPONENTS opengl) + list(APPEND MLT_SUPPORTED_COMPONENTS movit) else() - set(MOD_OPENGL OFF) + set(MOD_MOVIT OFF) endif() endif() diff --git a/docs/install.txt b/docs/install.txt index c69c371ae..831711a97 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -33,7 +33,7 @@ Last Revision: 2013-09-07 * motion_est - motion estimation-based filters (*) * normalize - audio normalisation functions (*) * oldfilm - filters to make pristine video dirty - * opengl - !OpenGL dependent services (*) + * movit - Movit dependent services (*) * plus - miscellaneous services (pending move to core) * qt - Qt dependent services (*) * resample - libresample dependent services (*) @@ -71,7 +71,7 @@ Last Revision: 2013-09-07 | *Module* | *Description* | | avformat | [[http://www.ffmpeg.org][FFmpeg]] v4.0 or later | | jackrack | [[http://jackaudio.org][JACK]], [[http://www.xmlsoft.org/][libxml2]], and ladspa.h | - | opengl | [[http://git.sesse.net/movit][Movit]] | + | movit | [[http://git.sesse.net/movit][Movit]] | | qt | [[http://www.qt-project.org][Qt]] 4.4 or later | | resample | [[http://www.mega-nerd.com/SRC][libsamplerate]] 0.15 or later | | sdl | [[http://www.libsdl.org][SDL]] 1.2 or later | diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index f81b1db0f..8844542c1 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -44,8 +44,8 @@ if(MOD_OPENCV) add_subdirectory(opencv) endif() -if(MOD_OPENGL) - add_subdirectory(opengl) +if(MOD_MOVIT) + add_subdirectory(movit) endif() if(MOD_PLUS) diff --git a/src/modules/opengl/CMakeLists.txt b/src/modules/movit/CMakeLists.txt similarity index 70% rename from src/modules/opengl/CMakeLists.txt rename to src/modules/movit/CMakeLists.txt index 4389e0aa4..e4fd4fe29 100644 --- a/src/modules/opengl/CMakeLists.txt +++ b/src/modules/movit/CMakeLists.txt @@ -1,4 +1,4 @@ -add_library(mltopengl MODULE +add_library(mltmovit MODULE consumer_xgl.c factory.c filter_glsl_manager.cpp @@ -24,20 +24,20 @@ add_library(mltopengl MODULE transition_movit_overlay.cpp ) -target_compile_options(mltopengl PRIVATE ${MLT_COMPILE_OPTIONS}) +target_compile_options(mltmovit PRIVATE ${MLT_COMPILE_OPTIONS}) -target_link_libraries(mltopengl PRIVATE m Threads::Threads mlt mlt++ OpenGL::GL PkgConfig::movit) +target_link_libraries(mltmovit PRIVATE m Threads::Threads mlt mlt++ OpenGL::GL PkgConfig::movit) if(UNIX AND NOT APPLE) - target_link_libraries(mltopengl PRIVATE X11::X11) + target_link_libraries(mltmovit PRIVATE X11::X11) endif() pkg_get_variable(SHADERDIR movit shaderdir) -target_compile_definitions(mltopengl PRIVATE SHADERDIR="${SHADERDIR}") +target_compile_definitions(mltmovit PRIVATE SHADERDIR="${SHADERDIR}") -set_target_properties(mltopengl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") +set_target_properties(mltmovit PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltopengl LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) +install(TARGETS mltmovit LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) install(FILES filter_movit_blur.yml diff --git a/src/modules/opengl/Makefile b/src/modules/movit/Makefile similarity index 93% rename from src/modules/opengl/Makefile rename to src/modules/movit/Makefile index b78457ca6..48a2ef281 100644 --- a/src/modules/opengl/Makefile +++ b/src/modules/movit/Makefile @@ -4,7 +4,7 @@ CFLAGS := -I../.. $(CFLAGS) LDFLAGS := -L../../framework -lmlt -lm $(LDFLAGS) -TARGET = ../libmltopengl$(LIBSUF) +TARGET = ../libmltmovit$(LIBSUF) OBJS = factory.o @@ -75,8 +75,8 @@ clean: install: all install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" - install -d "$(DESTDIR)$(mltdatadir)/opengl" - install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/opengl" + install -d "$(DESTDIR)$(mltdatadir)/movit" + install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/movit" ifneq ($(wildcard .depend),) include .depend diff --git a/src/modules/opengl/configure b/src/modules/movit/configure similarity index 89% rename from src/modules/opengl/configure rename to src/modules/movit/configure index 3065ba126..7a4052bcb 100755 --- a/src/modules/opengl/configure +++ b/src/modules/movit/configure @@ -5,7 +5,7 @@ then if ! $(pkg-config movit) then echo "- movit not found: disabling" - touch ../disable-opengl + touch ../disable-movit exit 0 fi diff --git a/src/modules/opengl/consumer_xgl.c b/src/modules/movit/consumer_xgl.c similarity index 100% rename from src/modules/opengl/consumer_xgl.c rename to src/modules/movit/consumer_xgl.c diff --git a/src/modules/opengl/factory.c b/src/modules/movit/factory.c similarity index 98% rename from src/modules/opengl/factory.c rename to src/modules/movit/factory.c index 989c4f29a..ce19b0d3f 100644 --- a/src/modules/opengl/factory.c +++ b/src/modules/movit/factory.c @@ -48,7 +48,7 @@ extern mlt_transition transition_movit_overlay_init( mlt_profile profile, mlt_se static mlt_properties metadata( mlt_service_type type, const char *id, void *data ) { char file[ PATH_MAX ]; - snprintf( file, PATH_MAX, "%s/opengl/%s", mlt_environment( "MLT_DATA" ), (char*) data ); + snprintf( file, PATH_MAX, "%s/movit/%s", mlt_environment( "MLT_DATA" ), (char*) data ); return mlt_properties_parse_yaml( file ); } diff --git a/src/modules/opengl/filter_glsl_manager.cpp b/src/modules/movit/filter_glsl_manager.cpp similarity index 100% rename from src/modules/opengl/filter_glsl_manager.cpp rename to src/modules/movit/filter_glsl_manager.cpp diff --git a/src/modules/opengl/filter_glsl_manager.h b/src/modules/movit/filter_glsl_manager.h similarity index 100% rename from src/modules/opengl/filter_glsl_manager.h rename to src/modules/movit/filter_glsl_manager.h diff --git a/src/modules/opengl/filter_movit_blur.cpp b/src/modules/movit/filter_movit_blur.cpp similarity index 100% rename from src/modules/opengl/filter_movit_blur.cpp rename to src/modules/movit/filter_movit_blur.cpp diff --git a/src/modules/opengl/filter_movit_blur.yml b/src/modules/movit/filter_movit_blur.yml similarity index 100% rename from src/modules/opengl/filter_movit_blur.yml rename to src/modules/movit/filter_movit_blur.yml diff --git a/src/modules/opengl/filter_movit_convert.cpp b/src/modules/movit/filter_movit_convert.cpp similarity index 100% rename from src/modules/opengl/filter_movit_convert.cpp rename to src/modules/movit/filter_movit_convert.cpp diff --git a/src/modules/opengl/filter_movit_crop.cpp b/src/modules/movit/filter_movit_crop.cpp similarity index 100% rename from src/modules/opengl/filter_movit_crop.cpp rename to src/modules/movit/filter_movit_crop.cpp diff --git a/src/modules/opengl/filter_movit_deconvolution_sharpen.cpp b/src/modules/movit/filter_movit_deconvolution_sharpen.cpp similarity index 100% rename from src/modules/opengl/filter_movit_deconvolution_sharpen.cpp rename to src/modules/movit/filter_movit_deconvolution_sharpen.cpp diff --git a/src/modules/opengl/filter_movit_deconvolution_sharpen.yml b/src/modules/movit/filter_movit_deconvolution_sharpen.yml similarity index 100% rename from src/modules/opengl/filter_movit_deconvolution_sharpen.yml rename to src/modules/movit/filter_movit_deconvolution_sharpen.yml diff --git a/src/modules/opengl/filter_movit_diffusion.cpp b/src/modules/movit/filter_movit_diffusion.cpp similarity index 100% rename from src/modules/opengl/filter_movit_diffusion.cpp rename to src/modules/movit/filter_movit_diffusion.cpp diff --git a/src/modules/opengl/filter_movit_diffusion.yml b/src/modules/movit/filter_movit_diffusion.yml similarity index 100% rename from src/modules/opengl/filter_movit_diffusion.yml rename to src/modules/movit/filter_movit_diffusion.yml diff --git a/src/modules/opengl/filter_movit_flip.cpp b/src/modules/movit/filter_movit_flip.cpp similarity index 100% rename from src/modules/opengl/filter_movit_flip.cpp rename to src/modules/movit/filter_movit_flip.cpp diff --git a/src/modules/opengl/filter_movit_flip.yml b/src/modules/movit/filter_movit_flip.yml similarity index 100% rename from src/modules/opengl/filter_movit_flip.yml rename to src/modules/movit/filter_movit_flip.yml diff --git a/src/modules/opengl/filter_movit_glow.cpp b/src/modules/movit/filter_movit_glow.cpp similarity index 100% rename from src/modules/opengl/filter_movit_glow.cpp rename to src/modules/movit/filter_movit_glow.cpp diff --git a/src/modules/opengl/filter_movit_glow.yml b/src/modules/movit/filter_movit_glow.yml similarity index 100% rename from src/modules/opengl/filter_movit_glow.yml rename to src/modules/movit/filter_movit_glow.yml diff --git a/src/modules/opengl/filter_movit_lift_gamma_gain.cpp b/src/modules/movit/filter_movit_lift_gamma_gain.cpp similarity index 100% rename from src/modules/opengl/filter_movit_lift_gamma_gain.cpp rename to src/modules/movit/filter_movit_lift_gamma_gain.cpp diff --git a/src/modules/opengl/filter_movit_lift_gamma_gain.yml b/src/modules/movit/filter_movit_lift_gamma_gain.yml similarity index 100% rename from src/modules/opengl/filter_movit_lift_gamma_gain.yml rename to src/modules/movit/filter_movit_lift_gamma_gain.yml diff --git a/src/modules/opengl/filter_movit_mirror.cpp b/src/modules/movit/filter_movit_mirror.cpp similarity index 100% rename from src/modules/opengl/filter_movit_mirror.cpp rename to src/modules/movit/filter_movit_mirror.cpp diff --git a/src/modules/opengl/filter_movit_mirror.yml b/src/modules/movit/filter_movit_mirror.yml similarity index 100% rename from src/modules/opengl/filter_movit_mirror.yml rename to src/modules/movit/filter_movit_mirror.yml diff --git a/src/modules/opengl/filter_movit_opacity.cpp b/src/modules/movit/filter_movit_opacity.cpp similarity index 100% rename from src/modules/opengl/filter_movit_opacity.cpp rename to src/modules/movit/filter_movit_opacity.cpp diff --git a/src/modules/opengl/filter_movit_opacity.yml b/src/modules/movit/filter_movit_opacity.yml similarity index 100% rename from src/modules/opengl/filter_movit_opacity.yml rename to src/modules/movit/filter_movit_opacity.yml diff --git a/src/modules/opengl/filter_movit_rect.cpp b/src/modules/movit/filter_movit_rect.cpp similarity index 100% rename from src/modules/opengl/filter_movit_rect.cpp rename to src/modules/movit/filter_movit_rect.cpp diff --git a/src/modules/opengl/filter_movit_rect.yml b/src/modules/movit/filter_movit_rect.yml similarity index 100% rename from src/modules/opengl/filter_movit_rect.yml rename to src/modules/movit/filter_movit_rect.yml diff --git a/src/modules/opengl/filter_movit_resample.cpp b/src/modules/movit/filter_movit_resample.cpp similarity index 100% rename from src/modules/opengl/filter_movit_resample.cpp rename to src/modules/movit/filter_movit_resample.cpp diff --git a/src/modules/opengl/filter_movit_resize.cpp b/src/modules/movit/filter_movit_resize.cpp similarity index 100% rename from src/modules/opengl/filter_movit_resize.cpp rename to src/modules/movit/filter_movit_resize.cpp diff --git a/src/modules/opengl/filter_movit_saturation.cpp b/src/modules/movit/filter_movit_saturation.cpp similarity index 100% rename from src/modules/opengl/filter_movit_saturation.cpp rename to src/modules/movit/filter_movit_saturation.cpp diff --git a/src/modules/opengl/filter_movit_saturation.yml b/src/modules/movit/filter_movit_saturation.yml similarity index 100% rename from src/modules/opengl/filter_movit_saturation.yml rename to src/modules/movit/filter_movit_saturation.yml diff --git a/src/modules/opengl/filter_movit_vignette.cpp b/src/modules/movit/filter_movit_vignette.cpp similarity index 100% rename from src/modules/opengl/filter_movit_vignette.cpp rename to src/modules/movit/filter_movit_vignette.cpp diff --git a/src/modules/opengl/filter_movit_vignette.yml b/src/modules/movit/filter_movit_vignette.yml similarity index 100% rename from src/modules/opengl/filter_movit_vignette.yml rename to src/modules/movit/filter_movit_vignette.yml diff --git a/src/modules/opengl/filter_movit_white_balance.cpp b/src/modules/movit/filter_movit_white_balance.cpp similarity index 100% rename from src/modules/opengl/filter_movit_white_balance.cpp rename to src/modules/movit/filter_movit_white_balance.cpp diff --git a/src/modules/opengl/filter_movit_white_balance.yml b/src/modules/movit/filter_movit_white_balance.yml similarity index 100% rename from src/modules/opengl/filter_movit_white_balance.yml rename to src/modules/movit/filter_movit_white_balance.yml diff --git a/src/modules/opengl/mlt_flip_effect.h b/src/modules/movit/mlt_flip_effect.h similarity index 100% rename from src/modules/opengl/mlt_flip_effect.h rename to src/modules/movit/mlt_flip_effect.h diff --git a/src/modules/opengl/mlt_movit_input.cpp b/src/modules/movit/mlt_movit_input.cpp similarity index 100% rename from src/modules/opengl/mlt_movit_input.cpp rename to src/modules/movit/mlt_movit_input.cpp diff --git a/src/modules/opengl/mlt_movit_input.h b/src/modules/movit/mlt_movit_input.h similarity index 100% rename from src/modules/opengl/mlt_movit_input.h rename to src/modules/movit/mlt_movit_input.h diff --git a/src/modules/opengl/optional_effect.h b/src/modules/movit/optional_effect.h similarity index 100% rename from src/modules/opengl/optional_effect.h rename to src/modules/movit/optional_effect.h diff --git a/src/modules/opengl/transition_movit_luma.cpp b/src/modules/movit/transition_movit_luma.cpp similarity index 100% rename from src/modules/opengl/transition_movit_luma.cpp rename to src/modules/movit/transition_movit_luma.cpp diff --git a/src/modules/opengl/transition_movit_luma.yml b/src/modules/movit/transition_movit_luma.yml similarity index 100% rename from src/modules/opengl/transition_movit_luma.yml rename to src/modules/movit/transition_movit_luma.yml diff --git a/src/modules/opengl/transition_movit_mix.cpp b/src/modules/movit/transition_movit_mix.cpp similarity index 100% rename from src/modules/opengl/transition_movit_mix.cpp rename to src/modules/movit/transition_movit_mix.cpp diff --git a/src/modules/opengl/transition_movit_mix.yml b/src/modules/movit/transition_movit_mix.yml similarity index 100% rename from src/modules/opengl/transition_movit_mix.yml rename to src/modules/movit/transition_movit_mix.yml diff --git a/src/modules/opengl/transition_movit_overlay.cpp b/src/modules/movit/transition_movit_overlay.cpp similarity index 100% rename from src/modules/opengl/transition_movit_overlay.cpp rename to src/modules/movit/transition_movit_overlay.cpp diff --git a/src/modules/opengl/transition_movit_overlay.yml b/src/modules/movit/transition_movit_overlay.yml similarity index 100% rename from src/modules/opengl/transition_movit_overlay.yml rename to src/modules/movit/transition_movit_overlay.yml From 0213299cd8bd3337b6d7c5013c027dc029e0ce0d Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 15 Mar 2021 18:28:09 -0500 Subject: [PATCH 071/122] Remove motion_est module --- CMakeLists.txt | 6 - docs/install.txt | 1 - src/modules/CMakeLists.txt | 4 - src/modules/motion_est/CMakeLists.txt | 29 - src/modules/motion_est/Makefile | 57 - src/modules/motion_est/README | 97 -- src/modules/motion_est/arrow_code.c | 163 --- src/modules/motion_est/arrow_code.h | 26 - src/modules/motion_est/factory.c | 47 - .../motion_est/filter_autotrack_rectangle.c | 400 ------ .../motion_est/filter_autotrack_rectangle.yml | 11 - src/modules/motion_est/filter_crop_detect.c | 247 ---- src/modules/motion_est/filter_motion_est.c | 1152 ----------------- src/modules/motion_est/filter_motion_est.h | 42 - src/modules/motion_est/filter_motion_est.yml | 11 - src/modules/motion_est/filter_vismv.c | 155 --- src/modules/motion_est/filter_vismv.yml | 11 - src/modules/motion_est/gpl | 0 src/modules/motion_est/producer_slowmotion.c | 414 ------ .../motion_est/producer_slowmotion.yml | 11 - src/modules/motion_est/sad_sse.h | 429 ------ 21 files changed, 3313 deletions(-) delete mode 100644 src/modules/motion_est/CMakeLists.txt delete mode 100644 src/modules/motion_est/Makefile delete mode 100644 src/modules/motion_est/README delete mode 100644 src/modules/motion_est/arrow_code.c delete mode 100644 src/modules/motion_est/arrow_code.h delete mode 100644 src/modules/motion_est/factory.c delete mode 100644 src/modules/motion_est/filter_autotrack_rectangle.c delete mode 100644 src/modules/motion_est/filter_autotrack_rectangle.yml delete mode 100644 src/modules/motion_est/filter_crop_detect.c delete mode 100644 src/modules/motion_est/filter_motion_est.c delete mode 100644 src/modules/motion_est/filter_motion_est.h delete mode 100644 src/modules/motion_est/filter_motion_est.yml delete mode 100644 src/modules/motion_est/filter_vismv.c delete mode 100644 src/modules/motion_est/filter_vismv.yml delete mode 100644 src/modules/motion_est/gpl delete mode 100644 src/modules/motion_est/producer_slowmotion.c delete mode 100644 src/modules/motion_est/producer_slowmotion.yml delete mode 100644 src/modules/motion_est/sad_sse.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 381541b05..0b12bf73e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,7 +18,6 @@ option(MOD_FREI0R "Enable frei0r module" ON) option(MOD_GDK "Enable gdk module" ON) option(MOD_JACKRACK "Enable jackrack module" ON) option(MOD_KDENLIVE "Enable kdenlive module" ON) -option(MOD_MOTION_EST "Enable motion estimation module" ON) option(MOD_NDI "Enable NDI module" OFF) option(MOD_NORMALIZE "Enable normalize module" ON) option(MOD_OLDFILM "Enable oldfilm module" ON) @@ -125,7 +124,6 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") endif() if(NOT GPL) - set(MOD_MOTION_EST OFF) set(MOD_NORMALIZE OFF) set(MOD_PLUSGPL OFF) set(MOD_QT OFF) @@ -226,10 +224,6 @@ if(MOD_KDENLIVE) list(APPEND MLT_SUPPORTED_COMPONENTS kdenlive) endif() -if(MOD_MOTION_EST) - list(APPEND MLT_SUPPORTED_COMPONENTS motion_est) -endif() - if(MOD_NDI) find_package(NDI REQUIRED) list(APPEND MLT_SUPPORTED_COMPONENTS ndi) diff --git a/docs/install.txt b/docs/install.txt index 831711a97..234d7642c 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -30,7 +30,6 @@ Last Revision: 2013-09-07 * gdk - GDK pango and pixbuf dependent services * jackrack - adapter for LADSPA audio plugins and JACK server * kdenlive - services contributed by Kdenlive project - * motion_est - motion estimation-based filters (*) * normalize - audio normalisation functions (*) * oldfilm - filters to make pristine video dirty * movit - Movit dependent services (*) diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 8844542c1..b78c671b0 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -24,10 +24,6 @@ if(MOD_KDENLIVE) add_subdirectory(kdenlive) endif() -if(MOD_MOTION_EST) - add_subdirectory(motion_est) -endif() - if(MOD_NDI) add_subdirectory(ndi) endif() diff --git a/src/modules/motion_est/CMakeLists.txt b/src/modules/motion_est/CMakeLists.txt deleted file mode 100644 index 3e3ca65fe..000000000 --- a/src/modules/motion_est/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -add_library(mltmotion_est MODULE - arrow_code.c - factory.c - filter_autotrack_rectangle.c - filter_crop_detect.c - filter_motion_est.c - filter_vismv.c - producer_slowmotion.c -) - -target_compile_options(mltmotion_est PRIVATE ${MLT_COMPILE_OPTIONS}) - -target_link_libraries(mltmotion_est PRIVATE mlt m) - -if(CPU_SSE) - target_compile_definitions(mltmotion_est PRIVATE USE_SSE) -endif() - -set_target_properties(mltmotion_est PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") - -install(TARGETS mltmotion_est LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) - -install(FILES - filter_autotrack_rectangle.yml - filter_motion_est.yml - filter_vismv.yml - producer_slowmotion.yml - DESTINATION ${MLT_INSTALL_DATA_DIR}/motion_est -) diff --git a/src/modules/motion_est/Makefile b/src/modules/motion_est/Makefile deleted file mode 100644 index 0d142750e..000000000 --- a/src/modules/motion_est/Makefile +++ /dev/null @@ -1,57 +0,0 @@ -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt -lm - -include ../../../config.mak - -TARGET = ../libmltmotion_est$(LIBSUF) - -OBJS = factory.o \ - filter_motion_est.o \ - filter_crop_detect.o \ - filter_autotrack_rectangle.o \ - arrow_code.o \ - filter_vismv.o \ - producer_slowmotion.o - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" - install -d "$(DESTDIR)$(mltdatadir)/motion_est" - install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/motion_est" - -test: $(TARGET) - ~/mlt-devel/mlt/src/melt/melt -filter motion_est -filter vismv -filter benchmark -consumer sdl rescale=none real_time=0 audio_off=1 silent=1 /media/cdrecorder/BBC.The.Private.Life.Of.Plants.Pt5.Living.Together.DivX505.AC3.www.MVGroup.org.uk.avi in=50000 - -hist: $(TARGET) - ~/mlt-devel/mlt/src/melt/melt -filter motion_est -filter histogram -consumer sdl rescale=none real_time=0 audio_off=1 silent=1 /media/cdrecorder/BBC.The.Private.Life.Of.Plants.Pt5.Living.Together.DivX505.AC3.www.MVGroup.org.uk.avi in=40000 - - -test2: $(TARGET) - melt colour:black -filter watermark:"+mello.txt" composite.geometry="0/0:10%x10%;99=90%/90%" composite.out=99 -filter crop_detect -filter motion_est -filter vismv - -realtime: $(TARGET) - ~/mlt-devel/mlt/src/melt/melt -filter motion_est -filter vismv -consumer sdl rescale=none /media/cdrecorder/BBC.The.Private.Life.Of.Plants.Pt5.Living.Together.DivX505.AC3.www.MVGroup.org.uk.avi in=30000 - -testhist: $(TARGET) - ~/mlt-devel/mlt/src/melt/melt -consumer sdl rescale=none silent=1 -filter motion_est -filter histogram -filter vismv /media/cdrecorder/BBC.The.Private.Life.Of.Plants.Pt5.Living.Together.DivX505.AC3.www.MVGroup.org.uk.avi in=10000 - - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/motion_est/README b/src/modules/motion_est/README deleted file mode 100644 index ee7de1770..000000000 --- a/src/modules/motion_est/README +++ /dev/null @@ -1,97 +0,0 @@ -INTRO: - -This module is designed to provide application agnostic motion estimation. -I wrote it from scratch because I found the other Open Source code to be -limited by their difficulty of reuse. - - -COMPILE: - -To compile this module, you must supply these options to the root configure script: - ---enable-gpl --enable-motion-est - - -EXAMPLES: - -Estimate the motion: - - > melt -filter motion_est - -To display the motion vectors as pretty arrows: - - > melt -filter motion_est -filter vismv - -If your using a movie file that contains a crop, you will get better results with this: - - > melt -filter crop_detect -filter motion_est -filter vismv - -If your computer is unable to do the above examples in real time, try this: - - > melt -filter motion_est -filter vismv -consumer melt real_time=0 - -If you'd like to see the motion vectors without the median denoising function, do this: - - > melt -filter motion_est denoise=0 -filter vismv - -To reconstruct each frame by applying the motion to the previous frame: - - > melt -filter motion_est show_reconstruction=1 - -To compare the reconstructed frame and the real frame (while paused): - - > melt -filter motion_est show_reconstruction=1 toggle_when_paused=1 - -To show the difference (residual) between the reconstructed frame the real frame: - - > melt -filter motion_est show_residual=1 - -To automatically track an object in the frame, try this: - - > melt -filter autotrack_rectangle:X,Y:WxH debug=1 - -(Where X,Y is the origin of the rectangle indexed from upper left and WxH is the dimensions of the rectangle.) - -To obscure that same object in the frame, try this: - - > melt -filter autotrack_rectangle:X,Y:WxH obscure=1 - -There is now a slow motion producer that does interpolation based on the motion vectors: - - > melt slowmotion: _speed=0.1 method=1 debug=1 - -NOTES (and deficiencies): - -1. Ignore shot change detection when your using the autotrack_rectangle filter. - -2. Don't assume motion vectors displayed while stepping backwards and forward are that same vectors - that would be calculated while playing the footage from start to finish, nonstop. Stepping forward - should be fine after a few frames, however. - -3. SSE instructions are lazily assumed. MMX, Altivec, and SIMD-less would be good too. - -4. Motion estimation is only performed in the luma color space. - -5. Motion vectors should have sub-pixel accuracy. - -6. Motion vectors are not serializable yet. - -7. A diligent test suite is needed. (show_reconstruction & show_residual are a start) - -8. Multithreaded code will see HUGE benefits on multi-CPU systems. Donations of a multi-core cpu or a - multi-cpu system to the author will encourage development. - -9. Macroblock sizes are not dynamic (Though settable at runtime.) - -10. Notes (5), (7), and (9) would go a long ways to making this code suitable for a modern video encoder. - -11. Shot change works well but arbitrarily chosen thresholds need to be tuned. - -12. Given the documentation of other motion estimation code bases, I will GLADLY clarify and - document any piece of code upon request. - -13. Considerable effort has been put into the speed. I usually experience 10ms or less per frame for PAL on 2.8GHZ p4. - -Zachary Drew -drew0054@tc.umn.edu - diff --git a/src/modules/motion_est/arrow_code.c b/src/modules/motion_est/arrow_code.c deleted file mode 100644 index 69a507dca..000000000 --- a/src/modules/motion_est/arrow_code.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * /brief Draw arrows - * /author Zachary Drew, Copyright 2004 - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include "arrow_code.h" - -#include -#include -#include -#include - -#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - - -static int w; -static int h; -static int xstride; -static int ystride; -static mlt_image_format format; - -int init_arrows( mlt_image_format *image_format, int width, int height ) -{ - w = width; - h = height; - format = *image_format; - switch( *image_format ) { - case mlt_image_yuv422: - xstride = 2; - ystride = xstride * w; - break; - default: - // I don't know - return 0; - } - return 1; - -} - -// ffmpeg borrowed -static inline int clip(int a, int amin, int amax) -{ - if (a < amin) - return amin; - else if (a > amax) - return amax; - else - return a; -} - - -/** - * draws an line from (ex, ey) -> (sx, sy). - * Credits: modified from ffmpeg project - * @param ystride stride/linesize of the image - * @param xstride stride/element size of the image - * @param color color of the arrow - */ -void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int color) -{ - int t, x, y, fr, f; - - - sx= clip(sx, 0, w-1); - sy= clip(sy, 0, h-1); - ex= clip(ex, 0, w-1); - ey= clip(ey, 0, h-1); - - buf[sy*ystride + sx*xstride]+= color; - - if(ABS(ex - sx) > ABS(ey - sy)){ - if(sx > ex){ - t=sx; sx=ex; ex=t; - t=sy; sy=ey; ey=t; - } - buf+= sx*xstride + sy*ystride; - ex-= sx; - f= ((ey-sy)<<16)/ex; - for(x= 0; x <= ex; x++){ - y = (x*f)>>16; - fr= (x*f)&0xFFFF; - buf[ y *ystride + x*xstride]+= (color*(0x10000-fr))>>16; - buf[(y+1)*ystride + x*xstride]+= (color* fr )>>16; - } - }else{ - if(sy > ey){ - t=sx; sx=ex; ex=t; - t=sy; sy=ey; ey=t; - } - buf+= sx*xstride + sy*ystride; - ey-= sy; - if(ey) f= ((ex-sx)<<16)/ey; - else f= 0; - for(y= 0; y <= ey; y++){ - x = (y*f)>>16; - fr= (y*f)&0xFFFF; - buf[y*ystride + x *xstride]+= (color*(0x10000-fr))>>16;; - buf[y*ystride + (x+1)*xstride]+= (color* fr )>>16;; - } - } -} - -void draw_rectangle_fill(uint8_t *buf, int x, int y, int w, int h, int color) -{ - int i,j; - for ( i = 0; i < w; i++ ) - for ( j = 0; j < h; j++ ) - buf[ (y+j)*ystride + (x+i)*xstride] = color; -} - -void draw_rectangle_outline(uint8_t *buf, int x, int y, int w, int h, int color) -{ - int i,j; - for ( i = 0; i < w; i++ ) { - buf[ y*ystride + (x+i)*xstride ] += color; - buf[ (y+h)*ystride + (x+i)*xstride ] += color; - } - for ( j = 1; j < h+1; j++ ) { - buf[ (y+j)*ystride + x*xstride ] += color; - buf[ (y+j)*ystride + (x+w)*xstride ] += color; - } -} -/** - * draws an arrow from (ex, ey) -> (sx, sy). - * Credits: modified from ffmpeg project - * @param stride stride/linesize of the image - * @param color color of the arrow - */ -void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int color){ - - int dx,dy; - dx= ex - sx; - dy= ey - sy; - - if(dx*dx + dy*dy > 3*3){ - int rx= dx + dy; - int ry= -dx + dy; - int length= sqrt((rx*rx + ry*ry)<<8); - - rx= ROUNDED_DIV(rx*3<<4, length); - ry= ROUNDED_DIV(ry*3<<4, length); - - draw_line(buf, sx, sy, sx + rx, sy + ry, color); - draw_line(buf, sx, sy, sx - ry, sy + rx, color); - } - draw_line(buf, sx, sy, ex, ey, color); -} diff --git a/src/modules/motion_est/arrow_code.h b/src/modules/motion_est/arrow_code.h deleted file mode 100644 index 7012e0d4e..000000000 --- a/src/modules/motion_est/arrow_code.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * file: arrow_code.h - * - * /brief Misc functions to draw arrows - * /author Zachary Drew, Copyright 2004 - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -extern int init_arrows( mlt_image_format *image_format, int width, int height ); -extern void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, int color); -extern void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int ey, int color); -extern void draw_rectangle_fill(uint8_t *buf, int x, int y, int w, int h, int color); -extern void draw_rectangle_outline(uint8_t *buf, int x, int y, int w, int h, int color); diff --git a/src/modules/motion_est/factory.c b/src/modules/motion_est/factory.c deleted file mode 100644 index b25709eba..000000000 --- a/src/modules/motion_est/factory.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -extern mlt_filter filter_motion_est_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_vismv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_crop_detect_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_autotrack_rectangle_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_slowmotion_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -static mlt_properties metadata( mlt_service_type type, const char *id, void *data ) -{ - char file[ PATH_MAX ]; - snprintf( file, PATH_MAX, "%s/motion_est/%s", mlt_environment( "MLT_DATA" ), (char*) data ); - return mlt_properties_parse_yaml( file ); -} - -MLT_REPOSITORY -{ - MLT_REGISTER( mlt_service_filter_type, "motion_est", filter_motion_est_init ); - MLT_REGISTER( mlt_service_filter_type, "vismv", filter_vismv_init ); - MLT_REGISTER( mlt_service_filter_type, "crop_detect", filter_crop_detect_init ); - MLT_REGISTER( mlt_service_filter_type, "autotrack_rectangle", filter_autotrack_rectangle_init ); - MLT_REGISTER( mlt_service_producer_type, "slowmotion", producer_slowmotion_init ); - - MLT_REGISTER_METADATA( mlt_service_filter_type, "motion_est", metadata, "filter_motion_est.yml" ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "vismv", metadata, "filter_vismv.yml" ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "crop_detect", metadata, "filter_crop_detect.yml" ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "autotrack_rectangle", metadata, "filter_autotrack_rectangle.yml" ); - MLT_REGISTER_METADATA( mlt_service_producer_type, "slowmotion", metadata, "producer_slowmotion.yml" ); -} diff --git a/src/modules/motion_est/filter_autotrack_rectangle.c b/src/modules/motion_est/filter_autotrack_rectangle.c deleted file mode 100644 index cf82c5059..000000000 --- a/src/modules/motion_est/filter_autotrack_rectangle.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * filter_autotrack_rectangle.c - * - * /brief - * /author Zachary Drew, Copyright 2005 - * - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "filter_motion_est.h" -#include "arrow_code.h" - -#include - -#include -#include -#include -#include - -#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - -void caculate_motion( struct motion_vector_s *vectors, - mlt_geometry_item boundry, - int macroblock_width, - int macroblock_height, - int mv_buffer_width, - int method, - int width, - int height ) -{ - - - // translate pixel units (from bounds) to macroblock units - // make sure whole macroblock stay within bounds - int left_mb = ( boundry->x + macroblock_width - 1 ) / macroblock_width; - int top_mb = ( boundry->y + macroblock_height - 1 ) / macroblock_height; - int right_mb = ( boundry->x + boundry->w ) / macroblock_width - 1; - int bottom_mb = ( boundry->y + boundry->h ) / macroblock_height - 1; - - int i, j, n = 0; - - int average_x = 0, average_y = 0; - - #define CURRENT ( vectors + j*mv_buffer_width + i ) - - for( i = left_mb; i <= right_mb; i++ ){ - for( j = top_mb; j <= bottom_mb; j++ ) - { - n++; - average_x += CURRENT->dx; - average_y += CURRENT->dy; - } - } - - if ( n == 0 ) return; - - average_x /= n; - average_y /= n; - - n = 0; - int average2_x = 0, average2_y = 0; - for( i = left_mb; i <= right_mb; i++ ){ - for( j = top_mb; j <= bottom_mb; j++ ){ - - if( ABS(CURRENT->dx - average_x) < 3 && - ABS(CURRENT->dy - average_y) < 3 ) - { - n++; - average2_x += CURRENT->dx; - average2_y += CURRENT->dy; - } - } - } - - if ( n == 0 ) return; - - boundry->x -= (double)average2_x / (double)n; - boundry->y -= (double)average2_y / (double)n; - - if ( boundry->x < 0 ) - boundry->x = 0; - - if ( boundry->y < 0 ) - boundry->y = 0; - - if ( boundry->x + boundry->w > width ) - boundry->x = width - boundry->w; - - if ( boundry->y + boundry->h > height ) - boundry->y = height - boundry->h; -} - -// Image stack(able) method -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - // Get the filter object - mlt_filter filter = mlt_frame_pop_service( frame ); - - // Get the filter's property object - mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter); - - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame); - - // Get the frame position - mlt_position position = mlt_filter_get_position( filter, frame ); - - mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter)); - - // Disable consumer scaling - if (profile && profile->width && profile->height) { - *width = profile->width; - *height = profile->height; - } - - // Get the new image - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - if( error != 0 ) - mlt_properties_debug( frame_properties, "error after mlt_frame_get_image() in autotrack_rectangle", stderr ); - - mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); - - // Get the geometry object - mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL); - - // Get the current geometry item - struct mlt_geometry_item_s boundry; - mlt_geometry_fetch(geometry, &boundry, position); - - // Get the motion vectors - struct motion_vector_s *vectors = mlt_properties_get_data( frame_properties, "motion_est.vectors", NULL ); - - // Cleanse the geometry item - boundry.w = boundry.x < 0 ? boundry.w + boundry.x : boundry.w; - boundry.h = boundry.y < 0 ? boundry.h + boundry.y : boundry.h; - boundry.x = boundry.x < 0 ? 0 : boundry.x; - boundry.y = boundry.y < 0 ? 0 : boundry.y; - boundry.w = boundry.w < 0 ? 0 : boundry.w; - boundry.h = boundry.h < 0 ? 0 : boundry.h; - - // How did the rectangle move? - if( vectors != NULL && - boundry.key != 1 ) // Paused? - { - - int method = mlt_properties_get_int( filter_properties, "method" ); - - // Get the size of macroblocks in pixel units - int macroblock_height = mlt_properties_get_int( frame_properties, "motion_est.macroblock_height" ); - int macroblock_width = mlt_properties_get_int( frame_properties, "motion_est.macroblock_width" ); - int mv_buffer_width = *width / macroblock_width; - - caculate_motion( vectors, &boundry, macroblock_width, macroblock_height, mv_buffer_width, method, *width, *height ); - - - // Make the geometry object a real boy - boundry.key = 1; - boundry.f[0] = 1; - boundry.f[1] = 1; - boundry.f[2] = 1; - boundry.f[3] = 1; - boundry.f[4] = 1; - mlt_geometry_insert(geometry, &boundry); - mlt_geometry_interpolate(geometry); - } - - mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); - - if( mlt_properties_get_int( filter_properties, "debug" ) == 1 ) - { - init_arrows( format, *width, *height ); - draw_rectangle_outline(*image, boundry.x, boundry.y, boundry.w, boundry.h, 100); - } - - if( mlt_properties_get_int( filter_properties, "_serialize" ) == 1 ) - { - // Add the vector change to the list - mlt_geometry key_frames = mlt_properties_get_data( filter_properties, "motion_vector_list", NULL ); - if ( !key_frames ) - { - key_frames = mlt_geometry_init(); - mlt_properties_set_data( filter_properties, "motion_vector_list", key_frames, 0, - (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise ); - if ( key_frames ) - mlt_geometry_set_length( key_frames, mlt_filter_get_length2( filter, frame ) ); - } - if ( key_frames ) - { - struct mlt_geometry_item_s item; - item.frame = (int) mlt_frame_get_position( frame ); - item.key = 1; - item.x = boundry.x; - item.y = boundry.y; - item.w = boundry.w; - item.h = boundry.h; - item.mix = 0; - item.f[0] = item.f[1] = item.f[2] = item.f[3] = 1; - item.f[4] = 0; - mlt_geometry_insert( key_frames, &item ); - } - } - - if( mlt_properties_get_int( filter_properties, "obscure" ) == 1 ) - { - mlt_filter obscure = mlt_properties_get_data( filter_properties, "_obscure", NULL ); - - mlt_properties_pass_list( MLT_FILTER_PROPERTIES(obscure), filter_properties, "in, out"); - - // Because filter_obscure needs to be rewritten to use mlt_geometry - char geom[100]; - sprintf( geom, "%d/%d:%dx%d", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h ); - mlt_properties_set( MLT_FILTER_PROPERTIES( obscure ), "start", geom ); - mlt_properties_set( MLT_FILTER_PROPERTIES( obscure ), "end", geom ); - } - - if( mlt_properties_get_int( filter_properties, "collect" ) == 1 ) - { - fprintf( stderr, "%d,%d,%d,%d\n", (int)boundry.x, (int)boundry.y, (int)boundry.w, (int)boundry.h ); - fflush( stdout ); - } - - return error; -} - -static int attach_boundry_to_frame( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the filter object - mlt_filter filter = mlt_frame_pop_service( frame ); - - // Get the filter's property object - mlt_properties filter_properties = MLT_FILTER_PROPERTIES(filter); - - // Get the frame properties - mlt_properties frame_properties = MLT_FRAME_PROPERTIES(frame); - - // Get the frame position - mlt_position position = mlt_filter_get_position( filter, frame ); - - mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter)); - - // Disable consumer scaling - if (profile && profile->width && profile->height) { - *width = profile->width; - *height = profile->height; - } - - mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); - - // Get the geometry object - mlt_geometry geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL); - if (geometry == NULL) { - mlt_geometry geom = mlt_geometry_init(); - char *arg = mlt_properties_get(filter_properties, "geometry"); - - // Parse the geometry if we have one - mlt_position length = mlt_filter_get_length2( filter, frame ); - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( filter ) ); - mlt_geometry_parse( geom, arg, length, profile->width, profile->height ); - - // Initialize with the supplied geometry - struct mlt_geometry_item_s item; - mlt_geometry_parse_item( geom, &item, arg ); - - item.frame = 0; - item.key = 1; - item.mix = 100; - - mlt_geometry_insert( geom, &item ); - mlt_geometry_interpolate( geom ); - mlt_properties_set_data( filter_properties, "filter_geometry", geom, 0, (mlt_destructor)mlt_geometry_close, (mlt_serialiser)mlt_geometry_serialise ); - geometry = mlt_properties_get_data(filter_properties, "filter_geometry", NULL); - } - - mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); - - // Get the current geometry item - mlt_geometry_item geometry_item = mlt_pool_alloc( sizeof( struct mlt_geometry_item_s ) ); - mlt_geometry_fetch(geometry, geometry_item, position); - - // Cleanse the geometry item - geometry_item->w = geometry_item->x < 0 ? geometry_item->w + geometry_item->x : geometry_item->w; - geometry_item->h = geometry_item->y < 0 ? geometry_item->h + geometry_item->y : geometry_item->h; - geometry_item->x = geometry_item->x < 0 ? 0 : geometry_item->x; - geometry_item->y = geometry_item->y < 0 ? 0 : geometry_item->y; - geometry_item->w = geometry_item->w < 0 ? 0 : geometry_item->w; - geometry_item->h = geometry_item->h < 0 ? 0 : geometry_item->h; - - mlt_properties_set_data( frame_properties, "bounds", geometry_item, sizeof( struct mlt_geometry_item_s ), mlt_pool_release, NULL ); - - // Get the new image - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - if( error != 0 ) - mlt_properties_debug( frame_properties, "error after mlt_frame_get_image() in autotrack_rectangle attach_boundry_to_frame", stderr ); - - return error; -} - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - /* modify the frame with the current geometry */ - mlt_frame_push_service( frame, this); - mlt_frame_push_get_image( frame, attach_boundry_to_frame ); - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - /* apply the motion estimation filter */ - mlt_filter motion_est = mlt_properties_get_data( properties, "_motion_est", NULL ); - /* Pass motion_est properties */ - mlt_properties_pass( MLT_FILTER_PROPERTIES( motion_est ), properties, "motion_est." ); - mlt_filter_process( motion_est, frame); - - /* calculate the new geometry based on the motion */ - mlt_frame_push_service( frame, this); - mlt_frame_push_get_image( frame, filter_get_image ); - - - /* visualize the motion vectors */ - if( mlt_properties_get_int( MLT_FILTER_PROPERTIES(this), "debug" ) == 1 ) - { - mlt_filter vismv = mlt_properties_get_data( properties, "_vismv", NULL ); - if( vismv == NULL ) - { - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) ); - vismv = mlt_factory_filter( profile, "vismv", NULL ); - mlt_properties_set_data( properties, "_vismv", vismv, 0, (mlt_destructor)mlt_filter_close, NULL ); - } - - mlt_filter_process( vismv, frame ); - } - - if( mlt_properties_get_int( MLT_FILTER_PROPERTIES(this), "obscure" ) == 1 ) - { - mlt_filter obscure = mlt_properties_get_data( properties, "_obscure", NULL ); - if( obscure == NULL ) - { - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE( this ) ); - obscure = mlt_factory_filter( profile, "obscure", NULL ); - mlt_properties_set_data( properties, "_obscure", obscure, 0, (mlt_destructor)mlt_filter_close, NULL ); - } - - mlt_filter_process( obscure, frame ); - } - - return frame; -} - -/** Constructor for the filter. -*/ - - -mlt_filter filter_autotrack_rectangle_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - - // Initialize with the supplied geometry if there is one - if( arg != NULL ) - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "geometry", arg ); - else - mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "geometry", "100/100:100x100" ); - - // create an instance of the motion_est and obscure filter - mlt_filter motion_est = mlt_factory_filter( profile, "motion_est", NULL ); - if( motion_est != NULL ) - mlt_properties_set_data( MLT_FILTER_PROPERTIES(this), "_motion_est", motion_est, 0, (mlt_destructor)mlt_filter_close, NULL ); - else { - mlt_filter_close( this ); - return NULL; - } - - - } - - return this; -} - -/** This source code will self destruct in 5...4...3... -*/ diff --git a/src/modules/motion_est/filter_autotrack_rectangle.yml b/src/modules/motion_est/filter_autotrack_rectangle.yml deleted file mode 100644 index a7e903c76..000000000 --- a/src/modules/motion_est/filter_autotrack_rectangle.yml +++ /dev/null @@ -1,11 +0,0 @@ -schema_version: 0.1 -type: filter -identifier: autotrack_rectangle -title: Autotrack Rectangle -version: 1 -copyright: Zachary Drew -creator: Zachary Drew -license: GPLv2 -language: en -tags: - - Video diff --git a/src/modules/motion_est/filter_crop_detect.c b/src/modules/motion_est/filter_crop_detect.c deleted file mode 100644 index d7b709531..000000000 --- a/src/modules/motion_est/filter_crop_detect.c +++ /dev/null @@ -1,247 +0,0 @@ -/** - * /brief Crop Detection filter - * - * /author Zachary Drew, Copyright 2005 - * - * inspired by mplayer's cropdetect filter - * - * Note: The goemetry generated is zero-indexed and is inclusive of the end values - * - * Options: - * -filter crop_detect debug=1 // Visualize crop - * -filter crop_detect frequency=25 // Detect the crop once a second - * -filter crop_detect frequency=0 // Never detect unless the producer changes - * -filter crop_detect thresh=100 // Changes the threshold (default = 25) - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#define DEBUG -#define DEFAULT_THRESH 20 - -#include - -#include -#include -#include -#include -#include "arrow_code.h" - -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - -// Image stack(able) method -static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - // Get the filter object and properties - mlt_filter filter = mlt_frame_pop_service( this ); - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter)); - - // Disable consumer scaling - if (profile && profile->width && profile->height) { - *width = profile->width; - *height = profile->height; - } - - // Get the new image - int error = mlt_frame_get_image( this, image, format, width, height, 1 ); - - if( error != 0 ) { - mlt_properties_debug( MLT_FRAME_PROPERTIES(this), "error after mlt_frame_get_image()", stderr ); - return error; - } - - // Parameter that describes how often to check for the crop - int frequency = mlt_properties_get_int( properties, "frequency"); - - // Producers may start with blank footage, by default we will skip, oh, 5 frames unless overridden - int skip = mlt_properties_get_int( properties, "skip"); - - mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); - - // The result - mlt_geometry_item bounds = mlt_properties_get_data( properties, "bounds", NULL ); - - // Initialize if needed - if( bounds == NULL ) { - bounds = calloc( 1, sizeof( struct mlt_geometry_item_s ) ); - bounds->w = *width; - bounds->h = *height; - mlt_properties_set_data( properties, "bounds", bounds, sizeof( struct mlt_geometry_item_s ), free, NULL ); - } - - // For periodic detection (with offset of 'skip') - if( frequency == 0 || (int)(mlt_filter_get_position(filter, this)+skip) % frequency != 0) - { - // Inject in stream - mlt_properties_set_data( MLT_FRAME_PROPERTIES(this), "bounds", bounds, sizeof( struct mlt_geometry_item_s ), NULL, NULL ); - - return 0; - } - - - // There is no way to detect a crop for sure, so make up an arbitrary one - int thresh = mlt_properties_get_int( properties, "thresh" ); - - *format = mlt_image_yuv422; - int xstride = 2; - int ystride = 2 * *width; - - int x, y, average_brightness, deviation; // Scratch variables - uint8_t *q; - - // Top crop - for( y = 0; y < *height/2; y++ ) { - bounds->y = y; - average_brightness = 0; - deviation = 0; - q = *image + y*ystride; - for( x = 0; x < *width; x++ ) - average_brightness += q[x*xstride]; - - average_brightness /= *width; - - for( x = 0; x < *width; x++ ) - deviation += abs(average_brightness - q[x*xstride]); - - if( deviation*10 >= thresh * *width ) - break; - } - - // Bottom crop - for( y = *height - 1; y >= *height/2; y-- ) { - bounds->h = y; - average_brightness = 0; - deviation = 0; - q = *image + y*ystride; - for( x = 0; x < *width; x++ ) - average_brightness += q[x*xstride]; - - average_brightness /= *width; - - for( x = 0; x < *width; x++ ) - deviation += abs(average_brightness - q[x*xstride]); - - if( deviation*10 >= thresh * *width) - break; - } - - // Left crop - for( x = 0; x < *width/2; x++ ) { - bounds->x = x; - average_brightness = 0; - deviation = 0; - q = *image + x*xstride; - for( y = 0; y < *height; y++ ) - average_brightness += q[y*ystride]; - - average_brightness /= *height; - - for( y = 0; y < *height; y++ ) - deviation += abs(average_brightness - q[y*ystride]); - - if( deviation*10 >= thresh * *width ) - break; - } - - // Right crop - for( x = *width - 1; x >= *width/2; x-- ) { - bounds->w = x; - average_brightness = 0; - deviation = 0; - q = *image + x*xstride; - for( y = 0; y < *height; y++ ) - average_brightness += q[y*ystride]; - - average_brightness /= *height; - - for( y = 0; y < *height; y++ ) - deviation += abs(average_brightness - q[y*ystride]); - - if( deviation*10 >= thresh * *width ) - break; - } - - /* Debug: Draw arrows to show crop */ - if( mlt_properties_get_int( properties, "debug") == 1 ) - { - init_arrows( format, *width, *height ); - - draw_arrow(*image, bounds->x, *height/2, bounds->x+50, *height/2, 100); - draw_arrow(*image, *width/2, bounds->y, *width/2, bounds->y+50, 100); - draw_arrow(*image, bounds->w, *height/2, bounds->w-50, *height/2, 100); - draw_arrow(*image, *width/2, bounds->h, *width/2, bounds->h-50, 100); - draw_arrow(*image, bounds->x, bounds->y, bounds->x+40, bounds->y+30, 100); - draw_arrow(*image, bounds->x, bounds->h, bounds->x+40, bounds->h-30, 100); - draw_arrow(*image, bounds->w, bounds->y, bounds->w-40, bounds->y+30, 100); - draw_arrow(*image, bounds->w, bounds->h, bounds->w-40, bounds->h-30, 100); - } - - // Convert to width and correct indexing - bounds->w -= bounds->x - 1; - bounds->h -= bounds->y - 1; - - if( mlt_properties_get_int( properties, "debug") == 1 ) - fprintf(stderr, "Top:%f Left:%f Width:%f Height:%f\n", bounds->y, bounds->x, bounds->w, bounds->h); - - /* inject into frame */ - mlt_properties_set_data( MLT_FRAME_PROPERTIES(this), "bounds", bounds, sizeof( struct mlt_geometry_item_s ), NULL, NULL ); - - mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); - - return error; -} - - - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - // Put the filter object somewhere we can find it - mlt_frame_push_service( frame, this); - - // Push the frame filter - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ -mlt_filter filter_crop_detect_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - - /* defaults */ - mlt_properties_set_int( MLT_FILTER_PROPERTIES(this), "frequency", 1); - mlt_properties_set_int( MLT_FILTER_PROPERTIES(this), "thresh", 5); - mlt_properties_set_int( MLT_FILTER_PROPERTIES(this), "clip", 5); - mlt_properties_set_int( MLT_FILTER_PROPERTIES(this), "former_producer_id", -1); - - } - - return this; -} - -/** This source code will self destruct in 5...4...3... -*/ - diff --git a/src/modules/motion_est/filter_motion_est.c b/src/modules/motion_est/filter_motion_est.c deleted file mode 100644 index 7ee71ecec..000000000 --- a/src/modules/motion_est/filter_motion_est.c +++ /dev/null @@ -1,1152 +0,0 @@ -/* - * /brief fast motion estimation filter - * /author Zachary Drew, Copyright 2005 - * - * Currently only uses Gamma data for comparisonon (bug or feature?) - * SSE optimized where available. - * - * Vector orientation: The vector data that is generated for the current frame specifies - * the motion from the previous frame to the current frame. To know how a macroblock - * in the current frame will move in the future, the next frame is needed. - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - - -#include "filter_motion_est.h" -#include -#include -#include -#include -#include -#include -#include - -#ifdef USE_SSE -#include "sad_sse.h" -#endif - -#define NDEBUG -#include - -#undef DEBUG -#undef DEBUG_ASM -#undef BENCHMARK -#undef COUNT_COMPARES - -#define DIAMOND_SEARCH 0x0 -#define FULL_SEARCH 0x1 -#define SHIFT 8 -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - - -struct motion_est_context_s -{ - int initialized; // true if filter has been initialized - -#ifdef COUNT_COMPARES - int compares; -#endif - - /* same as mlt_frame's parameters */ - int width, height; - - /* Operational details */ - int mb_w, mb_h; - int xstride, ystride; - uint8_t *cache_image; // Copy of current frame - uint8_t *former_image; // Copy of former frame - int search_method; - int skip_prediction; - int shot_change; - int limit_x, limit_y; // max x and y of a motion vector - int initial_thresh; - int check_chroma; // if check_chroma == 1 then compare chroma - int denoise; - int previous_msad; - int show_reconstruction; - int toggle_when_paused; - int show_residual; - - /* bounds */ - struct mlt_geometry_item_s bounds; // Current bounds (from filters crop_detect, autotrack rectangle, or other) - - /* bounds in macroblock units; macroblocks are completely contained within the boundry */ - int left_mb, prev_left_mb, right_mb, prev_right_mb; - int top_mb, prev_top_mb, bottom_mb, prev_bottom_mb; - - /* size of our vector buffers */ - int mv_buffer_height, mv_buffer_width, mv_size; - - /* vector buffers */ - int former_vectors_valid; // right || x2 + *w > right ) - w_remains = right - ((*x > x2) ? *x : x2); - - // Origin of macroblock moves above image boundy - if( *y < top || y2 < top ) { - h_remains = *h - top + ((*y < y2) ? *y : y2); - *y += *h - h_remains; - } - // Portion of macroblock moves below image boundry - else if( *y + *h > bottom || y2 + *h > bottom ) - h_remains = bottom - ((*y > y2) ? *y : y2); - - if( w_remains == *w && h_remains == *h ) return penalty; - if( w_remains <= 0 || h_remains <= 0) return 0; // Block is clipped out of existence - penalty = (*w * *h * penalty) - / ( w_remains * h_remains); // Recipricol of the fraction of the block that remains - - assert(*x >= left); assert(x2 + *w - w_remains >= left); - assert(*y >= top); assert(y2 + *h - h_remains >= top); - assert(*x + w_remains <= right); assert(x2 + w_remains <= right); - assert(*y + h_remains <= bottom); assert(y2 + h_remains <= bottom); - - *w = w_remains; // Update the width and height - *h = h_remains; - - return penalty; -} - -/** /brief Reference Sum of Absolute Differences comparison function -* -*/ -static int sad_reference( uint8_t *block1, uint8_t *block2, const int xstride, const int ystride, const int w, const int h ) -{ - int i, j, score = 0; - for ( j = 0; j < h; j++ ){ - for ( i = 0; i < w; i++ ){ - score += ABS( block1[i*xstride] - block2[i*xstride] ); - } - block1 += ystride; - block2 += ystride; - } - - return score; -} - - -/** /brief Abstracted block comparison function -*/ -inline static int block_compare( uint8_t *block1, - uint8_t *block2, - int x, - int y, - int dx, - int dy, - struct motion_est_context_s *c) -{ - -#ifdef COUNT_COMPARES - c->compares++; -#endif - - int score; - - // Default comparison may be overridden by the slower, more capable reference comparison - int (*cmp)(uint8_t *, uint8_t *, int, int, int, int) = c->compare_optimized; - - // vector displacement limited has been exceeded - if( ABS( dx ) >= c->limit_x || ABS( dy ) >= c->limit_y ) - return MAX_MSAD; - - int mb_w = c->mb_w; // Some writeable local copies - int mb_h = c->mb_h; - - // Determine if either macroblock got clipped - int penalty = constrain( &x, &y, &mb_w, &mb_h, dx, dy, 0, c->width, 0, c->height); - - // Some gotchas - if( penalty == 0 ) // Clipped out of existence: Return worst score - return MAX_MSAD; - else if( penalty != 1<compare_reference; - - // Calculate the memory locations of the macroblocks - block1 += x * c->xstride + y * c->ystride; - block2 += (x+dx) * c->xstride + (y+dy) * c->ystride; - - #ifdef DEBUG_ASM - if( penalty == 1<compare_reference( block1, block2, c->xstride, c->ystride, mb_w, mb_h ); - int score2 = c->compare_optimized( block1, block2, c->xstride, c->ystride, mb_w, mb_h ); - if ( score != score2 ) - fprintf(stderr, "Your assembly doesn't work! Reference: %d Asm: %d\n", score, score2); - } - else - #endif - - score = cmp( block1, block2, c->xstride, c->ystride, mb_w, mb_h ); - - return ( score * penalty ) >> SHIFT; // Ditch the extra precision -} - -static inline void check_candidates ( uint8_t *ref, - uint8_t *candidate_base, - const int x, - const int y, - const motion_vector *candidates,// Contains to_x & to_y - const int count, // Number of candidates - const int unique, // Sometimes we know the candidates are unique - motion_vector *result, - struct motion_est_context_s *c ) -{ - int score, i, j; - /* Scan for the best candidate */ - for ( i = 0; i < count; i++ ) - { - // this little dohicky ignores duplicate candidates, if they are possible - if ( unique == 0 ) { - j = 0; - while ( j < i ) - { - if ( candidates[j].dx == candidates[i].dx && - candidates[j].dy == candidates[i].dy ) - goto next_for_loop; - - j++; - } - } - - // Luma - score = block_compare( ref, candidate_base, - x, y, - candidates[i].dx, // from - candidates[i].dy, - c); - - if ( score < result->msad ) { // New minimum - result->dx = candidates[i].dx; - result->dy = candidates[i].dy; - result->msad = score; - } - next_for_loop:; - } -} - -/* /brief Diamond search -* Operates on a single macroblock -*/ -static inline void diamond_search( - uint8_t *ref, //dx; - current.dy = result->dy; - - if ( first == 1 ) // Set the initial pattern - { - candidates[0].dx = result->dx + 1; candidates[0].dy = result->dy + 0; - candidates[1].dx = result->dx + 0; candidates[1].dy = result->dy + 1; - candidates[2].dx = result->dx - 1; candidates[2].dy = result->dy + 0; - candidates[3].dx = result->dx + 0; candidates[3].dy = result->dy - 1; - i = 4; - } - else // Construct the next portion of the search pattern - { - candidates[0].dx = result->dx + best.dx; - candidates[0].dy = result->dy + best.dy; - if (best.dx == former.dx && best.dy == former.dy) { - candidates[1].dx = result->dx + best.dy; - candidates[1].dy = result->dy + best.dx; // Yes, the wires - candidates[2].dx = result->dx - best.dy; // are crossed - candidates[2].dy = result->dy - best.dx; - i = 3; - } else { - candidates[1].dx = result->dx + former.dx; - candidates[1].dy = result->dy + former.dy; - i = 2; - } - - former.dx = best.dx; former.dy = best.dy; // Keep track of new former best - } - - check_candidates ( ref, candidate_base, x, y, candidates, i, 1, result, c ); - - // Which candidate was the best? - best.dx = result->dx - current.dx; - best.dy = result->dy - current.dy; - - // A better candidate was not found - if ( best.dx == 0 && best.dy == 0 ) - return; - - if ( first == 1 ){ - first = 0; - former.dx = best.dx; former.dy = best.dy; // First iteration, sensible value for former.d* - } - } -} - -/* /brief Full (brute) search -* Operates on a single macroblock -*/ -__attribute__((used)) -static void full_search( - uint8_t *ref, //mb_w; i <= c->mb_w; i++ ){ - for( j = -c->mb_h; j <= c->mb_h; j++ ){ - - score = block_compare( ref, candidate_base, - x, - y, - x + i, - y + j, - c); - - if ( score < result->msad ) { - result->dx = i; - result->dy = j; - result->msad = score; - } - } - } -} - -// Macros for pointer calculations -#define CURRENT(i,j) ( c->current_vectors + (j)*c->mv_buffer_width + (i) ) -#define FORMER(i,j) ( c->former_vectors + (j)*c->mv_buffer_width + (i) ) -#define DENOISE(i,j) ( c->denoise_vectors + (j)*c->mv_buffer_width + (i) ) - -int ncompare (const void * a, const void * b) -{ - return ( *(const int*)a - *(const int*)b ); -} - -// motion vector denoising -// for x and y components separately, -// change the vector to be the median value of the 9 adjacent vectors -static void median_denoise( motion_vector *v, struct motion_est_context_s *c ) -{ - int xvalues[9], yvalues[9]; - - int i,j,n; - for( j = c->top_mb; j <= c->bottom_mb; j++ ) - for( i = c->left_mb; i <= c->right_mb; i++ ){ - { - n = 0; - - xvalues[n ] = CURRENT(i,j)->dx; // Center - yvalues[n++] = CURRENT(i,j)->dy; - - if( i > c->left_mb ) // Not in First Column - { - xvalues[n ] = CURRENT(i-1,j)->dx; // Left - yvalues[n++] = CURRENT(i-1,j)->dy; - - if( j > c->top_mb ) { - xvalues[n ] = CURRENT(i-1,j-1)->dx; // Upper Left - yvalues[n++] = CURRENT(i-1,j-1)->dy; - } - - if( j < c->bottom_mb ) { - xvalues[n ] = CURRENT(i-1,j+1)->dx; // Bottom Left - yvalues[n++] = CURRENT(i-1,j+1)->dy; - } - } - if( i < c->right_mb ) // Not in Last Column - { - xvalues[n ] = CURRENT(i+1,j)->dx; // Right - yvalues[n++] = CURRENT(i+1,j)->dy; - - - if( j > c->top_mb ) { - xvalues[n ] = CURRENT(i+1,j-1)->dx; // Upper Right - yvalues[n++] = CURRENT(i+1,j-1)->dy; - } - - if( j < c->bottom_mb ) { - xvalues[n ] = CURRENT(i+1,j+1)->dx; // Bottom Right - yvalues[n++] = CURRENT(i+1,j+1)->dy; - } - } - if( j > c->top_mb ) // Not in First Row - { - xvalues[n ] = CURRENT(i,j-1)->dx; // Top - yvalues[n++] = CURRENT(i,j-1)->dy; - } - - if( j < c->bottom_mb ) // Not in Last Row - { - xvalues[n ] = CURRENT(i,j+1)->dx; // Bottom - yvalues[n++] = CURRENT(i,j+1)->dy; - } - - qsort (xvalues, n, sizeof(int), ncompare); - qsort (yvalues, n, sizeof(int), ncompare); - - if( n % 2 == 1 ) { - DENOISE(i,j)->dx = xvalues[n/2]; - DENOISE(i,j)->dy = yvalues[n/2]; - } - else { - DENOISE(i,j)->dx = (xvalues[n/2] + xvalues[n/2+1])/2; - DENOISE(i,j)->dy = (yvalues[n/2] + yvalues[n/2+1])/2; - } - } - } - - motion_vector *t = c->current_vectors; - c->current_vectors = c->denoise_vectors; - c->denoise_vectors = t; - -} - -// Credits: ffmpeg -// return the median -static inline int median_predictor(int a, int b, int c) { - if ( a > b ){ - if ( c > b ){ - if ( c > a ) b = a; - else b = c; - } - } else { - if ( b > c ){ - if ( c > a ) b = c; - else b = a; - } - } - return b; -} - - -/** /brief Motion search -* -* For each macroblock in the current frame, estimate the block from the last frame that -* matches best. -* -* Vocab: Colocated - the pixel in the previous frame at the current position -* -* Based on enhanced predictive zonal search. [Tourapis 2002] -*/ -static void motion_search( uint8_t *from, //left_mb; i <= c->right_mb; i++ ){ - for( j = c->top_mb; j <= c->bottom_mb; j++ ){ - - here = CURRENT(i,j); - here->valid = 1; - here->color = 100; - here->msad = MAX_MSAD; - count++; - n = 0; - - - /* Stack the predictors [i.e. checked in reverse order] */ - - /* Adjacent to collocated */ - if( c->former_vectors_valid ) - { - // Top of colocated - if( j > c->prev_top_mb ){// && COL_TOP->valid ){ - candidates[n ].dx = FORMER(i,j-1)->dx; - candidates[n++].dy = FORMER(i,j-1)->dy; - } - - // Left of colocated - if( i > c->prev_left_mb ){// && COL_LEFT->valid ){ - candidates[n ].dx = FORMER(i-1,j)->dx; - candidates[n++].dy = FORMER(i-1,j)->dy; - } - - // Right of colocated - if( i < c->prev_right_mb ){// && COL_RIGHT->valid ){ - candidates[n ].dx = FORMER(i+1,j)->dx; - candidates[n++].dy = FORMER(i+1,j)->dy; - } - - // Bottom of colocated - if( j < c->prev_bottom_mb ){// && COL_BOTTOM->valid ){ - candidates[n ].dx = FORMER(i,j+1)->dx; - candidates[n++].dy = FORMER(i,j+1)->dy; - } - - // And finally, colocated - candidates[n ].dx = FORMER(i,j)->dx; - candidates[n++].dy = FORMER(i,j)->dy; - } - - // For macroblocks not in the top row - if ( j > c->top_mb) { - - // Top if ( TOP->valid ) { - candidates[n ].dx = CURRENT(i,j-1)->dx; - candidates[n++].dy = CURRENT(i,j-1)->dy; - //} - - // Top-Right, macroblocks not in the right row - if ( i < c->right_mb ){// && TOP_RIGHT->valid ) { - candidates[n ].dx = CURRENT(i+1,j-1)->dx; - candidates[n++].dy = CURRENT(i+1,j-1)->dy; - } - } - - // Left, Macroblocks not in the left column - if ( i > c->left_mb ){// && LEFT->valid ) { - candidates[n ].dx = CURRENT(i-1,j)->dx; - candidates[n++].dy = CURRENT(i-1,j)->dy; - } - - /* Median predictor vector (median of left, top, and top right adjacent vectors) */ - if ( i > c->left_mb && j > c->top_mb && i < c->right_mb - )//&& LEFT->valid && TOP->valid && TOP_RIGHT->valid ) - { - candidates[n ].dx = median_predictor( CURRENT(i-1,j)->dx, CURRENT(i,j-1)->dx, CURRENT(i+1,j-1)->dx); - candidates[n++].dy = median_predictor( CURRENT(i-1,j)->dy, CURRENT(i,j-1)->dy, CURRENT(i+1,j-1)->dy); - } - - // Zero vector - candidates[n ].dx = 0; - candidates[n++].dy = 0; - - int x = i * c->mb_w; - int y = j * c->mb_h; - check_candidates ( to, from, x, y, candidates, n, 0, here, c ); - - -#ifndef FULLSEARCH - diamond_search( to, from, x, y, here, c); -#else - full_search( to, from, x, y, here, c); -#endif - - assert( x + c->mb_w + here->dx > 0 ); // All macroblocks must have area > 0 - assert( y + c->mb_h + here->dy > 0 ); - assert( x + here->dx < c->width ); - assert( y + here->dy < c->height ); - - } /* End column loop */ - } /* End row loop */ - -#ifdef USE_SSE - asm volatile ( "emms" ); -#endif - -#ifdef COUNT_COMPARES - fprintf(stderr, "%d comparisons per block were made", compares/count); -#endif - return; -} - -void collect_post_statistics( struct motion_est_context_s *c ) { - - c->comparison_average = 0; - c->average_length = 0; - c->average_x = 0; - c->average_y = 0; - - int i, j, count = 0; - - for ( i = c->left_mb; i <= c->right_mb; i++ ){ - for ( j = c->top_mb; j <= c->bottom_mb; j++ ){ - - count++; - c->comparison_average += CURRENT(i,j)->msad; - c->average_x += CURRENT(i,j)->dx; - c->average_y += CURRENT(i,j)->dy; - - - } - } - - if ( count > 0 ) - { - c->comparison_average /= count; - c->average_x /= count; - c->average_y /= count; - c->average_length = sqrt( c->average_x * c->average_x + c->average_y * c->average_y ); - } - -} - -static void init_optimizations( struct motion_est_context_s *c ) -{ - switch(c->mb_w){ -#ifdef USE_SSE - case 4: if(c->mb_h == 4) c->compare_optimized = sad_sse_422_luma_4x4; - else c->compare_optimized = sad_sse_422_luma_4w; - break; - case 8: if(c->mb_h == 8) c->compare_optimized = sad_sse_422_luma_8x8; - else c->compare_optimized = sad_sse_422_luma_8w; - break; - case 16: if(c->mb_h == 16) c->compare_optimized = sad_sse_422_luma_16x16; - else c->compare_optimized = sad_sse_422_luma_16w; - break; - case 32: if(c->mb_h == 32) c->compare_optimized = sad_sse_422_luma_32x32; - else c->compare_optimized = sad_sse_422_luma_32w; - break; - case 64: c->compare_optimized = sad_sse_422_luma_64w; - break; -#endif - default: c->compare_optimized = sad_reference; - break; - } -} - -inline static void set_red(uint8_t *image, struct motion_est_context_s *c) -{ - int n; - for( n = 0; n < c->width * c->height * 2; n+=4 ) - { - image[n] = 79; - image[n+1] = 91; - image[n+2] = 79; - image[n+3] = 237; - } - -} - -static void show_residual( uint8_t *result, struct motion_est_context_s *c ) -{ - int i, j; - int x,y,w,h; - int dx, dy; - int tx,ty; - uint8_t *b, *r; - -// set_red(result,c); - - for( j = c->top_mb; j <= c->bottom_mb; j++ ){ - for( i = c->left_mb; i <= c->right_mb; i++ ){ - - dx = CURRENT(i,j)->dx; - dy = CURRENT(i,j)->dy; - w = c->mb_w; - h = c->mb_h; - x = i * w; - y = j * h; - - // Denoise function caused some blocks to be completely clipped, ignore them - if (constrain( &x, &y, &w, &h, dx, dy, 0, c->width, 0, c->height) == 0 ) - continue; - - for( ty = y; ty < y + h ; ty++ ){ - for( tx = x; tx < x + w ; tx++ ){ - - b = c->former_image + (tx+dx)*c->xstride + (ty+dy)*c->ystride; - r = result + tx*c->xstride + ty*c->ystride; - - r[0] = 16 + ABS( r[0] - b[0] ); - - if( dx % 2 == 0 ) - r[1] = 128 + ABS( r[1] - b[1] ); - else - // FIXME: may exceed boundaries - r[1] = 128 + ABS( r[1] - ( *(b-1) + b[3] ) /2 ); - } - } - } - } -} - -static void show_reconstruction( uint8_t *result, struct motion_est_context_s *c ) -{ - int i, j; - int x,y,w,h; - int dx,dy; - uint8_t *r, *s; - int tx,ty; - - for( i = c->left_mb; i <= c->right_mb; i++ ){ - for( j = c->top_mb; j <= c->bottom_mb; j++ ){ - - dx = CURRENT(i,j)->dx; - dy = CURRENT(i,j)->dy; - w = c->mb_w; - h = c->mb_h; - x = i * w; - y = j * h; - - // Denoise function caused some blocks to be completely clipped, ignore them - if (constrain( &x, &y, &w, &h, dx, dy, 0, c->width, 0, c->height) == 0 ) - continue; - - for( ty = y; ty < y + h ; ty++ ){ - for( tx = x; tx < x + w ; tx++ ){ - - r = result + tx*c->xstride + ty*c->ystride; - s = c->former_image + (tx+dx)*c->xstride + (ty+dy)*c->ystride; - - r[0] = s[0]; - - if( dx % 2 == 0 ) - r[1] = s[1]; - else - // FIXME: may exceed boundaries - r[1] = ( *(s-1) + s[3] ) /2; - } - } - } - } -} - -// Image stack(able) method -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 ); - mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter)); - - // Disable consumer scaling - if (profile && profile->width && profile->height) { - *width = profile->width; - *height = profile->height; - } - - mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); - - // Get the motion_est context object - struct motion_est_context_s *c = mlt_properties_get_data( MLT_FILTER_PROPERTIES( filter ), "context", NULL); - - // Get the new image and frame number - *format = mlt_image_yuv422; - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - #ifdef BENCHMARK - struct timeval start; gettimeofday(&start, NULL ); - #endif - - - if( error != 0 ) - mlt_properties_debug( MLT_FRAME_PROPERTIES(frame), "error after mlt_frame_get_image() in motion_est", stderr ); - - c->current_frame_position = mlt_frame_get_position( frame ); - - /* Context Initialization */ - if ( c->initialized == 0 ) { - - // Get the filter properties object - mlt_properties properties = mlt_filter_properties( filter ); - - c->width = *width; - c->height = *height; - - /* Get parameters that may have been overridden */ - if( mlt_properties_get( properties, "macroblock_width") != NULL ) - c->mb_w = mlt_properties_get_int( properties, "macroblock_width"); - - if( mlt_properties_get( properties, "macroblock_height") != NULL ) - c->mb_h = mlt_properties_get_int( properties, "macroblock_height"); - - if( mlt_properties_get( properties, "prediction_thresh") != NULL ) - c->initial_thresh = mlt_properties_get_int( properties, "prediction_thresh" ); - else - c->initial_thresh = c->mb_w * c->mb_h; - - if( mlt_properties_get( properties, "search_method") != NULL ) - c->search_method = mlt_properties_get_int( properties, "search_method"); - - if( mlt_properties_get( properties, "skip_prediction") != NULL ) - c->skip_prediction = mlt_properties_get_int( properties, "skip_prediction"); - - if( mlt_properties_get( properties, "limit_x") != NULL ) - c->limit_x = mlt_properties_get_int( properties, "limit_x"); - - if( mlt_properties_get( properties, "limit_y") != NULL ) - c->limit_y = mlt_properties_get_int( properties, "limit_y"); - - if( mlt_properties_get( properties, "check_chroma" ) != NULL ) - c->check_chroma = mlt_properties_get_int( properties, "check_chroma" ); - - if( mlt_properties_get( properties, "denoise" ) != NULL ) - c->denoise = mlt_properties_get_int( properties, "denoise" ); - - if( mlt_properties_get( properties, "show_reconstruction" ) != NULL ) - c->show_reconstruction = mlt_properties_get_int( properties, "show_reconstruction" ); - - if( mlt_properties_get( properties, "show_residual" ) != NULL ) - c->show_residual = mlt_properties_get_int( properties, "show_residual" ); - - if( mlt_properties_get( properties, "toggle_when_paused" ) != NULL ) - c->toggle_when_paused = mlt_properties_get_int( properties, "toggle_when_paused" ); - - init_optimizations( c ); - - // Calculate the dimensions in macroblock units - c->mv_buffer_width = (*width / c->mb_w); - c->mv_buffer_height = (*height / c->mb_h); - - // Size of the motion vector buffer - c->mv_size = c->mv_buffer_width * c->mv_buffer_height * sizeof(struct motion_vector_s); - - // Allocate the motion vector buffers - c->former_vectors = mlt_pool_alloc( c->mv_size ); - c->current_vectors = mlt_pool_alloc( c->mv_size ); - c->denoise_vectors = mlt_pool_alloc( c->mv_size ); - - // Register motion buffers for destruction - mlt_properties_set_data( properties, "current_motion_vectors", (void *)c->current_vectors, 0, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "former_motion_vectors", (void *)c->former_vectors, 0, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "denoise_motion_vectors", (void *)c->denoise_vectors, 0, mlt_pool_release, NULL ); - - c->former_vectors_valid = 0; - memset( c->former_vectors, 0, c->mv_size ); - - c->xstride = 2; - c->ystride = c->xstride * *width; - - // Allocate a cache for the previous frame's image - c->former_image = mlt_pool_alloc( *width * *height * 2 ); - c->cache_image = mlt_pool_alloc( *width * *height * 2 ); - - // Register for destruction - mlt_properties_set_data( properties, "cache_image", (void *)c->cache_image, 0, mlt_pool_release, NULL ); - mlt_properties_set_data( properties, "former_image", (void *)c->former_image, 0, mlt_pool_release, NULL ); - - c->former_frame_position = c->current_frame_position; - c->previous_msad = 0; - - c->initialized = 1; - } - - /* Check to see if somebody else has given us bounds */ - struct mlt_geometry_item_s *bounds = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "bounds", NULL ); - - if ( !bounds ) - { - char *property = mlt_properties_get( MLT_FILTER_PROPERTIES( filter ), "bounding" ); - if ( property ) - { - mlt_geometry geometry = mlt_geometry_init( ); - mlt_profile profile = mlt_service_profile( MLT_FILTER_SERVICE(filter) ); - if ( geometry ) - { - mlt_geometry_parse( geometry, property, 0, profile->width, profile->height ); - bounds = calloc( 1, sizeof(*bounds) ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES(filter), "bounds", bounds, sizeof(*bounds), free, NULL ); - mlt_geometry_fetch( geometry, bounds, 0 ); - mlt_geometry_close( geometry ); - } - } - } - - if( bounds != NULL ) { - // translate pixel units (from bounds) to macroblock units - // make sure whole macroblock stays within bounds - c->left_mb = ( bounds->x + c->mb_w - 1 ) / c->mb_w; - c->top_mb = ( bounds->y + c->mb_h - 1 ) / c->mb_h; - c->right_mb = ( bounds->x + bounds->w ) / c->mb_w - 1; - c->bottom_mb = ( bounds->y + bounds->h ) / c->mb_h - 1; - c->bounds.x = bounds->x; - c->bounds.y = bounds->y; - c->bounds.w = bounds->w; - c->bounds.h = bounds->h; - } else { - c->left_mb = c->prev_left_mb = 0; - c->top_mb = c->prev_top_mb = 0; - c->right_mb = c->prev_right_mb = c->mv_buffer_width - 1; // Zero indexed - c->bottom_mb = c->prev_bottom_mb = c->mv_buffer_height - 1; - c->bounds.x = 0; - c->bounds.y = 0; - c->bounds.w = *width; - c->bounds.h = *height; - } - - // If video is advancing, run motion vector algorithm and etc... - if( c->former_frame_position + 1 == c->current_frame_position ) - { - - // Swap the motion vector buffers and reuse allocated memory - struct motion_vector_s *temp = c->current_vectors; - c->current_vectors = c->former_vectors; - c->former_vectors = temp; - - // This is done because filter_vismv doesn't pay attention to frame boundry - memset( c->current_vectors, 0, c->mv_size ); - - // Perform the motion search - motion_search( c->cache_image, *image, c ); - - collect_post_statistics( c ); - - - // Detect shot changes - if( c->comparison_average > 10 * c->mb_w * c->mb_h && - c->comparison_average > c->previous_msad * 2 ) - { - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - mlt_log_verbose( MLT_FILTER_SERVICE(filter), "shot change: %d\n", c->comparison_average); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "shot_change", 1); - c->shot_change = 1; - - // Add the shot change to the list - mlt_geometry key_frames = mlt_properties_get_data( properties, "shot_change_list", NULL ); - if ( !key_frames ) - { - key_frames = mlt_geometry_init(); - mlt_properties_set_data( properties, "shot_change_list", key_frames, 0, - (mlt_destructor) mlt_geometry_close, (mlt_serialiser) mlt_geometry_serialise ); - if ( key_frames ) - mlt_geometry_set_length( key_frames, mlt_filter_get_length2( filter, frame ) ); - } - if ( key_frames ) - { - struct mlt_geometry_item_s item; - item.frame = (int) c->current_frame_position; - item.x = c->comparison_average; - item.f[0] = 1; - item.f[1] = item.f[2] = item.f[3] = item.f[4] = 0; - mlt_geometry_insert( key_frames, &item ); - } - } - else { - c->former_vectors_valid = 1; - c->shot_change = 0; - //fprintf(stderr, " - SAD: %d\n", c->comparison_average); - } - - c->previous_msad = c->comparison_average; - - if( c->comparison_average != 0 ) { // If the frame is not a duplicate of the previous frame - - // denoise the vector buffer - if( c->denoise ) - median_denoise( c->current_vectors, c ); - - // Pass the new vector data into the frame - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "motion_est.vectors", - (void*)c->current_vectors, c->mv_size, NULL, NULL ); - - // Cache the frame's image. Save the old cache. Reuse memory. - // After this block, exactly two unique frames will be cached - uint8_t *timg = c->cache_image; - c->cache_image = c->former_image; - c->former_image = timg; - memcpy( c->cache_image, *image, *width * *height * c->xstride ); - - - } - else { - // Undo the Swap, This fixes the ugliness caused by a duplicate frame - temp = c->current_vectors; - c->current_vectors = c->former_vectors; - c->former_vectors = temp; - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "motion_est.vectors", - (void*)c->former_vectors, c->mv_size, NULL, NULL ); - } - - - if( c->shot_change == 1) - ; - else if( c->show_reconstruction ) - show_reconstruction( *image, c ); - else if( c->show_residual ) - show_residual( *image, c ); - - } - // paused - else if( c->former_frame_position == c->current_frame_position ) - { - // Pass the old vector data into the frame if it's valid - if( c->former_vectors_valid == 1 ) { - mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "motion_est.vectors", - (void*)c->current_vectors, c->mv_size, NULL, NULL ); - - if( c->shot_change == 1) - ; - else if( c->toggle_when_paused == 1 ) { - if( c->show_reconstruction ) - show_reconstruction( *image, c ); - else if( c->show_residual ) - show_residual( *image, c ); - c->toggle_when_paused = 2; - } - else if( c->toggle_when_paused == 2 ) - c->toggle_when_paused = 1; - else { - if( c->show_reconstruction ) - show_reconstruction( *image, c ); - else if( c->show_residual ) - show_residual( *image, c ); - } - - } - - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "shot_change", c->shot_change); - } - // there was jump in frame number - else { -// fprintf(stderr, "Warning: there was a frame number jumped from %d to %d.\n", c->former_frame_position, c->current_frame_position); - c->former_vectors_valid = 0; - } - - - // Cache our bounding geometry for the next frame's processing - c->prev_left_mb = c->left_mb; - c->prev_top_mb = c->top_mb; - c->prev_right_mb = c->right_mb; - c->prev_bottom_mb = c->bottom_mb; - - // Remember which frame this is - c->former_frame_position = c->current_frame_position; - - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.macroblock_width", c->mb_w ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.macroblock_height", c->mb_h ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.left_mb", c->left_mb ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.right_mb", c->right_mb ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.top_mb", c->top_mb ); - mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "motion_est.bottom_mb", c->bottom_mb ); - - #ifdef BENCHMARK - struct timeval finish; gettimeofday(&finish, NULL ); int difference = (finish.tv_sec - start.tv_sec) * 1000000 + (finish.tv_usec - start.tv_usec); - fprintf(stderr, " in frame %d:%d usec\n", c->current_frame_position, difference); - #endif - - mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); - - return error; -} - - - -/** filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - - // Keeps tabs on the filter object - mlt_frame_push_service( frame, this); - - // Push the frame filter - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ -mlt_filter filter_motion_est_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - // Get the properties object - mlt_properties properties = MLT_FILTER_PROPERTIES( this ); - - // Initialize the motion estimation context - struct motion_est_context_s *context; - context = mlt_pool_alloc( sizeof(struct motion_est_context_s) ); - mlt_properties_set_data( properties, "context", (void *)context, sizeof( struct motion_est_context_s ), - mlt_pool_release, NULL ); - - - // Register the filter - this->process = filter_process; - - /* defaults that may be overridden */ - context->mb_w = 16; - context->mb_h = 16; - context->skip_prediction = 0; - context->limit_x = 64; - context->limit_y = 64; - context->search_method = DIAMOND_SEARCH; // FIXME: not used - context->check_chroma = 0; - context->denoise = 1; - context->show_reconstruction = 0; - context->show_residual = 0; - context->toggle_when_paused = 0; - - /* reference functions that may have optimized versions */ - context->compare_reference = sad_reference; - - // The rest of the buffers will be initialized when the filter is first processed - context->initialized = 0; - } - return this; -} diff --git a/src/modules/motion_est/filter_motion_est.h b/src/modules/motion_est/filter_motion_est.h deleted file mode 100644 index 03775ae12..000000000 --- a/src/modules/motion_est/filter_motion_est.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Perform motion estimation - * Zachary K Drew, Copyright 2004 - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef _FILTER_MOTION_EST_H_ -#define _FILTER_MOTION_EST_H_ - -#include - -extern mlt_filter filter_motion_est_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -#define MAX_MSAD 0xffff - -struct motion_vector_s -{ - int msad; // -#include - -#include -#include -#include -#include - -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - -static void paint_arrows( uint8_t *image, struct motion_vector_s *vectors, int w, int h, int mb_w, int mb_h ) -{ - int i, j, x, y; - struct motion_vector_s *p; - for( i = 0; i < w/mb_w; i++ ){ - for( j = 0; j < h/mb_h; j++ ){ - x = i*mb_w; - y = j*mb_h; - p = vectors + (w/mb_w)*j + i; - - if ( p->valid == 1 ) { - //draw_rectangle_outline(image, x-1, y-1, mb_w+1, mb_h+1,100); - //x += mb_w/4; - //y += mb_h/4; - //draw_rectangle_outline(image, x + p->dx, y + p->dy, mb_w, mb_h,100); - x += mb_w/2; - y += mb_h/2; - draw_arrow(image, x, y, x + p->dx, y + p->dy, 100); - //draw_rectangle_fill(image, x + p->dx, y + p->dy, mb_w, mb_h, 100); - } - else if ( p->valid == 2 ) { - draw_rectangle_outline(image, x+1, y+1, mb_w-2, mb_h-2,100); - } - else if ( p->valid == 3 ) { - draw_rectangle_fill(image, x-p->dx, y-p->dy, mb_w, mb_h,0); - } - else if ( p->valid == 4 ) { - draw_line(image, x, y, x + 4, y, 100); - draw_line(image, x, y, x, y + 4, 100); - draw_line(image, x + 4, y, x, y + 4, 100); - - draw_line(image, x+mb_w-1, y+mb_h-1, x+mb_w-5, y+mb_h-1, 100); - draw_line(image, x+mb_w-1, y+mb_h-1, x+mb_w-1, y+mb_h-5, 100); - draw_line(image, x+mb_w-5, y+mb_h-1, x+mb_w-1, y+mb_h-5, 100); - } - } - } -} - -// Image stack(able) method -static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Get the frame properties - mlt_properties properties = MLT_FRAME_PROPERTIES(frame); - mlt_filter filter = mlt_frame_pop_service( frame ); - mlt_profile profile = mlt_service_profile(MLT_FILTER_SERVICE(filter)); - - // Disable consumer scaling - if (profile && profile->width && profile->height) { - *width = profile->width; - *height = profile->height; - } - - // Get the new image - *format = mlt_image_yuv422; - int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - - if( error != 0 ) - mlt_properties_debug( MLT_FRAME_PROPERTIES(frame), "error after mlt_frame_get_image()", stderr ); - - - // Get the size of macroblocks in pixel units - int macroblock_height = mlt_properties_get_int( properties, "motion_est.macroblock_height" ); - int macroblock_width = mlt_properties_get_int( properties, "motion_est.macroblock_width" ); - - // Get the motion vectors - struct motion_vector_s *current_vectors = mlt_properties_get_data( properties, "motion_est.vectors", NULL ); - - init_arrows( format, *width, *height ); - - if ( mlt_properties_get_int( properties, "shot_change" ) == 1 ) - { - draw_line(*image, 0, 0, *width, *height, 100); - draw_line(*image, 0, *height, *width, 0, 100); - } - if( current_vectors != NULL ) { - paint_arrows( *image, current_vectors, *width, *height, macroblock_width, macroblock_height); - } - - return error; -} - - - -/** Filter processing. -*/ - -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) -{ - // Push the frame filter - mlt_frame_push_service( frame, this); - mlt_frame_push_get_image( frame, filter_get_image ); - - - return frame; -} - -/** Constructor for the filter. -*/ - - -mlt_filter filter_vismv_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) - { - this->process = filter_process; - - } - - return this; -} - -/** This source code will self destruct in 5...4...3... -*/ - - - - - - - - diff --git a/src/modules/motion_est/filter_vismv.yml b/src/modules/motion_est/filter_vismv.yml deleted file mode 100644 index e0ba65581..000000000 --- a/src/modules/motion_est/filter_vismv.yml +++ /dev/null @@ -1,11 +0,0 @@ -schema_version: 0.1 -type: filter -identifier: vismv -title: Visualize Motion Vectors -version: 1 -copyright: Zachary Drew -creator: Zachary Drew -license: GPLv2 -language: en -tags: - - Video diff --git a/src/modules/motion_est/gpl b/src/modules/motion_est/gpl deleted file mode 100644 index e69de29bb..000000000 diff --git a/src/modules/motion_est/producer_slowmotion.c b/src/modules/motion_est/producer_slowmotion.c deleted file mode 100644 index 160f98917..000000000 --- a/src/modules/motion_est/producer_slowmotion.c +++ /dev/null @@ -1,414 +0,0 @@ -/* - * producer_slowmotion.c -- create subspeed frames - * Author: Zachary Drew - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include "filter_motion_est.h" -#include - -#include -#include -#include -#include -#include -#include -#define SHIFT 8 -#define ABS(a) ((a) >= 0 ? (a) : (-(a))) - -// This is used to constrains pixel operations between two blocks to be within the image boundry -inline static int constrain( int *x, int *y, int *w, int *h, - const int dx, const int dy, - const int left, const int right, - const int top, const int bottom) -{ - uint32_t penalty = 1 << SHIFT; // Retain a few extra bits of precision - int x2 = *x + dx; - int y2 = *y + dy; - int w_remains = *w; - int h_remains = *h; - - // Origin of macroblock moves left of image boundy - if( *x < left || x2 < left ) { - w_remains = *w - left + ((*x < x2) ? *x : x2); - *x += *w - w_remains; - } - // Portion of macroblock moves right of image boundry - else if( *x + *w > right || x2 + *w > right ) - w_remains = right - ((*x > x2) ? *x : x2); - - // Origin of macroblock moves above image boundy - if( *y < top || y2 < top ) { - h_remains = *h - top + ((*y < y2) ? *y : y2); - *y += *h - h_remains; - } - // Portion of macroblock moves below image boundry - else if( *y + *h > bottom || y2 + *h > bottom ) - h_remains = bottom - ((*y > y2) ? *y : y2); - - if( w_remains == *w && h_remains == *h ) return penalty; - if( w_remains <= 0 || h_remains <= 0) return 0; // Block is clipped out of existence - penalty = (*w * *h * penalty) - / ( w_remains * h_remains); // Recipricol of the fraction of the block that remains - - *w = w_remains; // Update the width and height - *h = h_remains; - - return penalty; -} - -static void motion_interpolate( uint8_t *first_image, uint8_t *second_image, uint8_t *output, - int top_mb, int bottom_mb, int left_mb, int right_mb, - int mb_w, int mb_h, - int width, int height, - int xstride, int ystride, - double scale, - motion_vector *vectors ) -{ - assert ( scale >= 0.0 && scale <= 1.0 ); - - int i, j; - int x,y,w,h; - int dx, dy; - int scaled_dx, scaled_dy; - int tx,ty; - uint8_t *f,*s,*r; - motion_vector *here; - int mv_width = width / mb_w; - - for( j = top_mb; j <= bottom_mb; j++ ){ - for( i = left_mb; i <= right_mb; i++ ){ - - here = vectors + j*mv_width + i; - scaled_dx = (1.0 - scale) * (double)here->dx; - scaled_dy = (1.0 - scale) * (double)here->dy; - dx = here->dx; - dy = here->dy; - w = mb_w; h = mb_h; - x = i * w; y = j * h; - - // Denoise function caused some blocks to be completely clipped, ignore them - if (constrain( &x, &y, &w, &h, dx, dy, 0, width, 0, height) == 0 ) - continue; - - for( ty = y; ty < y + h ; ty++ ){ - for( tx = x; tx < x + w ; tx++ ){ - - f = first_image + (tx + dx )*xstride + (ty + dy )*ystride; - s = second_image + (tx )*xstride + (ty )*ystride; - r = output + (tx+scaled_dx)*xstride + (ty+scaled_dy)*ystride; -/* - if( ABS(f[0] - s[0]) > 3 * here->msad / (mb_w * mb_h * 2) ) - { - r[0] = f[0]; - r[1] = f[1]; - } - - else - { - -*/ - r[0] = ( 1.0 - scale ) * (double)f[0] + scale * (double)s[0]; - - if( dx % 2 == 0 ) - { - if( scaled_dx % 2 == 0 ) - r[1] = ( 1.0 - scale ) * (double)f[1] + scale * (double) s[1]; - else - *(r-1) = ( 1.0 - scale ) * (double)f[1] + scale * (double) s[1]; - } - else - { - if( scaled_dx %2 == 0 ) - // FIXME: may exceed boundaries - r[1] = ( 1.0 - scale ) * ( (double)(*(f-1) + (double)f[3]) / 2.0 ) + scale * (double) s[1]; - else - // FIXME: may exceed boundaries - *(r-1) = ( 1.0 - scale ) * ( (double)(*(f-1) + (double)f[3]) / 2.0 ) + scale * (double) s[1]; - } -// } - } - } - } - } -} - -// Image stack(able) method -static int slowmotion_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - - // Get the filter object and properties - mlt_producer producer = mlt_frame_pop_service( this ); - mlt_frame second_frame = mlt_frame_pop_service( this ); - mlt_frame first_frame = mlt_frame_pop_service( this ); - - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Frame properties objects - mlt_properties frame_properties = MLT_FRAME_PROPERTIES( this ); - mlt_properties first_frame_properties = MLT_FRAME_PROPERTIES( first_frame ); - mlt_properties second_frame_properties = MLT_FRAME_PROPERTIES( second_frame ); - - // image stride - *format = mlt_image_yuv422; - int size = *width * *height * 2; - int xstride = 2; - int ystride = 2 * *width; - - uint8_t *output = mlt_properties_get_data( producer_properties, "output_buffer", 0 ); - if( output == NULL ) - { - output = mlt_pool_alloc( size ); - - // Let someone else clean up - mlt_properties_set_data( producer_properties, "output_buffer", output, size, mlt_pool_release, NULL ); - } - - uint8_t *first_image = mlt_properties_get_data( first_frame_properties, "image", NULL ); - uint8_t *second_image = mlt_properties_get_data( second_frame_properties, "image", NULL ); - - // which frames are buffered? - - int error = 0; - - if( first_image == NULL ) - { - error = mlt_frame_get_image( first_frame, &first_image, format, width, height, writable ); - - if( error != 0 ) { - fprintf(stderr, "first_image == NULL get image died\n"); - return error; - } - } - - if( second_image == NULL ) - { - error = mlt_frame_get_image( second_frame, &second_image, format, width, height, writable ); - - if( error != 0 ) { - fprintf(stderr, "second_image == NULL get image died\n"); - return error; - } - } - - // These need to passed onto the frame for other - mlt_properties_pass_list( frame_properties, second_frame_properties, - "motion_est.left_mb, motion_est.right_mb, \ - motion_est.top_mb, motion_est.bottom_mb, \ - motion_est.macroblock_width, motion_est.macroblock_height" ); - - // Pass the pointer to the vectors without serializing - mlt_properties_set_data( frame_properties, "motion_est.vectors", - mlt_properties_get_data( second_frame_properties, "motion_est.vectors", NULL ), - 0, NULL, NULL ); - - - // Start with a base image - memcpy( output, first_image, size ); - - if( mlt_properties_get_int( producer_properties, "method" ) == 1 ) { - - mlt_position first_position = mlt_frame_get_position( first_frame ); - double actual_position = mlt_producer_get_speed( producer ) * (double)mlt_frame_get_position( this ); - double scale = actual_position - first_position; - - motion_interpolate - ( - first_image, second_image, output, - mlt_properties_get_int( second_frame_properties, "motion_est.top_mb" ), - mlt_properties_get_int( second_frame_properties, "motion_est.bottom_mb" ), - mlt_properties_get_int( second_frame_properties, "motion_est.left_mb" ), - mlt_properties_get_int( second_frame_properties, "motion_est.right_mb" ), - mlt_properties_get_int( second_frame_properties, "motion_est.macroblock_width" ), - mlt_properties_get_int( second_frame_properties, "motion_est.macroblock_height" ), - *width, *height, - xstride, ystride, - scale, - mlt_properties_get_data( second_frame_properties, "motion_est.vectors", NULL ) - ); - - if( mlt_properties_get_int( producer_properties, "debug" ) == 1 ) { - mlt_filter watermark = mlt_properties_get_data( producer_properties, "watermark", NULL ); - - if( watermark == NULL ) { - mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( producer ) ); - watermark = mlt_factory_filter( profile, "watermark", NULL ); - mlt_properties_set_data( producer_properties, "watermark", watermark, 0, (mlt_destructor)mlt_filter_close, NULL ); - mlt_producer_attach( producer, watermark ); - } - - mlt_properties wm_properties = MLT_FILTER_PROPERTIES( watermark ); - - char disp[30]; - sprintf(disp, "+%10.2f.txt", actual_position); - mlt_properties_set( wm_properties, "resource", disp ); - - } - - } - - *image = output; - mlt_frame_set_image( this, output, size, NULL ); - - // Make sure that no further scaling is done - mlt_properties_set( frame_properties, "rescale.interps", "none" ); - mlt_properties_set( frame_properties, "scale", "off" ); - - mlt_frame_close( first_frame ); - mlt_frame_close( second_frame ); - - return 0; -} - -static int slowmotion_get_frame( mlt_producer this, mlt_frame_ptr frame, int index ) -{ - if ( !frame ) - return 1; - // Construct a new frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( this ) ); - - mlt_properties properties = MLT_PRODUCER_PROPERTIES(this); - - - if( *frame ) - { - - mlt_frame first_frame = mlt_properties_get_data( properties, "first_frame", NULL ); - mlt_frame second_frame = mlt_properties_get_data( properties, "second_frame", NULL ); - - mlt_position first_position = (first_frame != NULL) ? mlt_frame_get_position( first_frame ) : -1; - mlt_position second_position = (second_frame != NULL) ? mlt_frame_get_position( second_frame ) : -1; - - // Get the real producer - mlt_producer real_producer = mlt_properties_get_data( properties, "producer", NULL ); - - // Our "in" needs to be the same, keep it so - mlt_properties_pass_list( MLT_PRODUCER_PROPERTIES( real_producer ), properties, "in" ); - - // Calculate our positions - double actual_position = mlt_producer_get_speed( this ) * (double)mlt_producer_position( this ); - mlt_position need_first = floor( actual_position ); - mlt_position need_second = need_first + 1; - - if( need_first != first_position ) - { - mlt_frame_close( first_frame ); - first_position = -1; - first_frame = NULL; - } - - if( need_second != second_position) - { - mlt_frame_close( second_frame ); - second_position = -1; - second_frame = NULL; - } - - if( first_frame == NULL ) - { - // Seek the producer to the correct place - mlt_producer_seek( real_producer, need_first ); - - // Get the frame - mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &first_frame, index ); - } - - if( second_frame == NULL ) - { - // Seek the producer to the correct place - mlt_producer_seek( real_producer, need_second ); - - // Get the frame - mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &second_frame, index ); - } - - // Make sure things are in their place - mlt_properties_set_data( properties, "first_frame", first_frame, 0, NULL, NULL ); - mlt_properties_set_data( properties, "second_frame", second_frame, 0, NULL, NULL ); - - mlt_properties_set_int( MLT_FRAME_PROPERTIES( *frame ), "test_image", 0 ); - - // Stack the producer and producer's get image - mlt_frame_push_service( *frame, first_frame ); - mlt_properties_inc_ref( MLT_FRAME_PROPERTIES( first_frame ) ); - - mlt_frame_push_service( *frame, second_frame ); - mlt_properties_inc_ref( MLT_FRAME_PROPERTIES( second_frame ) ); - - mlt_frame_push_service( *frame, this ); - mlt_frame_push_service( *frame, slowmotion_get_image ); - - // Give the returned frame temporal identity - mlt_frame_set_position( *frame, mlt_producer_position( this ) ); - } - - return 0; -} - -mlt_producer producer_slowmotion_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - mlt_producer this = mlt_producer_new( profile ); - - // Wrap the loader - mlt_producer real_producer = mlt_factory_producer( profile, NULL, arg ); - - // We need to apply the motion estimation filter manually - mlt_filter filter = mlt_factory_filter( profile, "motion_est", NULL ); - - if ( this != NULL && real_producer != NULL && filter != NULL) - { - // attach the motion_est filter to the real producer - mlt_producer_attach( real_producer, filter ); - - // Get the properties of this producer - mlt_properties properties = MLT_PRODUCER_PROPERTIES( this ); - - // The loader normalised it for us already - mlt_properties_set_int( properties, "loader_normalised", 1); - - // Store the producer and filter - mlt_properties_set_data( properties, "producer", real_producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - mlt_properties_set_data( properties, "motion_est", filter, 0, ( mlt_destructor )mlt_filter_close, NULL ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "macroblock_width", 16 ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "macroblock_height", 16 ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "denoise", 0 ); - - // Grap some stuff from the real_producer - mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( real_producer ), - "in, out, length, resource" ); - - // Since we control the seeking, prevent it from seeking on its own - mlt_producer_set_speed( real_producer, 0 ); - - //mlt_properties_set( properties, "method", "onefield" ); - - // Override the get_frame method - this->get_frame = slowmotion_get_frame; - - } - else - { - if ( this ) - mlt_producer_close( this ); - if ( real_producer ) - mlt_producer_close( real_producer ); - if ( filter ) - mlt_filter_close( filter ); - - this = NULL; - } - return this; -} diff --git a/src/modules/motion_est/producer_slowmotion.yml b/src/modules/motion_est/producer_slowmotion.yml deleted file mode 100644 index 44358fa18..000000000 --- a/src/modules/motion_est/producer_slowmotion.yml +++ /dev/null @@ -1,11 +0,0 @@ -schema_version: 0.1 -type: producer -identifier: slowmotion -title: Slow Motion -version: 1 -copyright: Zachary Drew -creator: Zachary Drew -license: GPLv2 -language: en -tags: - - Video diff --git a/src/modules/motion_est/sad_sse.h b/src/modules/motion_est/sad_sse.h deleted file mode 100644 index 5ec54b41d..000000000 --- a/src/modules/motion_est/sad_sse.h +++ /dev/null @@ -1,429 +0,0 @@ -/* - * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include - -#define SAD_SSE_INIT \ - asm volatile ( "pxor %%mm6,%%mm6\n\t" :: );\ - -// Sum two 8x1 pixel blocks -#define SAD_SSE_SUM_8(OFFSET) \ - "movq " #OFFSET "(%0),%%mm0 \n\t"\ - "movq " #OFFSET "(%1),%%mm1 \n\t"\ - "psadbw %%mm1,%%mm0 \n\t"\ - "paddw %%mm0,%%mm6 \n\t"\ - -#define SAD_SSE_FINISH(RESULT) \ - asm volatile( "movd %%mm6,%0" : "=r" (RESULT) : ); - -// Advance by ystride -#define SAD_SSE_NEXTROW \ - "add %2,%0 \n\t"\ - "add %2,%1 \n\t"\ - -// BROKEN! -inline static int sad_sse_4x4( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_INIT - #define ROW SAD_SSE_SUM_8(0) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((intptr_t)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -inline static int sad_sse_8x8( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_INIT - #define ROW SAD_SSE_SUM_8(0) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((intptr_t)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -inline static int sad_sse_16x16( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_INIT - #define ROW SAD_SSE_SUM_8(0) SAD_SSE_SUM_8(8) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((intptr_t)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -inline static int sad_sse_32x32( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_INIT - #define ROW SAD_SSE_SUM_8(0) SAD_SSE_SUM_8(8) SAD_SSE_SUM_8(16) SAD_SSE_SUM_8(24)\ - SAD_SSE_NEXTROW - - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((intptr_t)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} -// BROKEN! -inline static int sad_sse_4w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -inline static int sad_sse_8w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -inline static int sad_sse_16w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - SAD_SSE_SUM_8(8) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -inline static int sad_sse_32w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - SAD_SSE_SUM_8(8) - SAD_SSE_SUM_8(16) - SAD_SSE_SUM_8(24) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -inline static int sad_sse_64w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_SUM_8(0) - SAD_SSE_SUM_8(8) - SAD_SSE_SUM_8(16) - SAD_SSE_SUM_8(24) - SAD_SSE_SUM_8(32) - SAD_SSE_SUM_8(40) - SAD_SSE_SUM_8(48) - SAD_SSE_SUM_8(56) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} -static __attribute__((used)) __attribute__((aligned(8))) uint64_t sad_sse_422_mask_chroma = 0x00ff00ff00ff00ffULL; - -#define SAD_SSE_422_LUMA_INIT \ - asm volatile ( "movq %0,%%mm7\n\t"\ - "pxor %%mm6,%%mm6\n\t" :: "m" (sad_sse_422_mask_chroma) );\ - -// Sum two 4x1 pixel blocks -#define SAD_SSE_422_LUMA_SUM_4(OFFSET) \ - "movq " #OFFSET "(%0),%%mm0 \n\t"\ - "movq " #OFFSET "(%1),%%mm1 \n\t"\ - "pand %%mm7,%%mm0 \n\t"\ - "pand %%mm7,%%mm1 \n\t"\ - "psadbw %%mm1,%%mm0 \n\t"\ - "paddw %%mm0,%%mm6 \n\t"\ - -static int sad_sse_422_luma_4x4( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_422_LUMA_INIT - #define ROW SAD_SSE_422_LUMA_SUM_4(0) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((intptr_t)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -static int sad_sse_422_luma_8x8( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_422_LUMA_INIT - #define ROW SAD_SSE_422_LUMA_SUM_4(0) SAD_SSE_422_LUMA_SUM_4(8) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((intptr_t)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -static int sad_sse_422_luma_16x16( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_422_LUMA_INIT - #define ROW SAD_SSE_422_LUMA_SUM_4(0) SAD_SSE_422_LUMA_SUM_4(8) SAD_SSE_422_LUMA_SUM_4(16) SAD_SSE_422_LUMA_SUM_4(24) SAD_SSE_NEXTROW - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((intptr_t)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -static int sad_sse_422_luma_32x32( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - SAD_SSE_422_LUMA_INIT - #define ROW SAD_SSE_422_LUMA_SUM_4(0) SAD_SSE_422_LUMA_SUM_4(8) SAD_SSE_422_LUMA_SUM_4(16) SAD_SSE_422_LUMA_SUM_4(24)\ - SAD_SSE_422_LUMA_SUM_4(32) SAD_SSE_422_LUMA_SUM_4(40) SAD_SSE_422_LUMA_SUM_4(48) SAD_SSE_422_LUMA_SUM_4(56)\ - SAD_SSE_NEXTROW - - asm volatile ( ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - ROW ROW ROW ROW ROW ROW ROW ROW - :: "r" (block1), "r" (block2), "r" ((intptr_t)(ystride))); - - SAD_SSE_FINISH(result) - return result; - #undef ROW - -} - -static int sad_sse_422_luma_4w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -static int sad_sse_422_luma_8w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - SAD_SSE_422_LUMA_SUM_4(8) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -static int sad_sse_422_luma_16w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - SAD_SSE_422_LUMA_SUM_4(8) - SAD_SSE_422_LUMA_SUM_4(16) - SAD_SSE_422_LUMA_SUM_4(24) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -static int sad_sse_422_luma_32w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - SAD_SSE_422_LUMA_SUM_4(8) - SAD_SSE_422_LUMA_SUM_4(16) - SAD_SSE_422_LUMA_SUM_4(24) - SAD_SSE_422_LUMA_SUM_4(32) - SAD_SSE_422_LUMA_SUM_4(40) - SAD_SSE_422_LUMA_SUM_4(48) - SAD_SSE_422_LUMA_SUM_4(56) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; - -} - -static int sad_sse_422_luma_64w( uint8_t *block1, uint8_t *block2, int xstride, int ystride, int w, int h ) -{ - int result; - - SAD_SSE_422_LUMA_INIT - - while( h != 0 ) { - asm volatile ( - SAD_SSE_422_LUMA_SUM_4(0) - SAD_SSE_422_LUMA_SUM_4(8) - SAD_SSE_422_LUMA_SUM_4(16) - SAD_SSE_422_LUMA_SUM_4(24) - SAD_SSE_422_LUMA_SUM_4(32) - SAD_SSE_422_LUMA_SUM_4(40) - SAD_SSE_422_LUMA_SUM_4(48) - SAD_SSE_422_LUMA_SUM_4(56) - SAD_SSE_422_LUMA_SUM_4(64) - SAD_SSE_422_LUMA_SUM_4(72) - SAD_SSE_422_LUMA_SUM_4(80) - SAD_SSE_422_LUMA_SUM_4(88) - SAD_SSE_422_LUMA_SUM_4(96) - SAD_SSE_422_LUMA_SUM_4(104) - SAD_SSE_422_LUMA_SUM_4(112) - SAD_SSE_422_LUMA_SUM_4(120) - - :: "r" (block1), "r" (block2) - ); - - h--; - block1 += ystride; - block2 += ystride; - } - SAD_SSE_FINISH(result) - return result; -} From 1d27f040982f351493a952a1abf029f6f0bc1b40 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 15 Mar 2021 19:52:42 -0500 Subject: [PATCH 072/122] Remove the core/region filter and transition --- demo/README | 10 - demo/demo.ini | 2 - demo/mlt_bouncy_ball | 15 - demo/mlt_obscure | 5 - src/framework/mlt_service.h | 2 +- src/modules/core/CMakeLists.txt | 4 - src/modules/core/Makefile | 2 - src/modules/core/factory.c | 6 - src/modules/core/filter_region.c | 113 ------ src/modules/core/filter_region.yml | 29 -- src/modules/core/transition_region.c | 456 ------------------------- src/modules/core/transition_region.h | 27 -- src/modules/core/transition_region.yml | 52 --- 13 files changed, 1 insertion(+), 722 deletions(-) delete mode 100644 demo/mlt_bouncy_ball delete mode 100644 demo/mlt_obscure delete mode 100644 src/modules/core/filter_region.c delete mode 100644 src/modules/core/filter_region.yml delete mode 100644 src/modules/core/transition_region.c delete mode 100644 src/modules/core/transition_region.h delete mode 100644 src/modules/core/transition_region.yml diff --git a/demo/README b/demo/README index 4f75c3710..2577def61 100644 --- a/demo/README +++ b/demo/README @@ -76,16 +76,6 @@ Clock in and out http://mlt.sf.net/. It also performs field rendering. The second wipe demonstrates the ability to control the direction of the wipe as well. - -Obscure - - A popular requirement in news production is to obscure a face, obscenity, - or trademarked logo. This demonstrates using a simple rectangular - obscure filter applied to a region of the image. The second example is more - advanced and shows using the "region" filter to select the image area and a - property of the region filter to "shape" the region using the alpha channel - of another image (circle.png) and another property to "filter" the region - using the obscure filter. Audio Stuff diff --git a/demo/demo.ini b/demo/demo.ini index a276a6d80..cc347bebc 100644 --- a/demo/demo.ini +++ b/demo/demo.ini @@ -5,7 +5,6 @@ mlt_my_name_is My name is... clip3.dv mlt_composite_transition A composite transition clip1.dv,clip2.mpeg mlt_fade_in_and_out Fade in and out clip1.dv,clip2.mpeg,clip3.dv mlt_clock_in_and_out Clock in and out clip2.dv,clip1.dv,clip3.mpeg -mlt_obscure Obscure clip2.mpeg,circle.png mlt_audio_stuff Audio Stuff clip*.dv,music1.ogg mlt_levels Audio and Video Levels clip*.dv mlt_titleshadow_watermark Shadowed Title and Watermark clip3.dv @@ -15,7 +14,6 @@ mlt_avantika_title GJ-TTAvantika title pango.mlt mlt_title_over_gfx Title over graphic watermark1.png,clip1.dv mlt_slideshow Slideshow photos mlt_bouncy Bouncy, Bouncy clip1.dv,clip3.dv -mlt_bouncy_ball Bouncy, Bouncy Ball clip1.mpeg,clip3.mpeg,circle.png mlt_news Breaking News clip1.dv,clip2.dv mlt_squeeze Squeeze Transitions clip1.dv,clip2.dv,clip3.dv mlt_squeeze_box Squeeze Box clip1.dv,clip2.dv,clip3.dv diff --git a/demo/mlt_bouncy_ball b/demo/mlt_bouncy_ball deleted file mode 100644 index e549862a6..000000000 --- a/demo/mlt_bouncy_ball +++ /dev/null @@ -1,15 +0,0 @@ -melt \ -clip3.dv \ --track \ -clip1.dv \ --transition \ -region:circle \ -composite.geometry="10%,10%:20%x20%;33=30%/70%:25%x25%;66=70%/30%:15%x15%;-1=70%/70%:20%x20%" \ -composite.out=100 \ -composite.softness=0.1 \ -composite.sliced_composite=1 \ -a_track=0 \ -b_track=1 \ -in=0 \ -out=5000 \ -$* diff --git a/demo/mlt_obscure b/demo/mlt_obscure deleted file mode 100644 index 1bd3e1261..000000000 --- a/demo/mlt_obscure +++ /dev/null @@ -1,5 +0,0 @@ -melt \ -clip2.mpeg \ --filter obscure:25%/25%:25%x25%:10x10 in=0 out=68 \ --filter region:circle.png filter=obscure composite.start=55%/25%:12%x50% in=68 out=200 region.composite.sliced_composite=1 \ -$* diff --git a/src/framework/mlt_service.h b/src/framework/mlt_service.h index 2d8934da3..80219d532 100644 --- a/src/framework/mlt_service.h +++ b/src/framework/mlt_service.h @@ -47,7 +47,7 @@ * \properties \em in when to start, what is started is service-specific * \properties \em out when to stop * \properties \em _filter_private Set this on a service to ensure that attached filters are handled privately. - * See modules/core/filter_region.c and modules/core/filter_watermark.c for examples. + * See modules/core/filter_watermark.c for example. * \properties \em _profile stores the mlt_profile for a service * \properties \em _unique_id is a unique identifier * \properties \em _need_previous_next boolean that instructs producers to get diff --git a/src/modules/core/CMakeLists.txt b/src/modules/core/CMakeLists.txt index fe95104be..f2f270d94 100644 --- a/src/modules/core/CMakeLists.txt +++ b/src/modules/core/CMakeLists.txt @@ -21,7 +21,6 @@ add_library(mltcore MODULE filter_mono.c filter_obscure.c filter_panner.c - filter_region.c filter_rescale.c filter_resize.c filter_transition.c @@ -39,7 +38,6 @@ add_library(mltcore MODULE transition_luma.c transition_matte.c transition_mix.c - transition_region.c ) target_compile_options(mltcore PRIVATE ${MLT_COMPILE_OPTIONS}) @@ -82,7 +80,6 @@ install(FILES filter_mono.yml filter_obscure.yml filter_panner.yml - filter_region.yml filter_rescale.yml filter_resize.yml filter_transition.yml @@ -101,7 +98,6 @@ install(FILES transition_luma.yml transition_matte.yml transition_mix.yml - transition_region.yml loader.dict loader.ini DESTINATION ${MLT_INSTALL_DATA_DIR}/core diff --git a/src/modules/core/Makefile b/src/modules/core/Makefile index b7e8dc304..1ac5a1af0 100644 --- a/src/modules/core/Makefile +++ b/src/modules/core/Makefile @@ -34,7 +34,6 @@ OBJS = factory.o \ filter_mono.o \ filter_obscure.o \ filter_panner.o \ - filter_region.o \ filter_rescale.o \ filter_resize.o \ filter_transition.o \ @@ -43,7 +42,6 @@ OBJS = factory.o \ transition_composite.o \ transition_luma.o \ transition_mix.o \ - transition_region.o \ transition_matte.o \ consumer_multi.o \ consumer_null.o diff --git a/src/modules/core/factory.c b/src/modules/core/factory.c index 8305d033f..b506f6507 100644 --- a/src/modules/core/factory.c +++ b/src/modules/core/factory.c @@ -42,7 +42,6 @@ extern mlt_filter filter_mirror_init( mlt_profile profile, mlt_service_type type extern mlt_filter filter_mono_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_obscure_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_panner_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_region_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_rescale_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_resize_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_transition_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); @@ -61,7 +60,6 @@ extern mlt_producer producer_tone_init( mlt_profile profile, mlt_service_type ty extern mlt_transition transition_luma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_transition transition_mix_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_transition transition_matte_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -#include "transition_region.h" static mlt_properties metadata( mlt_service_type type, const char *id, void *data ) { @@ -95,7 +93,6 @@ MLT_REPOSITORY MLT_REGISTER( mlt_service_filter_type, "mono", filter_mono_init ); MLT_REGISTER( mlt_service_filter_type, "obscure", filter_obscure_init ); MLT_REGISTER( mlt_service_filter_type, "panner", filter_panner_init ); - MLT_REGISTER( mlt_service_filter_type, "region", filter_region_init ); MLT_REGISTER( mlt_service_filter_type, "rescale", filter_rescale_init ); MLT_REGISTER( mlt_service_filter_type, "resize", filter_resize_init ); MLT_REGISTER( mlt_service_filter_type, "transition", filter_transition_init ); @@ -116,7 +113,6 @@ MLT_REPOSITORY MLT_REGISTER( mlt_service_transition_type, "luma", transition_luma_init ); MLT_REGISTER( mlt_service_transition_type, "mix", transition_mix_init ); MLT_REGISTER( mlt_service_transition_type, "matte", transition_matte_init ); - MLT_REGISTER( mlt_service_transition_type, "region", transition_region_init ); MLT_REGISTER_METADATA( mlt_service_consumer_type, "multi", metadata, "consumer_multi.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "audiomap", metadata, "filter_audiomap.yml" ); @@ -137,7 +133,6 @@ MLT_REPOSITORY MLT_REGISTER_METADATA( mlt_service_filter_type, "mono", metadata, "filter_mono.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "obscure", metadata, "filter_obscure.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "panner", metadata, "filter_panner.yml" ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "region", metadata, "filter_region.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "rescale", metadata, "filter_rescale.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "resize", metadata, "filter_resize.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "transition", metadata, "filter_transition.yml" ); @@ -157,5 +152,4 @@ MLT_REPOSITORY MLT_REGISTER_METADATA( mlt_service_transition_type, "luma", metadata, "transition_luma.yml" ); MLT_REGISTER_METADATA( mlt_service_transition_type, "mix", metadata, "transition_mix.yml" ); MLT_REGISTER_METADATA( mlt_service_transition_type, "matte", metadata, "transition_matte.yml" ); - MLT_REGISTER_METADATA( mlt_service_transition_type, "region", metadata, "transition_region.yml" ); } diff --git a/src/modules/core/filter_region.c b/src/modules/core/filter_region.c deleted file mode 100644 index a63f15599..000000000 --- a/src/modules/core/filter_region.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * filter_region.c -- region filter - * Copyright (C) 2003-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "transition_region.h" - -#include -#include - -#include -#include -#include - -/** Filter processing. -*/ - -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( filter ); - - mlt_service_lock( MLT_FILTER_SERVICE( filter ) ); - - // Get the region transition - mlt_transition transition = mlt_properties_get_data( properties, "_transition", NULL ); - - // Create the transition if not available - if ( transition == NULL ) - { - // Create the transition - 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", filter, 0, NULL, NULL ); - } - - mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); - - // Pass all properties down - 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 - mlt_transition_process( transition, frame, NULL ); - - int result = mlt_frame_get_image( frame, image, format, width, height, writable ); - - // Restore the frame's position. - mlt_frame_set_position( frame, mlt_frame_original_position( frame ) ); - - return result; -} - -static mlt_frame filter_process( mlt_filter filter, mlt_frame frame ) -{ - mlt_frame_push_service( frame, filter ); - mlt_frame_push_get_image( frame, filter_get_image ); - - return frame; -} - -/** Constructor for the filter. -*/ - -mlt_filter filter_region_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create a new filter - mlt_filter filter = mlt_filter_new( ); - - // Further initialisation - if ( filter != NULL ) - { - // Get the properties from the filter - mlt_properties properties = MLT_FILTER_PROPERTIES( filter ); - - // Assign the filter process method - filter->process = filter_process; - - // Resource defines the shape of the region - mlt_properties_set( properties, "resource", arg == NULL ? "rectangle" : arg ); - - // Ensure that attached filters are handled privately - mlt_properties_set_int( properties, "_filter_private", 1 ); - } - - // Return the filter - return filter; -} - diff --git a/src/modules/core/filter_region.yml b/src/modules/core/filter_region.yml deleted file mode 100644 index 9845b138c..000000000 --- a/src/modules/core/filter_region.yml +++ /dev/null @@ -1,29 +0,0 @@ -schema_version: 0.1 -type: filter -identifier: region -title: Regionalize -version: 1 -copyright: Meltytech, LLC -creator: Charles Yates -license: LGPLv2.1 -language: en -tags: - - Video -description: > - Apply one or more filters to a region of the video image. The region can be - shaped as well using the alpha channel of another producer. -bugs: - - Circle is unpredictable in the absence of the librsvg pixbuf loader. -parameters: - - identifier: argument - title: File - type: string - description: > - A file whose alpha channel will "shape" the region. The string "circle" - is a shortcut but it requires pixbuf with the librsvg loader. The circle - is automatically stretched to the region to create an ellipse. - - identifier: region.* - title: Region - description: > - Properties may be set on the encapsulated region transition. See "region" - transition for details. diff --git a/src/modules/core/transition_region.c b/src/modules/core/transition_region.c deleted file mode 100644 index 739fe0852..000000000 --- a/src/modules/core/transition_region.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * transition_region.c -- region transition - * Copyright (C) 2003-2017 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "transition_region.h" -#include "transition_composite.h" - -#include - -#include -#include -#include - -static int create_instance( mlt_transition transition, char *name, char *value, int count ) -{ - // Return from this function - int error = 0; - - // Duplicate the value - char *type = strdup( value ); - - // Pointer to filter argument - char *arg = type == NULL ? NULL : strchr( type, ':' ); - - // New filter being created - mlt_filter filter = NULL; - - // Cleanup type and arg - if ( arg != NULL ) - *arg ++ = '\0'; - - // Create the filter - mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) ); - if ( type ) - filter = mlt_factory_filter( profile, type, arg ); - - // If we have a filter, then initialise and store it - if ( filter != NULL ) - { - // Properties of transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition ); - - // String to hold the property name - char id[ 256 ]; - - // String to hold the passdown key - char key[ 256 ]; - - // Construct id - sprintf( id, "_filter_%d", count ); - - // Counstruct key - sprintf( key, "%s.", name ); - - // Just in case, let's assume that the filter here has a composite - //mlt_properties_set( MLT_FILTER_PROPERTIES( filter ), "composite.geometry", "0%/0%:100%x100%" ); - //mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "composite.fill", 1 ); - - // 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 ); - } - else - { - // Indicate that an error has occurred - error = 1; - } - - // Cleanup - free( type ); - - // Return error condition - return error; -} - -static uint8_t *filter_get_alpha_mask( mlt_frame frame ) -{ - uint8_t *alpha = NULL; - - // Obtain properties of frame - 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( properties, "width" ); - int region_height = mlt_properties_get_int( properties, "height" ); - uint8_t *image = NULL; - mlt_image_format format = mlt_image_yuv422; - - // Get the shape image to trigger alpha creation - mlt_properties_set_int( MLT_FRAME_PROPERTIES( shape_frame ), "distort", 1 ); - mlt_frame_get_image( shape_frame, &image, &format, ®ion_width, ®ion_height, 0 ); - - 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 ) - { - alpha = alpha_duplicate; - while ( size -- ) - { - *alpha ++ = ( int )( ( ( *image ++ - 16 ) * 299 ) / 255 ); - image ++; - } - } - else - { - memcpy( alpha_duplicate, alpha, size ); - } - mlt_frame_set_alpha( frame, alpha_duplicate, region_width * region_height, mlt_pool_release ); - - return alpha_duplicate; -} - -/** Do it :-). -*/ - -static int transition_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - // Error we will return - int error = 0; - - // We will get the 'b frame' from the frame stack - mlt_frame b_frame = mlt_frame_pop_frame( frame ); - - // Get the watermark transition object - mlt_transition transition = mlt_frame_pop_service( frame ); - - // Get the properties of the transition - 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( transition ) ); - - // Get the composite from the transition - mlt_transition composite = mlt_properties_get_data( properties, "composite", NULL ); - - // Look for the first filter - mlt_filter filter = mlt_properties_get_data( properties, "_filter_0", NULL ); - - // Get the position - 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( transition ) ); - composite = mlt_factory_transition( profile, "composite", NULL ); - - // If we have one - if ( composite != NULL ) - { - // Get the properties - mlt_properties composite_properties = MLT_TRANSITION_PROPERTIES( composite ); - - // We want to ensure that we don't get a wobble... - //mlt_properties_set_int( composite_properties, "distort", 1 ); - mlt_properties_set_int( composite_properties, "progressive", 1 ); - - // Pass all the composite. properties on the transition down - mlt_properties_pass( composite_properties, properties, "composite." ); - - // Register the composite for reuse/destruction - mlt_properties_set_data( properties, "composite", composite, 0, ( mlt_destructor )mlt_transition_close, NULL ); - } - } - else - { - // Pass all current properties down - mlt_properties composite_properties = MLT_TRANSITION_PROPERTIES( composite ); - mlt_properties_pass( composite_properties, properties, "composite." ); - } - - // Create filters - if ( filter == NULL ) - { - // Loop Variable - int i = 0; - - // Number of filters created - int count = 0; - - // Loop for all properties - for ( i = 0; i < mlt_properties_count( properties ); i ++ ) - { - // Get the name of this property - char *name = mlt_properties_get_name( properties, i ); - - // If the name does not contain a . and matches filter - if ( strchr( name, '.' ) == NULL && !strncmp( name, "filter", 6 ) ) - { - // Get the filter constructor - char *value = mlt_properties_get_value( properties, i ); - - // Create an instance - if ( create_instance( transition, name, value, count ) == 0 ) - count ++; - } - } - - // Look for the first filter again - filter = mlt_properties_get_data( properties, "_filter_0", NULL ); - } - else - { - // Pass all properties down - mlt_filter temp = NULL; - - // Loop Variable - int i = 0; - - // Number of filters found - int count = 0; - - // Loop for all properties - for ( i = 0; i < mlt_properties_count( properties ); i ++ ) - { - // Get the name of this property - char *name = mlt_properties_get_name( properties, i ); - - // If the name does not contain a . and matches filter - if ( strchr( name, '.' ) == NULL && !strncmp( name, "filter", 6 ) ) - { - // Strings to hold the id and pass down key - char id[ 256 ]; - char key[ 256 ]; - - // Construct id and key - sprintf( id, "_filter_%d", count ); - sprintf( key, "%s.", name ); - - // Get the filter - temp = mlt_properties_get_data( properties, id, NULL ); - - if ( temp != NULL ) - { - mlt_properties_pass( MLT_FILTER_PROPERTIES( temp ), properties, key ); - count ++; - } - } - } - } - - 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 ) - { - // Get the resource of this filter (could be a shape [rectangle/circle] or an alpha provider of choice - const char *resource = mlt_properties_get( properties, "resource" ); - - // Get the old resource in case it's changed - char *old_resource = mlt_properties_get( properties, "_old_resource" ); - - // String to hold the filter to query on - char id[ 256 ]; - - // Index to hold the count - int i = 0; - - // We will get the 'b frame' from the composite only if it's NULL (region filter) - if ( b_frame == NULL ) - { - // Copy the region - b_frame = composite_copy_region( composite, frame, position ); - - // Ensure a destructor - char name[64]; - snprintf( name, sizeof(name), "region %s", mlt_properties_get( properties, "_unique_id" ) ); - 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[64]; - snprintf( name, sizeof(name), "region %s", 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 - while ( filter != NULL ) - { - // Stack this filter - if ( mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "off" ) == 0 ) - mlt_filter_process( filter, b_frame ); - - // Generate the key for the next - sprintf( id, "_filter_%d", ++ i ); - - // Get the next filter - filter = mlt_properties_get_data( properties, id, NULL ); - } - - // Allow filters to be attached to a region filter - filter = mlt_properties_get_data( properties, "_region_filter", NULL ); - if ( filter != NULL ) - mlt_service_apply_filters( MLT_FILTER_SERVICE( filter ), b_frame, 0 ); - - // Hmm - this is probably going to go wrong.... - mlt_frame_set_position( frame, position ); - - // Get the b frame and process with composite if successful - mlt_transition_process( composite, frame, b_frame ); - - // If we have a shape producer copy the alpha mask from the shape frame to the b_frame - if ( strcmp( resource, "rectangle" ) != 0 ) - { - // Get the producer from the transition - mlt_producer producer = mlt_properties_get_data( properties, "producer", NULL ); - - // If We have no producer then create one - if ( producer == NULL || ( old_resource != NULL && strcmp( resource, old_resource ) ) ) - { - // Get the factory producer service - char *factory = mlt_properties_get( properties, "factory" ); - - // Store the old resource - mlt_properties_set( properties, "_old_resource", resource ); - - // Special case circle resource - if ( strcmp( resource, "circle" ) == 0 ) - resource = "pixbuf:"; - - // Create the producer - mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( transition ) ); - producer = mlt_factory_producer( profile, factory, resource ); - - // If we have one - if ( producer != NULL ) - { - // Get the producer properties - mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Ensure that we loop - mlt_properties_set( producer_properties, "eof", "loop" ); - - // Now pass all producer. properties on the transition down - mlt_properties_pass( producer_properties, properties, "producer." ); - - // Register the producer for reuse/destruction - mlt_properties_set_data( properties, "producer", producer, 0, ( mlt_destructor )mlt_producer_close, NULL ); - } - } - - // Now use the shape producer - if ( producer != NULL ) - { - // We will get the alpha frame from the producer - mlt_frame shape_frame = NULL; - - // Make sure the producer is in the correct position - mlt_producer_seek( producer, position ); - - // Get the shape frame - 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( 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; - } - } - } - - // Get the image - error = mlt_frame_get_image( frame, image, format, width, height, 0 ); - } - - mlt_service_unlock( MLT_TRANSITION_SERVICE( transition ) ); - - return error; -} - -/** Filter processing. -*/ - -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, transition ); - - // Push the b_frame on to the stack - mlt_frame_push_frame( a_frame, b_frame ); - - // Push the transition method - mlt_frame_push_get_image( a_frame, transition_get_image ); - - // Return the frame - return a_frame; -} - -/** Constructor for the transition. -*/ - -mlt_transition transition_region_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) -{ - // Create a new transition - mlt_transition transition = mlt_transition_new( ); - - // Further initialisation - if ( transition != NULL ) - { - // Get the properties from the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition ); - - // Assign the transition process method - transition->process = transition_process; - - // Default factory - mlt_properties_set( properties, "factory", mlt_environment( "MLT_PRODUCER" ) ); - - // Resource defines the shape of the region - mlt_properties_set( properties, "resource", arg == NULL ? "rectangle" : arg ); - - // Inform apps and framework that this is a video only transition - mlt_properties_set_int( properties, "_transition_type", 1 ); - } - - // Return the transition - return transition; -} - diff --git a/src/modules/core/transition_region.h b/src/modules/core/transition_region.h deleted file mode 100644 index f217d62f9..000000000 --- a/src/modules/core/transition_region.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * transition_region.h -- region transition - * Copyright (C) 2003-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef _TRANSITION_REGION_H_ -#define _TRANSITION_REGION_H_ - -#include - -extern mlt_transition transition_region_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -#endif diff --git a/src/modules/core/transition_region.yml b/src/modules/core/transition_region.yml deleted file mode 100644 index ab3ff4737..000000000 --- a/src/modules/core/transition_region.yml +++ /dev/null @@ -1,52 +0,0 @@ -schema_version: 0.1 -type: transition -identifier: region -title: Regionalize -version: 1 -copyright: Meltytech, LLC -creator: Charles Yates -license: LGPLv2.1 -language: en -tags: - - Video -description: > - Apply zero or more filters to B frame as it is composited onto a region of - the A frame. The "shape" of the region can be defined by the alpha channel - of a third producer. -parameters: - - identifier: argument - title: Shape producer - type: string - description: > - The default shape is a rectangle, "circle" is a pixbuf-generated SVG - circle, anything else is loaded by the factory. - - identifier: factory - title: Factory - type: string - description: > - The service that creates the shape producer. - default: loader - - identifier: filter[N] - title: Filter - type: string - description: > - One or more filters to apply. All filter properties are passed using the - same filter "key". - - identifier: composite.* - title: Composite - type: properties - service-name: transition.composite - description: > - Properties may be set on the encapsulated composite transition. - - e.g.: composite.valign=c - - See "composite" transition for details. - readonly: no - - identifier: filter_only - title: Use region for filtering only - type: integer - minimum: 0 - maximum: 1 - default: 0 - widget: checkbox From e3179ad680908ebbca34bf096811fc2f0e8a101f Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 15 Mar 2021 20:58:21 -0500 Subject: [PATCH 073/122] Merge vmfx module into core --- CMakeLists.txt | 5 -- docs/install.txt | 1 - src/modules/CMakeLists.txt | 4 -- src/modules/plus/CMakeLists.txt | 12 ++++- src/modules/plus/Makefile | 5 ++ src/modules/plus/factory.c | 23 +++++++-- src/modules/{vmfx => plus}/filter_chroma.c | 0 src/modules/{vmfx => plus}/filter_chroma.yml | 0 .../{vmfx => plus}/filter_chroma_hold.c | 0 .../{vmfx => plus}/filter_chroma_hold.yml | 0 src/modules/{vmfx => plus}/filter_shape.c | 0 src/modules/{vmfx => plus}/filter_shape.yml | 0 .../filter_mono.c => plus/filter_threshold.c} | 4 +- .../filter_threshold.yml} | 0 src/modules/{vmfx => plus}/producer_pgm.c | 0 src/modules/{vmfx => plus}/producer_pgm.yml | 0 src/modules/vmfx/CMakeLists.txt | 25 --------- src/modules/vmfx/Makefile | 39 -------------- src/modules/vmfx/factory.c | 51 ------------------- 19 files changed, 37 insertions(+), 132 deletions(-) rename src/modules/{vmfx => plus}/filter_chroma.c (100%) rename src/modules/{vmfx => plus}/filter_chroma.yml (100%) rename src/modules/{vmfx => plus}/filter_chroma_hold.c (100%) rename src/modules/{vmfx => plus}/filter_chroma_hold.yml (100%) rename src/modules/{vmfx => plus}/filter_shape.c (100%) rename src/modules/{vmfx => plus}/filter_shape.yml (100%) rename src/modules/{vmfx/filter_mono.c => plus/filter_threshold.c} (94%) rename src/modules/{vmfx/filter_mono.yml => plus/filter_threshold.yml} (100%) rename src/modules/{vmfx => plus}/producer_pgm.c (100%) rename src/modules/{vmfx => plus}/producer_pgm.yml (100%) delete mode 100644 src/modules/vmfx/CMakeLists.txt delete mode 100644 src/modules/vmfx/Makefile delete mode 100644 src/modules/vmfx/factory.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b12bf73e..1f1602154 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,6 @@ option(MOD_SDL1 "Enable SDL1 module" ON) option(MOD_SDL2 "Enable SDL2 module" ON) option(MOD_SOX "Enable SoX module" ON) option(MOD_VIDSTAB "Enable vid.stab module" ON) -option(MOD_VMFX "Enable vmfx module" ON) option(MOD_VORBIS "Enable Vorbis module" ON) option(MOD_XINE "Enable xine module" ON) option(MOD_XML "Enable XML module" ON) @@ -340,10 +339,6 @@ if(MOD_VIDSTAB) endif() endif() -if(MOD_VMFX) - list(APPEND MLT_SUPPORTED_COMPONENTS vmfx) -endif() - if(MOD_VORBIS) pkg_check_modules(vorbis IMPORTED_TARGET vorbis) pkg_check_modules(vorbisfile IMPORTED_TARGET vorbisfile) diff --git a/docs/install.txt b/docs/install.txt index 234d7642c..6c6c9ebe1 100644 --- a/docs/install.txt +++ b/docs/install.txt @@ -41,7 +41,6 @@ Last Revision: 2013-09-07 * sdl - SDL dependent services * sox - !SoX dependent audio filters * vid.stab - video stabilization filters (*) - * vmfx - services contributed by (defunct) Visual Media FX * vorbis - vorbis dependenent services * xine - Xine-derived sources (*) * xml - XML (de)serialization services diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index b78c671b0..c2e551a37 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -84,10 +84,6 @@ if(MOD_VIDSTAB) add_subdirectory(vid.stab) endif() -if(MOD_VMFX) - add_subdirectory(vmfx) -endif() - if(MOD_VORBIS) add_subdirectory(vorbis) endif() diff --git a/src/modules/plus/CMakeLists.txt b/src/modules/plus/CMakeLists.txt index b65477735..1141f0ff1 100644 --- a/src/modules/plus/CMakeLists.txt +++ b/src/modules/plus/CMakeLists.txt @@ -3,6 +3,8 @@ add_library(mltplus MODULE factory.c filter_affine.c filter_charcoal.c + filter_chroma_hold.c + filter_chroma.c filter_dynamictext.c filter_dynamic_loudness.c filter_invert.c @@ -13,12 +15,15 @@ add_library(mltplus MODULE filter_pillar_echo.c filter_rgblut.c filter_sepia.c + filter_shape.c filter_spot_remover.c + filter_strobe.c filter_text.c + filter_threshold.c filter_timer.c - filter_strobe.c producer_blipflash.c producer_count.c + producer_pgm.c transition_affine.c ) @@ -49,6 +54,8 @@ install(FILES consumer_blipflash.yml filter_affine.yml filter_charcoal.yml + filter_chroma_hold.yml + filter_chroma.yml filter_dynamic_loudness.yml filter_dynamictext.yml filter_invert.yml @@ -59,12 +66,15 @@ install(FILES filter_pillar_echo.yml filter_rgblut.yml filter_sepia.yml + filter_shape.yml filter_spot_remover.yml filter_strobe.yml filter_text.yml + filter_threshold.yml filter_timer.yml producer_blipflash.yml producer_count.yml + producer_pgm.yml transition_affine.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/plus ) diff --git a/src/modules/plus/Makefile b/src/modules/plus/Makefile index e5643d884..2f9de7ea2 100644 --- a/src/modules/plus/Makefile +++ b/src/modules/plus/Makefile @@ -11,6 +11,8 @@ OBJS = consumer_blipflash.o \ factory.o \ filter_affine.o \ filter_charcoal.o \ + filter_chroma.o \ + filter_chroma_hold.o \ filter_dynamictext.o \ filter_dynamic_loudness.o \ filter_invert.o \ @@ -23,10 +25,13 @@ OBJS = consumer_blipflash.o \ filter_sepia.o \ filter_spot_remover.o \ filter_text.o \ + filter_threshold.o \ filter_timer.o \ + filter_shape.o \ filter_strobe.o \ producer_blipflash.o \ producer_count.o \ + producer_pgm.o \ transition_affine.o ifdef USE_FFTW diff --git a/src/modules/plus/factory.c b/src/modules/plus/factory.c index e383da075..d139e4ecd 100644 --- a/src/modules/plus/factory.c +++ b/src/modules/plus/factory.c @@ -24,22 +24,27 @@ extern mlt_consumer consumer_blipflash_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_affine_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_charcoal_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); +extern mlt_filter filter_chroma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); +extern mlt_filter filter_chroma_hold_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_dynamictext_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_dynamic_loudness_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); +extern mlt_filter filter_invert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_lift_gamma_gain_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_loudness_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_loudness_meter_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_lumakey_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_pillar_echo_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_invert_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_rgblut_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_sepia_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); +extern mlt_filter filter_shape_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_spot_remover_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); +extern mlt_filter filter_strobe_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_text_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); +extern mlt_filter filter_threshold_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_filter filter_timer_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_strobe_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_producer producer_blipflash_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_producer producer_count_init( const char *arg ); +extern mlt_producer producer_pgm_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_transition transition_affine_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); #ifdef USE_FFTW @@ -59,6 +64,8 @@ MLT_REPOSITORY MLT_REGISTER( mlt_service_consumer_type, "blipflash", consumer_blipflash_init ); MLT_REGISTER( mlt_service_filter_type, "affine", filter_affine_init ); MLT_REGISTER( mlt_service_filter_type, "charcoal", filter_charcoal_init ); + MLT_REGISTER( mlt_service_filter_type, "chroma", filter_chroma_init ); + MLT_REGISTER( mlt_service_filter_type, "chroma_hold", filter_chroma_hold_init ); MLT_REGISTER( mlt_service_filter_type, "dynamictext", filter_dynamictext_init ); MLT_REGISTER( mlt_service_filter_type, "dynamic_loudness", filter_dynamic_loudness_init ); MLT_REGISTER( mlt_service_filter_type, "invert", filter_invert_init ); @@ -69,12 +76,15 @@ MLT_REPOSITORY MLT_REGISTER( mlt_service_filter_type, "pillar_echo", filter_pillar_echo_init ); MLT_REGISTER( mlt_service_filter_type, "rgblut", filter_rgblut_init ); MLT_REGISTER( mlt_service_filter_type, "sepia", filter_sepia_init ); + MLT_REGISTER( mlt_service_filter_type, "shape", filter_shape_init ); MLT_REGISTER( mlt_service_filter_type, "spot_remover", filter_spot_remover_init ); + MLT_REGISTER( mlt_service_filter_type, "strobe", filter_strobe_init ); MLT_REGISTER( mlt_service_filter_type, "text", filter_text_init ); + MLT_REGISTER( mlt_service_filter_type, "threshold", filter_threshold_init ); MLT_REGISTER( mlt_service_filter_type, "timer", filter_timer_init ); - MLT_REGISTER( mlt_service_filter_type, "strobe", filter_strobe_init ); MLT_REGISTER( mlt_service_producer_type, "blipflash", producer_blipflash_init ); MLT_REGISTER( mlt_service_producer_type, "count", producer_count_init ); + MLT_REGISTER( mlt_service_producer_type, "pgm", producer_pgm_init ); MLT_REGISTER( mlt_service_transition_type, "affine", transition_affine_init ); #ifdef USE_FFTW MLT_REGISTER( mlt_service_filter_type, "dance", filter_dance_init ); @@ -84,6 +94,8 @@ MLT_REPOSITORY MLT_REGISTER_METADATA( mlt_service_consumer_type, "blipflash", metadata, "consumer_blipflash.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "affine", metadata, "filter_affine.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "charcoal", metadata, "filter_charcoal.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "chroma", metadata, "filter_chroma.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "chroma_hold", metadata, "filter_chroma_hold.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "dynamictext", metadata, "filter_dynamictext.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "dynamic_loudness", metadata, "filter_dynamic_loudness.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "invert", metadata, "filter_invert.yml" ); @@ -94,12 +106,15 @@ MLT_REPOSITORY MLT_REGISTER_METADATA( mlt_service_filter_type, "pillar_echo", metadata, "filter_pillar_echo.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "rgblut", metadata, "filter_rgblut.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "sepia", metadata, "filter_sepia.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "shape", metadata, "filter_shape.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "spot_remover", metadata, "filter_spot_remover.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "strobe", metadata, "filter_strobe.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "text", metadata, "filter_text.yml" ); + MLT_REGISTER_METADATA( mlt_service_filter_type, "threshold", metadata, "filter_threshold.yml" ); MLT_REGISTER_METADATA( mlt_service_filter_type, "timer", metadata, "filter_timer.yml" ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "strobe", metadata, "filter_strobe.yml" ); MLT_REGISTER_METADATA( mlt_service_producer_type, "blipflash", metadata, "producer_blipflash.yml" ); MLT_REGISTER_METADATA( mlt_service_producer_type, "count", metadata, "producer_count.yml" ); + MLT_REGISTER_METADATA( mlt_service_producer_type, "pgm", metadata, "producer_pgm.yml" ); MLT_REGISTER_METADATA( mlt_service_transition_type, "affine", metadata, "transition_affine.yml" ); #ifdef USE_FFTW MLT_REGISTER_METADATA( mlt_service_filter_type, "dance", metadata, "filter_dance.yml" ); diff --git a/src/modules/vmfx/filter_chroma.c b/src/modules/plus/filter_chroma.c similarity index 100% rename from src/modules/vmfx/filter_chroma.c rename to src/modules/plus/filter_chroma.c diff --git a/src/modules/vmfx/filter_chroma.yml b/src/modules/plus/filter_chroma.yml similarity index 100% rename from src/modules/vmfx/filter_chroma.yml rename to src/modules/plus/filter_chroma.yml diff --git a/src/modules/vmfx/filter_chroma_hold.c b/src/modules/plus/filter_chroma_hold.c similarity index 100% rename from src/modules/vmfx/filter_chroma_hold.c rename to src/modules/plus/filter_chroma_hold.c diff --git a/src/modules/vmfx/filter_chroma_hold.yml b/src/modules/plus/filter_chroma_hold.yml similarity index 100% rename from src/modules/vmfx/filter_chroma_hold.yml rename to src/modules/plus/filter_chroma_hold.yml diff --git a/src/modules/vmfx/filter_shape.c b/src/modules/plus/filter_shape.c similarity index 100% rename from src/modules/vmfx/filter_shape.c rename to src/modules/plus/filter_shape.c diff --git a/src/modules/vmfx/filter_shape.yml b/src/modules/plus/filter_shape.yml similarity index 100% rename from src/modules/vmfx/filter_shape.yml rename to src/modules/plus/filter_shape.yml diff --git a/src/modules/vmfx/filter_mono.c b/src/modules/plus/filter_threshold.c similarity index 94% rename from src/modules/vmfx/filter_mono.c rename to src/modules/plus/filter_threshold.c index fd030a820..c3421c0e7 100644 --- a/src/modules/vmfx/filter_mono.c +++ b/src/modules/plus/filter_threshold.c @@ -1,5 +1,5 @@ /* - * filter_mono.c -- Arbitrary alpha channel shaping + * filter_threshold.c -- Arbitrary alpha channel shaping * Copyright (C) 2005 Visual Media Fx Inc. * Author: Charles Yates * @@ -90,7 +90,7 @@ static mlt_frame filter_process( mlt_filter filter, mlt_frame frame ) /** Constructor for the filter. */ -mlt_filter filter_mono_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) +mlt_filter filter_threshold_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) { mlt_filter filter = mlt_filter_new( ); if ( filter != NULL ) diff --git a/src/modules/vmfx/filter_mono.yml b/src/modules/plus/filter_threshold.yml similarity index 100% rename from src/modules/vmfx/filter_mono.yml rename to src/modules/plus/filter_threshold.yml diff --git a/src/modules/vmfx/producer_pgm.c b/src/modules/plus/producer_pgm.c similarity index 100% rename from src/modules/vmfx/producer_pgm.c rename to src/modules/plus/producer_pgm.c diff --git a/src/modules/vmfx/producer_pgm.yml b/src/modules/plus/producer_pgm.yml similarity index 100% rename from src/modules/vmfx/producer_pgm.yml rename to src/modules/plus/producer_pgm.yml diff --git a/src/modules/vmfx/CMakeLists.txt b/src/modules/vmfx/CMakeLists.txt deleted file mode 100644 index a9e6101dd..000000000 --- a/src/modules/vmfx/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -add_library(mltvmfx MODULE - factory.c - filter_chroma_hold.c - filter_chroma.c - filter_mono.c - filter_shape.c - producer_pgm.c -) - -target_compile_options(mltvmfx PRIVATE ${MLT_COMPILE_OPTIONS}) - -target_link_libraries(mltvmfx PRIVATE mlt) - -set_target_properties(mltvmfx PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") - -install(TARGETS mltvmfx LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) - -install(FILES - filter_chroma_hold.yml - filter_chroma.yml - filter_mono.yml - filter_shape.yml - producer_pgm.yml - DESTINATION ${MLT_INSTALL_DATA_DIR}/vmfx -) diff --git a/src/modules/vmfx/Makefile b/src/modules/vmfx/Makefile deleted file mode 100644 index 2343ec94a..000000000 --- a/src/modules/vmfx/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -CFLAGS += -I../.. - -LDFLAGS += -L../../framework -lmlt - -include ../../../config.mak - -TARGET = ../libmltvmfx$(LIBSUF) - -OBJS = factory.o \ - filter_chroma.o \ - filter_chroma_hold.o \ - filter_mono.o \ - filter_shape.o \ - producer_pgm.o - -SRCS := $(OBJS:.o=.c) - -all: $(TARGET) - -$(TARGET): $(OBJS) - $(CC) $(SHFLAGS) -o $@ $(OBJS) $(LDFLAGS) - -depend: $(SRCS) - $(CC) -MM $(CFLAGS) $^ 1>.depend - -distclean: clean - rm -f .depend - -clean: - rm -f $(OBJS) $(TARGET) - -install: all - install -m 755 $(TARGET) "$(DESTDIR)$(moduledir)" - install -d "$(DESTDIR)$(mltdatadir)/vmfx" - install -m 644 *.yml "$(DESTDIR)$(mltdatadir)/vmfx" - -ifneq ($(wildcard .depend),) -include .depend -endif diff --git a/src/modules/vmfx/factory.c b/src/modules/vmfx/factory.c deleted file mode 100644 index 5b8b30f16..000000000 --- a/src/modules/vmfx/factory.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * factory.c -- the factory method interfaces - * Copyright (C) 2005 Visual Media Fx Inc. - * Author: Charles Yates - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include - -extern mlt_filter filter_chroma_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_chroma_hold_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_mono_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_filter filter_shape_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -extern mlt_producer producer_pgm_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); - -static mlt_properties metadata( mlt_service_type type, const char *id, void *data ) -{ - char file[ PATH_MAX ]; - snprintf( file, PATH_MAX, "%s/vmfx/%s", mlt_environment( "MLT_DATA" ), (char*) data ); - return mlt_properties_parse_yaml( file ); -} - -MLT_REPOSITORY -{ - MLT_REGISTER( mlt_service_filter_type, "chroma", filter_chroma_init ); - MLT_REGISTER( mlt_service_filter_type, "chroma_hold", filter_chroma_hold_init ); - MLT_REGISTER( mlt_service_filter_type, "threshold", filter_mono_init ); - MLT_REGISTER( mlt_service_filter_type, "shape", filter_shape_init ); - MLT_REGISTER( mlt_service_producer_type, "pgm", producer_pgm_init ); - - MLT_REGISTER_METADATA( mlt_service_filter_type, "chroma", metadata, "filter_chroma.yml" ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "chroma_hold", metadata, "filter_chroma_hold.yml" ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "threshold", metadata, "filter_mono.yml" ); - MLT_REGISTER_METADATA( mlt_service_filter_type, "shape", metadata, "filter_shape.yml" ); - MLT_REGISTER_METADATA( mlt_service_producer_type, "pgm", metadata, "producer_pgm.yml" ); -} From d3691ee6fb0b8741d439198c7c2acb278e842fea Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 15 Mar 2021 21:24:32 -0500 Subject: [PATCH 074/122] Update name and attribution for this contributor * Remove creator/author tags (use git log instead) * Change copyright to Meltytech, LLC --- src/modules/avformat/filter_swresample.c | 1 - src/modules/core/producer_timewarp.yml | 1 - src/modules/core/producer_tone.c | 1 - src/modules/core/producer_tone.yml | 1 - src/modules/jackrack/producer_ladspa.yml | 1 - src/modules/plus/consumer_blipflash.c | 3 +-- src/modules/plus/consumer_blipflash.yml | 3 +-- src/modules/plus/filter_dance.yml | 1 - src/modules/plus/filter_dynamic_loudness.c | 3 +-- src/modules/plus/filter_dynamic_loudness.yml | 3 +-- src/modules/plus/filter_dynamictext.yml | 1 - src/modules/plus/filter_fft.yml | 1 - src/modules/plus/filter_lift_gamma_gain.c | 2 +- src/modules/plus/filter_lift_gamma_gain.yml | 3 +-- src/modules/plus/filter_loudness.c | 3 +-- src/modules/plus/filter_loudness.yml | 3 +-- src/modules/plus/filter_loudness_meter.c | 3 +-- src/modules/plus/filter_loudness_meter.yml | 3 +-- src/modules/plus/filter_spot_remover.yml | 1 - src/modules/plus/filter_text.yml | 1 - src/modules/plus/filter_timer.yml | 1 - src/modules/plus/producer_blipflash.c | 3 +-- src/modules/plus/producer_blipflash.yml | 3 +-- src/modules/plus/producer_count.c | 3 +-- src/modules/plus/producer_count.yml | 3 +-- src/modules/qt/filter_audiospectrum.cpp | 1 - src/modules/qt/filter_audiospectrum.yml | 1 - src/modules/qt/filter_audiowaveform.yml | 1 - src/modules/qt/filter_lightshow.yml | 1 - src/modules/qt/filter_qtext.yml | 1 - src/modules/qt/graph.cpp | 1 - src/modules/qt/graph.h | 1 - src/modules/qt/producer_qtext.cpp | 3 +-- src/modules/qt/producer_qtext.yml | 3 +-- src/modules/rubberband/filter_rbpitch.yml | 1 - src/modules/sdl2/common.c | 3 +-- src/modules/sdl2/common.h | 1 - src/modules/vid.stab/common.c | 2 +- src/modules/vid.stab/common.h | 2 +- src/modules/vid.stab/filter_deshake.cpp | 2 +- src/modules/vid.stab/filter_vidstab.cpp | 2 +- src/tests/test_filter/test_filter.cpp | 2 +- src/tests/test_frame/test_frame.cpp | 2 +- 43 files changed, 23 insertions(+), 59 deletions(-) diff --git a/src/modules/avformat/filter_swresample.c b/src/modules/avformat/filter_swresample.c index 8bb6e33f5..0d3a8478e 100644 --- a/src/modules/avformat/filter_swresample.c +++ b/src/modules/avformat/filter_swresample.c @@ -1,7 +1,6 @@ /* * filter_swresample.c -- convert from one format/ configuration to another * Copyright (C) 2018 Meltytech, LLC - * Author: Brian Matherly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/core/producer_timewarp.yml b/src/modules/core/producer_timewarp.yml index 9252407e4..4df6c2137 100644 --- a/src/modules/core/producer_timewarp.yml +++ b/src/modules/core/producer_timewarp.yml @@ -4,7 +4,6 @@ identifier: timewarp title: Time Warp version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/core/producer_tone.c b/src/modules/core/producer_tone.c index 3766c87a8..6b183150a 100644 --- a/src/modules/core/producer_tone.c +++ b/src/modules/core/producer_tone.c @@ -1,7 +1,6 @@ /* * producer_tone.c -- audio tone generating producer * Copyright (C) 2014 Meltytech, LLC - * Author: Brian Matherly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/core/producer_tone.yml b/src/modules/core/producer_tone.yml index 24cf654f3..ffd34e9ae 100644 --- a/src/modules/core/producer_tone.yml +++ b/src/modules/core/producer_tone.yml @@ -4,7 +4,6 @@ identifier: tone title: Tone version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/jackrack/producer_ladspa.yml b/src/modules/jackrack/producer_ladspa.yml index 0b367ba13..23912cfba 100644 --- a/src/modules/jackrack/producer_ladspa.yml +++ b/src/modules/jackrack/producer_ladspa.yml @@ -6,7 +6,6 @@ version: 1 copyright: Copyright (C) 2013-2014 Meltytech, LLC license: GPLv2 language: en -creator: Brian Matherly tags: - Audio description: Generate audio using LADSPA plugins. diff --git a/src/modules/plus/consumer_blipflash.c b/src/modules/plus/consumer_blipflash.c index 00aec25f4..3595d91c2 100644 --- a/src/modules/plus/consumer_blipflash.c +++ b/src/modules/plus/consumer_blipflash.c @@ -1,8 +1,7 @@ /* * consumer_blipflash.c -- a consumer to measure A/V sync from a blip/flash * source - * Copyright (C) 2013 Brian Matherly - * Author: Brian Matherly + * Copyright (C) 2013 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/plus/consumer_blipflash.yml b/src/modules/plus/consumer_blipflash.yml index 5c8f40e50..56e933d1c 100644 --- a/src/modules/plus/consumer_blipflash.yml +++ b/src/modules/plus/consumer_blipflash.yml @@ -3,8 +3,7 @@ type: consumer identifier: blipflash title: Blip Flash version: 1 -copyright: Brian Matherly -creator: Brian Matherly +copyright: Meltytech, LLC license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_dance.yml b/src/modules/plus/filter_dance.yml index 3368390e9..4f89ad398 100644 --- a/src/modules/plus/filter_dance.yml +++ b/src/modules/plus/filter_dance.yml @@ -4,7 +4,6 @@ identifier: dance title: Dance version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_dynamic_loudness.c b/src/modules/plus/filter_dynamic_loudness.c index 85a02bd62..932817e4a 100644 --- a/src/modules/plus/filter_dynamic_loudness.c +++ b/src/modules/plus/filter_dynamic_loudness.c @@ -1,7 +1,6 @@ /* * filter_loudness.c -- normalize audio according to EBU R128 - * Copyright (C) 2014 Brian Matherly - * Author: Brian Matherly + * Copyright (C) 2014 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/plus/filter_dynamic_loudness.yml b/src/modules/plus/filter_dynamic_loudness.yml index 83b865040..cf990e0a2 100644 --- a/src/modules/plus/filter_dynamic_loudness.yml +++ b/src/modules/plus/filter_dynamic_loudness.yml @@ -3,8 +3,7 @@ type: filter identifier: dynamic_loudness title: Dynamic Loudness version: 1 -copyright: Brian Matherly -creator: Brian Matherly +copyright: Meltytech, LLC license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_dynamictext.yml b/src/modules/plus/filter_dynamictext.yml index 51c1d8682..ff9890e00 100644 --- a/src/modules/plus/filter_dynamictext.yml +++ b/src/modules/plus/filter_dynamictext.yml @@ -4,7 +4,6 @@ identifier: dynamictext title: Dynamic text version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_fft.yml b/src/modules/plus/filter_fft.yml index 0b6f9c9a8..e529fb40e 100644 --- a/src/modules/plus/filter_fft.yml +++ b/src/modules/plus/filter_fft.yml @@ -4,7 +4,6 @@ identifier: fft title: FFT version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_lift_gamma_gain.c b/src/modules/plus/filter_lift_gamma_gain.c index 9d1132184..29b29157c 100644 --- a/src/modules/plus/filter_lift_gamma_gain.c +++ b/src/modules/plus/filter_lift_gamma_gain.c @@ -1,6 +1,6 @@ /* * filter_lift_gamma_gain.cpp - * Copyright (C) 2014 Brian Matherly + * Copyright (C) 2014 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/plus/filter_lift_gamma_gain.yml b/src/modules/plus/filter_lift_gamma_gain.yml index a4a3be3ab..6d989d37d 100644 --- a/src/modules/plus/filter_lift_gamma_gain.yml +++ b/src/modules/plus/filter_lift_gamma_gain.yml @@ -3,8 +3,7 @@ type: filter identifier: lift_gamma_gain title: Lift, Gamma, and Gain version: 1 -copyright: Brian Matherly -creator: Brian Matherly +copyright: Meltytech, LLC license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_loudness.c b/src/modules/plus/filter_loudness.c index 0614fecc3..3612b586a 100644 --- a/src/modules/plus/filter_loudness.c +++ b/src/modules/plus/filter_loudness.c @@ -1,7 +1,6 @@ /* * filter_loudness.c -- normalize audio according to EBU R128 - * Copyright (C) 2014 Brian Matherly - * Author: Brian Matherly + * Copyright (C) 2014 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/plus/filter_loudness.yml b/src/modules/plus/filter_loudness.yml index 7c935b4e6..c7da8ff4e 100644 --- a/src/modules/plus/filter_loudness.yml +++ b/src/modules/plus/filter_loudness.yml @@ -3,8 +3,7 @@ type: filter identifier: loudness title: Loudness version: 1 -copyright: Brian Matherly -creator: Brian Matherly +copyright: Meltytech, LLC license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_loudness_meter.c b/src/modules/plus/filter_loudness_meter.c index 0247cc362..bcd720fa1 100644 --- a/src/modules/plus/filter_loudness_meter.c +++ b/src/modules/plus/filter_loudness_meter.c @@ -1,7 +1,6 @@ /* * filter_loudness_meter.c -- measure audio loudness according to EBU R128 - * Copyright (C) 2016 Brian Matherly - * Author: Brian Matherly + * Copyright (C) 2016 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/plus/filter_loudness_meter.yml b/src/modules/plus/filter_loudness_meter.yml index e6078af9e..6f4838618 100644 --- a/src/modules/plus/filter_loudness_meter.yml +++ b/src/modules/plus/filter_loudness_meter.yml @@ -3,8 +3,7 @@ type: filter identifier: loudness_meter title: Loudness Meter version: 1 -copyright: Brian Matherly -creator: Brian Matherly +copyright: Meltytech, LLC license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_spot_remover.yml b/src/modules/plus/filter_spot_remover.yml index dc07c8d7e..a427fec73 100644 --- a/src/modules/plus/filter_spot_remover.yml +++ b/src/modules/plus/filter_spot_remover.yml @@ -4,7 +4,6 @@ identifier: spot_remover title: Spot Remover version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_text.yml b/src/modules/plus/filter_text.yml index aefaca002..85f104dea 100644 --- a/src/modules/plus/filter_text.yml +++ b/src/modules/plus/filter_text.yml @@ -4,7 +4,6 @@ identifier: text title: Text version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/filter_timer.yml b/src/modules/plus/filter_timer.yml index 47d09a1fb..d803bfb30 100644 --- a/src/modules/plus/filter_timer.yml +++ b/src/modules/plus/filter_timer.yml @@ -4,7 +4,6 @@ identifier: timer title: Timer version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/producer_blipflash.c b/src/modules/plus/producer_blipflash.c index 83a386195..7bb4b1ba1 100644 --- a/src/modules/plus/producer_blipflash.c +++ b/src/modules/plus/producer_blipflash.c @@ -1,7 +1,6 @@ /* * producer_blipflash.c -- blip/flash generating producer - * Copyright (C) 2013 Brian Matherly - * Author: Brian Matherly + * Copyright (C) 2013 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/plus/producer_blipflash.yml b/src/modules/plus/producer_blipflash.yml index 8bec5a3f0..8b6f4e158 100644 --- a/src/modules/plus/producer_blipflash.yml +++ b/src/modules/plus/producer_blipflash.yml @@ -3,8 +3,7 @@ type: producer identifier: blipflash title: Blip Flash version: 1 -copyright: Brian Matherly -creator: Brian Matherly +copyright: Meltytech, LLC license: LGPLv2.1 language: en tags: diff --git a/src/modules/plus/producer_count.c b/src/modules/plus/producer_count.c index b00a5f1e9..2f9c42120 100644 --- a/src/modules/plus/producer_count.c +++ b/src/modules/plus/producer_count.c @@ -1,7 +1,6 @@ /* * producer_count.c -- counting producer - * Copyright (C) 2013 Brian Matherly - * Author: Brian Matherly + * Copyright (C) 2013 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/plus/producer_count.yml b/src/modules/plus/producer_count.yml index 4cd906844..024ce7779 100644 --- a/src/modules/plus/producer_count.yml +++ b/src/modules/plus/producer_count.yml @@ -3,8 +3,7 @@ type: producer identifier: count title: Count version: 1 -copyright: Brian Matherly -creator: Brian Matherly +copyright: Meltytech, LLC license: LGPLv2.1 language: en tags: diff --git a/src/modules/qt/filter_audiospectrum.cpp b/src/modules/qt/filter_audiospectrum.cpp index 69c3a7fd0..1dc620527 100644 --- a/src/modules/qt/filter_audiospectrum.cpp +++ b/src/modules/qt/filter_audiospectrum.cpp @@ -1,7 +1,6 @@ /* * filter_audiospectrum.cpp -- audio spectrum visualization filter * Copyright (c) 2015-2020 Meltytech, LLC - * Author: Brian Matherly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/qt/filter_audiospectrum.yml b/src/modules/qt/filter_audiospectrum.yml index 80d3eb9a5..969447fd5 100644 --- a/src/modules/qt/filter_audiospectrum.yml +++ b/src/modules/qt/filter_audiospectrum.yml @@ -4,7 +4,6 @@ identifier: audiospectrum title: Audio Spectrum Filter version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/qt/filter_audiowaveform.yml b/src/modules/qt/filter_audiowaveform.yml index 60bd13b13..50896dd5a 100644 --- a/src/modules/qt/filter_audiowaveform.yml +++ b/src/modules/qt/filter_audiowaveform.yml @@ -4,7 +4,6 @@ identifier: audiowaveform title: Audio Waveform Filter version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/qt/filter_lightshow.yml b/src/modules/qt/filter_lightshow.yml index 66938c4fb..056edf706 100644 --- a/src/modules/qt/filter_lightshow.yml +++ b/src/modules/qt/filter_lightshow.yml @@ -4,7 +4,6 @@ identifier: lightshow title: Light Show version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/qt/filter_qtext.yml b/src/modules/qt/filter_qtext.yml index 007d8a48d..7363cadba 100644 --- a/src/modules/qt/filter_qtext.yml +++ b/src/modules/qt/filter_qtext.yml @@ -4,7 +4,6 @@ identifier: qtext title: QText version: 3 copyright: Meltytech, LLC -creator: Brian Matherly license: LGPLv2.1 language: en tags: diff --git a/src/modules/qt/graph.cpp b/src/modules/qt/graph.cpp index ac2c8a99b..b9200bbf2 100644 --- a/src/modules/qt/graph.cpp +++ b/src/modules/qt/graph.cpp @@ -1,6 +1,5 @@ /* * Copyright (c) 2015-2020 Meltytech, LLC - * Author: Brian Matherly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/qt/graph.h b/src/modules/qt/graph.h index 695c3edab..69b53f1ea 100644 --- a/src/modules/qt/graph.h +++ b/src/modules/qt/graph.h @@ -1,6 +1,5 @@ /* * Copyright (c) 2015-2020 Meltytech, LLC - * Author: Brian Matherly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/qt/producer_qtext.cpp b/src/modules/qt/producer_qtext.cpp index 67075a57e..3a46975cf 100644 --- a/src/modules/qt/producer_qtext.cpp +++ b/src/modules/qt/producer_qtext.cpp @@ -1,7 +1,6 @@ /* * producer_qtext.c -- text generating producer - * Copyright (C) 2013 Brian Matherly - * Author: Brian Matherly + * Copyright (C) 2013 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/qt/producer_qtext.yml b/src/modules/qt/producer_qtext.yml index 76d1b7830..97d5486ef 100644 --- a/src/modules/qt/producer_qtext.yml +++ b/src/modules/qt/producer_qtext.yml @@ -3,8 +3,7 @@ type: producer identifier: qtext title: Qt Titler version: 1 -copyright: Brian Matherly -creator: Brian Matherly +copyright: Meltytech, LLC license: LGPLv2.1 language: en tags: diff --git a/src/modules/rubberband/filter_rbpitch.yml b/src/modules/rubberband/filter_rbpitch.yml index 671c29034..85de27ebf 100644 --- a/src/modules/rubberband/filter_rbpitch.yml +++ b/src/modules/rubberband/filter_rbpitch.yml @@ -4,7 +4,6 @@ identifier: rbpitch title: Rubberband Pitch version: 1 copyright: Meltytech, LLC -creator: Brian Matherly license: GPLv2 language: en tags: diff --git a/src/modules/sdl2/common.c b/src/modules/sdl2/common.c index 57311e6b3..67d068434 100644 --- a/src/modules/sdl2/common.c +++ b/src/modules/sdl2/common.c @@ -1,7 +1,6 @@ /* * common.h * Copyright (C) 2018 Meltytech, LLC - * Author: Brian Matherly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -73,4 +72,4 @@ SDL_AudioDeviceID sdl2_open_audio( const SDL_AudioSpec* desired, SDL_AudioSpec* } return dev; -} \ No newline at end of file +} diff --git a/src/modules/sdl2/common.h b/src/modules/sdl2/common.h index abe86ca99..23e5fbe19 100644 --- a/src/modules/sdl2/common.h +++ b/src/modules/sdl2/common.h @@ -1,7 +1,6 @@ /* * common.h * Copyright (C) 2018 Meltytech, LLC - * Author: Brian Matherly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/modules/vid.stab/common.c b/src/modules/vid.stab/common.c index 9899f3ed6..3da5df62f 100644 --- a/src/modules/vid.stab/common.c +++ b/src/modules/vid.stab/common.c @@ -1,6 +1,6 @@ /* * common.c - * Copyright (C) 2014 Brian Matherly + * Copyright (C) 2014 Meltytech, LLC * * 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 diff --git a/src/modules/vid.stab/common.h b/src/modules/vid.stab/common.h index ff175c2a5..967698072 100644 --- a/src/modules/vid.stab/common.h +++ b/src/modules/vid.stab/common.h @@ -1,7 +1,7 @@ /* * common.h * Copyright (C) 2013 Jakub Ksiezniak - * Copyright (C) 2014 Brian Matherly + * Copyright (C) 2014 Meltytech, LLC * * 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 diff --git a/src/modules/vid.stab/filter_deshake.cpp b/src/modules/vid.stab/filter_deshake.cpp index e9eb0f981..a601ce9aa 100644 --- a/src/modules/vid.stab/filter_deshake.cpp +++ b/src/modules/vid.stab/filter_deshake.cpp @@ -2,7 +2,7 @@ * filter_deshake.cpp * Copyright (C) 2013 Marco Gittler * Copyright (C) 2013 Jakub Ksiezniak - * Copyright (C) 2014 Brian Matherly + * Copyright (C) 2014 Meltytech, LLC * * 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 diff --git a/src/modules/vid.stab/filter_vidstab.cpp b/src/modules/vid.stab/filter_vidstab.cpp index 56704aaf0..b0beee4da 100644 --- a/src/modules/vid.stab/filter_vidstab.cpp +++ b/src/modules/vid.stab/filter_vidstab.cpp @@ -2,7 +2,7 @@ * filter_vidstab.cpp * Copyright (C) 2013 Marco Gittler * Copyright (C) 2013 Jakub Ksiezniak - * Copyright (C) 2014 Brian Matherly + * Copyright (C) 2014 Meltytech, LLC * * 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 diff --git a/src/tests/test_filter/test_filter.cpp b/src/tests/test_filter/test_filter.cpp index 1fb354886..58347ed26 100644 --- a/src/tests/test_filter/test_filter.cpp +++ b/src/tests/test_filter/test_filter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Brian Matherly + * Copyright (C) 2015 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/tests/test_frame/test_frame.cpp b/src/tests/test_frame/test_frame.cpp index df6869b57..3507e498e 100644 --- a/src/tests/test_frame/test_frame.cpp +++ b/src/tests/test_frame/test_frame.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Brian Matherly + * Copyright (C) 2015 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public From 1f4b41f3ce204c8f446bf959446bb05a3ea18558 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 15 Mar 2021 21:58:18 -0500 Subject: [PATCH 075/122] Remove mlt_frame.get_alpha_mask function pointer --- src/framework/mlt_frame.c | 12 ++---------- src/framework/mlt_frame.h | 6 ------ 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index e93d14934..777a52a91 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -349,7 +349,6 @@ int mlt_frame_set_image( mlt_frame self, uint8_t *image, int size, mlt_destructo int mlt_frame_set_alpha( mlt_frame self, uint8_t *alpha, int size, mlt_destructor destroy ) { - self->get_alpha_mask = NULL; return mlt_properties_set_data( MLT_FRAME_PROPERTIES( self ), "alpha", alpha, size, destroy, NULL ); } @@ -389,7 +388,6 @@ void mlt_frame_replace_image( mlt_frame self, uint8_t *image, mlt_image_format f mlt_properties_set_int( MLT_FRAME_PROPERTIES( self ), "width", width ); mlt_properties_set_int( MLT_FRAME_PROPERTIES( self ), "height", height ); mlt_properties_set_int( MLT_FRAME_PROPERTIES( self ), "format", format ); - self->get_alpha_mask = NULL; } static int generate_test_image( mlt_properties properties, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) @@ -540,10 +538,7 @@ uint8_t *mlt_frame_get_alpha_mask( mlt_frame self ) uint8_t *alpha = NULL; if ( self != NULL ) { - if ( self->get_alpha_mask != NULL ) - alpha = self->get_alpha_mask( self ); - if ( alpha == NULL ) - alpha = mlt_properties_get_data( &self->parent, "alpha", NULL ); + alpha = mlt_properties_get_data( &self->parent, "alpha", NULL ); if ( alpha == NULL ) { int size = mlt_properties_get_int( &self->parent, "width" ) * mlt_properties_get_int( &self->parent, "height" ); @@ -570,10 +565,7 @@ uint8_t *mlt_frame_get_alpha( mlt_frame self ) uint8_t *alpha = NULL; if ( self != NULL ) { - if ( self->get_alpha_mask != NULL ) - alpha = self->get_alpha_mask( self ); - if ( alpha == NULL ) - alpha = mlt_properties_get_data( &self->parent, "alpha", NULL ); + alpha = mlt_properties_get_data( &self->parent, "alpha", NULL ); } return alpha; } diff --git a/src/framework/mlt_frame.h b/src/framework/mlt_frame.h index fee520628..b0e02bc28 100644 --- a/src/framework/mlt_frame.h +++ b/src/framework/mlt_frame.h @@ -75,12 +75,6 @@ struct mlt_frame_s { struct mlt_properties_s parent; /**< \private A frame extends properties. */ - /** Get the alpha channel (callback function). - * \param self a frame - * \return the 8-bit alpha channel - */ - uint8_t * ( *get_alpha_mask )( mlt_frame self ); - /** Convert the image format (callback function). * \param self a frame * \param[in,out] image a buffer of image data From caae2f6f77feff4adff61d3635e8ad62fc4e2668 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Mon, 15 Mar 2021 18:09:48 -0700 Subject: [PATCH 076/122] remove mlt_geometry --- demo/consumers.ini | 8 +- demo/demo.ini | 1 - demo/mlt_bouncy | 5 +- demo/mlt_composite_transition | 2 +- demo/mlt_my_name_is | 6 +- demo/mlt_news | 2 +- demo/mlt_push | 6 +- demo/mlt_slideshow_black | 2 +- demo/mlt_squeeze_box | 6 +- demo/mlt_ticker | 5 +- demo/mlt_title_over_gfx | 7 +- demo/mlt_titleshadow_watermark | 4 +- src/framework/CMakeLists.txt | 2 - src/framework/Makefile | 2 - src/framework/mlt.h | 3 +- src/framework/mlt_animation.c | 5 +- src/framework/mlt_geometry.c | 714 ---------------------- src/framework/mlt_geometry.h | 85 --- src/framework/mlt_property.c | 4 +- src/mlt++/CMakeLists.txt | 2 - src/mlt++/Makefile | 1 - src/mlt++/Mlt.h | 1 - src/mlt++/MltGeometry.cpp | 105 ---- src/mlt++/MltGeometry.h | 81 --- src/modules/core/transition_composite.c | 367 +++-------- src/modules/core/transition_composite.h | 4 +- src/modules/core/transition_composite.yml | 41 +- src/modules/gdk/producer_pango.c | 24 +- src/modules/plus/transition_affine.c | 90 +-- src/modules/plus/transition_affine.yml | 37 +- src/swig/mlt.i | 1 - 31 files changed, 134 insertions(+), 1489 deletions(-) delete mode 100644 src/framework/mlt_geometry.c delete mode 100644 src/framework/mlt_geometry.h delete mode 100644 src/mlt++/MltGeometry.cpp delete mode 100644 src/mlt++/MltGeometry.h diff --git a/demo/consumers.ini b/demo/consumers.ini index f7363bb41..a69e723e8 100644 --- a/demo/consumers.ini +++ b/demo/consumers.ini @@ -1,7 +1,7 @@ -SDL Default sdl -SDL Half D1 sdl:360x288 rescale=nearest resize=1 -SDL High Latency sdl buffer=12 rescale=none -SDL Progressive sdl progressive=1 +SDL Default sdl2 +SDL Half D1 sdl2:360x288 rescale=nearest resize=1 +SDL High Latency sdl2 buffer=12 rescale=none +SDL Progressive sdl2 progressive=1 XML to Terminal xml XML to File xml: DeckLink decklink diff --git a/demo/demo.ini b/demo/demo.ini index cc347bebc..e2394f6f6 100644 --- a/demo/demo.ini +++ b/demo/demo.ini @@ -22,7 +22,6 @@ mlt_lcut L Cut clip1.dv,clip2.dv mlt_fade_black Fade from/to black/silence clip3.mpeg mlt_push Push wipe clip1.mpeg, clip2.mpeg mlt_ticker Ticker tape clip1.dv -mlt_attributes Attributes clip1.dv mlt_slideshow_black Composite slideshow photos mlt_slideshow2 Ken Burns slideshow photos mlt_pango_keyframes Pango Keyframed Markup pango_keyframes.mpl diff --git a/demo/mlt_bouncy b/demo/mlt_bouncy index 9cccc3afa..460507edf 100644 --- a/demo/mlt_bouncy +++ b/demo/mlt_bouncy @@ -2,10 +2,7 @@ melt \ clip3.dv \ -filter \ watermark:clip1.dv \ -composite.start=10%/10%:20%x20% \ -composite.key[33]=30%/70%:25%x25% \ -composite.key[66]=70%/30%:15%x15% \ -composite.end=70%/70%:20%x20% \ +composite.geometry="0=10%/10%:20%x20%; 33=30%/70%:25%x25%; 66=70%/30%:15%x15%; -1=70%/70%:20%x20%" \ composite.out=100 \ composite.sliced_composite=1 \ $* diff --git a/demo/mlt_composite_transition b/demo/mlt_composite_transition index d6e90b5f4..6a24f9b42 100644 --- a/demo/mlt_composite_transition +++ b/demo/mlt_composite_transition @@ -2,6 +2,6 @@ melt \ clip1.dv out=74 \ -track \ -blank 49 clip2.mpeg \ --transition composite:57%/10%:33%x33% end=0%/0%:100%x100% progressive=1 distort=true in=50 out=74 a_track=0 b_track=1 sliced_composite=1 \ +-transition composite:"0=57%/10%:33%x33%; -1=0%/0%:100%x100%" progressive=1 distort=true in=50 out=74 a_track=0 b_track=1 sliced_composite=1 \ -transition mix:-1 in=50 out=74 a_track=0 b_track=1 \ $* diff --git a/demo/mlt_my_name_is b/demo/mlt_my_name_is index fa4552460..41a799d35 100644 --- a/demo/mlt_my_name_is +++ b/demo/mlt_my_name_is @@ -4,7 +4,7 @@ clip3.dv \ "+My name is Inigo Montoya.txt" out=99 -blank 49 "+Prepare to die!.txt" out=99 \ -track \ -blank 74 "+You killed my father.txt" out=74 \ --transition composite:50%/20%:5%x4% end=10%/20%:80%x12% distort=1 halign=centre valign=centre in=0 out=99 a_track=0 b_track=1 sliced_composite=1 \ --transition composite:0%/70%:100%x10% end=100%/70%:100%x10% in=75 out=149 a_track=0 b_track=2 sliced_composite=1 \ --transition composite:25%/25%:50%x50%! in=150 out=249 a_track=0 b_track=1 sliced_composite=1 \ +-transition composite:"0=50%/20%:5%x4%; -1=10%/20%:80%x12%" distort=1 halign=centre valign=centre in=0 out=99 a_track=0 b_track=1 sliced_composite=1 \ +-transition composite:"0=0%/70%:100%x10%; -1=100%/70%:100%x10%" in=75 out=149 a_track=0 b_track=2 sliced_composite=1 \ +-transition composite:25%/25%:50%x50% in=150 out=249 a_track=0 b_track=1 sliced_composite=1 \ $* diff --git a/demo/mlt_news b/demo/mlt_news index 12074c3a5..303d8aa5c 100644 --- a/demo/mlt_news +++ b/demo/mlt_news @@ -12,7 +12,7 @@ pango: text=" Breaking News -transition mix:0.5 always_active=1 a_track=0 b_track=2 \ -transition composite geometry=50%/15%:37.5%x40% a_track=0 b_track=1 in=0 out=174 sliced_composite=1 \ -transition composite geometry=10%/15%:37.5%x40% a_track=0 b_track=2 in=0 out=199 sliced_composite=1 \ --transition composite geometry="50%/15%:37.5%x40%;-1=0%/0%:100%x100%" a_track=0 b_track=1 in=175 out=199 distort=1 sliced_composite=1 \ +-transition composite geometry="50%/15%:37.5%x40%; -1=0%/0%:100%x100%" a_track=0 b_track=1 in=175 out=199 distort=1 sliced_composite=1 \ -transition composite geometry=10%/65%:90%x20% a_track=0 b_track=3 in=0 out=199 sliced_composite=1 \ -transition composite geometry=10%/65%:90%x20% a_track=1 b_track=3 in=200 out=499 sliced_composite=1 \ $* diff --git a/demo/mlt_push b/demo/mlt_push index e1708d9e0..86b8e81f1 100644 --- a/demo/mlt_push +++ b/demo/mlt_push @@ -7,13 +7,11 @@ clip3.dv in=200 out=275 \ clip2.dv in=200 \ -transition \ composite in=50 out=75 a_track=0 b_track=1 \ -start=0/0:100%x100%:100 \ -end=100%/0:100%x100%:100 \ +geometry="0=0/0:100%x100%:100%; -1=100%/0:100%x100%:100%" \ sliced_composite=1 \ -transition \ composite in=50 out=75 a_track=0 b_track=2 \ -start=-100%/0:100%x100%:100 \ -end=0/0:100%x100%:100 \ +geometry="0=-100%/0:100%x100%:100%; -1=0/0:100%x100%:100%" \ sliced_composite=1 \ -transition \ mix:-1 in=50 out=75 a_track=1 b_track=2 \ diff --git a/demo/mlt_slideshow_black b/demo/mlt_slideshow_black index cc1f18680..6cefde3c3 100644 --- a/demo/mlt_slideshow_black +++ b/demo/mlt_slideshow_black @@ -1,3 +1,3 @@ melt photos/.all.jpg ttl=100 \ --filter watermark:colour:black reverse=1 composite.geometry="15%/15%:10%/10%;0.1625=0/0:100%x100%;-.1625=;-1=70%/70%:10%x10%" composite.mirror_off=1 composite.cycle=100 composite.fill=1 composite.valign=c composite.halign=c \ +-filter watermark:colour:black reverse=1 composite.geometry="0=15%/15%:10%/10%; 0.1625=0/0:100%x100%; -.1625=; -1=70%/70%:10%x10%" composite.mirror_off=1 composite.cycle=100 composite.fill=1 composite.valign=c composite.halign=c \ $* diff --git a/demo/mlt_squeeze_box b/demo/mlt_squeeze_box index 5f23fa389..234c74bb6 100644 --- a/demo/mlt_squeeze_box +++ b/demo/mlt_squeeze_box @@ -3,7 +3,7 @@ clip1.dv out=124 clip2.dv out=149 clip3.dv in=75 out=224 clip1.dv \ -track \ -blank 99 colour:black out=49 -blank 99 colour:black out=49 -blank 99 colour:black out=49 \ -group progressive=1 \ --transition composite:0%/0%:100%x100% key[25]=50%/0%:5%x100% end=0%/0%:100%x100% a_track=1 b_track=0 in=100 out=149 sliced_composite=1 \ --transition composite:0%/0%:100%x100% key[25]=0%/50%:100%x5% end=0%/0%:100%x100% a_track=1 b_track=0 in=250 out=299 sliced_composite=1 \ --transition composite:0%/0%:100%x100% key[25]=100%/0%:5%x100% end=0%/0%:100%x100% a_track=1 b_track=0 in=400 out=449 sliced_composite=1 \ +-transition composite:"0=0%/0%:100%x100%; 25=50%/0%:5%x100%; -1=0%/0%:100%x100%" a_track=1 b_track=0 in=100 out=149 sliced_composite=1 \ +-transition composite:"0=0%/0%:100%x100%; 25=0%/50%:100%x5%; -1=0%/0%:100%x100%" a_track=1 b_track=0 in=250 out=299 sliced_composite=1 \ +-transition composite:"0=0%/0%:100%x100%; 25=100%/0%:5%x100%; -1=0%/0%:100%x100%" a_track=1 b_track=0 in=400 out=449 sliced_composite=1 \ $* diff --git a/demo/mlt_ticker b/demo/mlt_ticker index 413c43661..c0afc068b 100644 --- a/demo/mlt_ticker +++ b/demo/mlt_ticker @@ -7,11 +7,10 @@ colour:0 out=299 \ out=299 \ -transition \ composite a_track=0 b_track=1 out=299 distort=1 \ -start=0/70%:100%x64:100 \ +geometry=0/70%:100%x11%:100% \ sliced_composite=1 \ -transition \ composite a_track=0 b_track=2 out=299 titles=1 \ -start=100%/70%:999%x20% \ -end=-299%/70%:999%x20% \ +geometry="0=100%/70%:999%x20%; -1=-299%/70%:999%x20%" \ sliced_composite=1 \ $* diff --git a/demo/mlt_title_over_gfx b/demo/mlt_title_over_gfx index 5b96628bb..f988ccea3 100644 --- a/demo/mlt_title_over_gfx +++ b/demo/mlt_title_over_gfx @@ -5,7 +5,7 @@ melt \ -track \ clip1.dv \ -transition \ - composite start=30%/20%:40%x60% \ + composite:30%/20%:40%x60% \ in=50 \ out=199 \ a_track=0 \ @@ -13,15 +13,12 @@ melt \ distort=1 \ sliced_composite=1 \ -transition \ - composite:0%/75%:100%x20%:0 \ + composite:"0=0%/75%:100%x20%:0; 24=0%/75%:100%x20%:100%; -25=0%/75%:100%x20%:100%; -1=0%/75%:100%x20%:0" \ in=50 \ out=199 \ a_track=2 \ b_track=0 \ - key[24]=0%/75%:100%x20%:100 \ - key[-25]=0%/75%:100%x20%:100 \ luma=luma1.pgm \ - end=0%/75%:100%x20%:0 \ distort=1 \ sliced_composite=1 \ $* diff --git a/demo/mlt_titleshadow_watermark b/demo/mlt_titleshadow_watermark index b137a535e..afe42f663 100644 --- a/demo/mlt_titleshadow_watermark +++ b/demo/mlt_titleshadow_watermark @@ -4,7 +4,7 @@ melt \ -track watermark1.png out=1000 \ -track clip3.dv \ -filter greyscale track=2 \ --transition composite:21%/11%:100%x100%:50 end=61%/41%:100%x100% out=99 a_track=3 b_track=1 sliced_composite=1 \ --transition composite:20%/10%:100%x100% end=60%/40%:100%x100% out=99 a_track=3 b_track=0 sliced_composite=1 \ +-transition composite:"0=21%/11%:100%x100%:50; -1=61%/41%:100%x100%" out=99 a_track=3 b_track=1 sliced_composite=1 \ +-transition composite:"0=20%/10%:100%x100%; -1=60%/40%:100%x100%" out=99 a_track=3 b_track=0 sliced_composite=1 \ -transition composite:85%/80%:10%x10%:30 out=1000 a_track=3 b_track=2 sliced_composite=1 \ $* diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 4865facfd..f89b6281c 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -11,7 +11,6 @@ set(MLT_PUPLIC_HEADERS mlt_field.h mlt_filter.h mlt_frame.h - mlt_geometry.h mlt_image.h mlt_link.h mlt_log.h @@ -46,7 +45,6 @@ add_library(mlt SHARED mlt_field.c mlt_filter.c mlt_frame.c - mlt_geometry.c mlt_image.c mlt_link.c mlt_log.c diff --git a/src/framework/Makefile b/src/framework/Makefile index 0fb2b58e2..0f812f53d 100644 --- a/src/framework/Makefile +++ b/src/framework/Makefile @@ -28,7 +28,6 @@ OBJS = mlt_audio.o \ mlt_image.o \ mlt_frame.o \ mlt_version.o \ - mlt_geometry.o \ mlt_deque.o \ mlt_property.o \ mlt_properties.o \ @@ -74,7 +73,6 @@ INCS = mlt_audio.h \ mlt_deque.h \ mlt_field.h \ mlt_frame.h \ - mlt_geometry.h \ mlt_playlist.h \ mlt_producer.h \ mlt_property.h \ diff --git a/src/framework/mlt.h b/src/framework/mlt.h index b9bff3f93..b8575b9a9 100644 --- a/src/framework/mlt.h +++ b/src/framework/mlt.h @@ -2,7 +2,7 @@ * \file mlt.h * \brief header file for lazy client and implementation code :-) * - * Copyright (C) 2003-2017 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -53,7 +53,6 @@ extern "C" #include "mlt_tractor.h" #include "mlt_tokeniser.h" #include "mlt_parser.h" -#include "mlt_geometry.h" #include "mlt_profile.h" #include "mlt_repository.h" #include "mlt_log.h" diff --git a/src/framework/mlt_animation.c b/src/framework/mlt_animation.c index d3fb9af71..2dc945f30 100644 --- a/src/framework/mlt_animation.c +++ b/src/framework/mlt_animation.c @@ -3,7 +3,7 @@ * \brief Property Animation class definition * \see mlt_animation_s * - * Copyright (C) 2004-2018 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -477,7 +477,8 @@ int mlt_animation_insert( mlt_animation self, mlt_animation_item item ) node->item.is_key = 1; node->item.keyframe_type = item->keyframe_type; node->item.property = mlt_property_init(); - mlt_property_pass( node->item.property, item->property ); + if (item->property) + mlt_property_pass( node->item.property, item->property ); // Determine if we need to insert or append to the list, or if it's a new list if ( self->nodes ) diff --git a/src/framework/mlt_geometry.c b/src/framework/mlt_geometry.c deleted file mode 100644 index 6cd496e64..000000000 --- a/src/framework/mlt_geometry.c +++ /dev/null @@ -1,714 +0,0 @@ -/** - * \file mlt_geometry.c - * \brief geometry animation API (deprecated) - * \deprecated use mlt_animation_s instead - * - * Copyright (C) 2004-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "mlt_geometry.h" -#include "mlt_tokeniser.h" -#include "mlt_factory.h" -#include "mlt_profile.h" - -#include -#include -#include - -/** private part of geometry animation item (deprecated) - * \deprecated use mlt_animation_s instead - */ - -typedef struct geometry_item_s -{ - struct mlt_geometry_item_s data; - struct geometry_item_s *next, *prev; -} -*geometry_item; - -/** private part of geometry object (deprecated) - * \deprecated use mlt_animation_s instead - */ - -typedef struct -{ - char *data; - int length; - int nw; - int nh; - geometry_item item; -} -geometry_s, *geometry; - -// Create a new geometry structure -mlt_geometry mlt_geometry_init( ) -{ - mlt_geometry self = calloc( 1, sizeof( struct mlt_geometry_s ) ); - if ( self != NULL ) - { - self->local = calloc( 1, sizeof( geometry_s ) ); - if ( self->local != NULL ) - { - geometry g = self->local; - g->nw = 720; - g->nh = 576; - } - else - { - free( self ); - self = NULL; - } - } - return self; -} - -/** A linear step -*/ - -static inline double linearstep( double start, double end, double position, int length ) -{ - double o = ( end - start ) / length; - return start + position * o; -} - -void mlt_geometry_interpolate( mlt_geometry self ) -{ - geometry g = self->local; - - // Parse of all items to ensure unspecified keys are calculated correctly - if ( g->item != NULL ) - { - int i = 0; - for ( i = 0; i < 5; i ++ ) - { - geometry_item current = g->item; - while( current != NULL ) - { - int fixed = current->data.f[ i ]; - if ( !fixed ) - { - geometry_item prev = current->prev; - geometry_item next = current->next; - - double prev_value = 0; - double next_value = 0; - double value = 0; - - while( prev != NULL && !prev->data.f[ i ] ) prev = prev->prev; - while( next != NULL && !next->data.f[ i ] ) next = next->next; - - switch( i ) - { - case 0: - if ( prev ) prev_value = prev->data.x; - if ( next ) next_value = next->data.x; - break; - case 1: - if ( prev ) prev_value = prev->data.y; - if ( next ) next_value = next->data.y; - break; - case 2: - if ( prev ) prev_value = prev->data.w; - if ( next ) next_value = next->data.w; - break; - case 3: - if ( prev ) prev_value = prev->data.h; - if ( next ) next_value = next->data.h; - break; - case 4: - if ( prev ) prev_value = prev->data.mix; - if ( next ) next_value = next->data.mix; - break; - } - - // This should never happen - if ( prev == NULL ) - current->data.f[ i ] = 1; - else if ( next == NULL ) - value = prev_value; - else - value = linearstep( prev_value, next_value, current->data.frame - prev->data.frame, next->data.frame - prev->data.frame ); - - switch( i ) - { - case 0: current->data.x = value; break; - case 1: current->data.y = value; break; - case 2: current->data.w = value; break; - case 3: current->data.h = value; break; - case 4: current->data.mix = value; break; - } - } - - // Move to the next item - current = current->next; - } - } - } -} - -static int mlt_geometry_drop( mlt_geometry self, geometry_item item ) -{ - geometry g = self->local; - - if ( item == g->item ) - { - g->item = item->next; - if ( g->item != NULL ) - g->item->prev = NULL; - // To ensure correct seeding, ensure all values are fixed - if ( g->item != NULL ) - { - g->item->data.f[0] = 1; - g->item->data.f[1] = 1; - g->item->data.f[2] = 1; - g->item->data.f[3] = 1; - g->item->data.f[4] = 1; - } - } - else if ( item->next != NULL && item->prev != NULL ) - { - item->prev->next = item->next; - item->next->prev = item->prev; - } - else if ( item->next != NULL ) - { - item->next->prev = item->prev; - } - else if ( item->prev != NULL ) - { - item->prev->next = item->next; - } - - free( item ); - - return 0; -} - -static void mlt_geometry_clean( mlt_geometry self ) -{ - geometry g = self->local; - free( g->data ); - g->data = NULL; - while( g->item ) - mlt_geometry_drop( self, g->item ); -} - -// Parse the geometry specification for a given length and normalised width/height (-1 for default) -// data is constructed as: [frame=]X/Y:WxH[:mix][!][;[frame=]X/Y:WxH[:mix][!]]* -// and X, Y, W and H can have trailing % chars to indicate percentage of normalised size -// Append a pair's value with ! to enable distort. -int mlt_geometry_parse( mlt_geometry self, char *data, int length, int nw, int nh ) -{ - int i = 0; - - // Create a tokeniser - mlt_tokeniser tokens = mlt_tokeniser_init( ); - - // Get the local/private structure - geometry g = self->local; - - // Clean the existing geometry - mlt_geometry_clean( self ); - - // Update the info on the data - if ( length != -1 ) - g->length = length; - if ( nw != -1 ) - g->nw = nw; - if ( nh != -1 ) - g->nh = nh; - if ( data != NULL ) - g->data = strdup( data ); - - // Tokenise - if ( data != NULL ) - mlt_tokeniser_parse_new( tokens, data, ";" ); - - // Iterate through each token - for ( i = 0; i < mlt_tokeniser_count( tokens ); i ++ ) - { - struct mlt_geometry_item_s item; - char *value = mlt_tokeniser_get_string( tokens, i ); - - // If no data in keyframe, drop it (trailing semicolon) - if ( value == NULL || !strcmp( value, "" ) ) - continue; - - // Set item to 0 - memset( &item, 0, sizeof( struct mlt_geometry_item_s ) ); - - // Now parse the item - mlt_geometry_parse_item( self, &item, value ); - - // Now insert into place - mlt_geometry_insert( self, &item ); - } - mlt_geometry_interpolate( self ); - - // Remove the tokeniser - mlt_tokeniser_close( tokens ); - - // ??? - return 0; -} - -// Conditionally refresh in case of a change -int mlt_geometry_refresh( mlt_geometry self, char *data, int length, int nw, int nh ) -{ - geometry g = self->local; - int changed = ( length != -1 && length != g->length ); - changed = changed || ( nw != -1 && nw != g->nw ); - changed = changed || ( nh != -1 && nh != g->nh ); - changed = changed || ( data != NULL && ( g->data == NULL || strcmp( data, g->data ) ) ); - if ( changed ) - return mlt_geometry_parse( self, data, length, nw, nh ); - return -1; -} - -int mlt_geometry_get_length( mlt_geometry self ) -{ - // Get the local/private structure - geometry g = self->local; - - // return the length - return g->length; -} - -void mlt_geometry_set_length( mlt_geometry self, int length ) -{ - // Get the local/private structure - geometry g = self->local; - - // set the length - g->length = length; -} - -int mlt_geometry_parse_item( mlt_geometry self, mlt_geometry_item item, char *value ) -{ - int ret = 0; - - // Get the local/private structure - geometry g = self->local; - - if ( value != NULL && strcmp( value, "" ) ) - { - char *p = strchr( value, '=' ); - int count = 0; - double temp; - - // Determine if a position has been specified - if ( p != NULL ) - { - temp = atof( value ); - if ( temp > -1 && temp < 1 ) - item->frame = temp * g->length; - else - item->frame = temp; - value = p + 1; - } - - // Special case - frame < 0 - if ( item->frame < 0 ) - item->frame += g->length; - - // Obtain the current value at this position - self allows new - // frames to be created which don't specify all values - mlt_geometry_fetch( self, item, item->frame ); - - // Special case - when an empty string is specified, all values are fixed - // TODO: Check if this is logical - it's convenient, but it's also odd... - if ( !*value ) - { - item->f[0] = 1; - item->f[1] = 1; - item->f[2] = 1; - item->f[3] = 1; - item->f[4] = 1; - } - - // Iterate through the remainder of value - while( *value ) - { - // Get the value - temp = strtod( value, &p ); - - // Check if a value was specified - if ( p != value ) - { - // Handle the % case - if ( *p == '%' ) - { - if ( count == 0 || count == 2 ) - temp *= g->nw / 100.0; - else if ( count == 1 || count == 3 ) - temp *= g->nh / 100.0; - p ++; - } - - // Special case - distort token - if ( *p == '!' || *p == '*' ) - { - p ++; - item->distort = 1; - } - - // Actually, we don't care about the delimiter at all.. - if ( *p ) p ++; - - // Assign to the item - switch( count ) - { - case 0: item->x = temp; item->f[0] = 1; break; - case 1: item->y = temp; item->f[1] = 1; break; - case 2: item->w = temp; item->f[2] = 1; break; - case 3: item->h = temp; item->f[3] = 1; break; - case 4: item->mix = temp; item->f[4] = 1; break; - } - } - else - { - p ++; - } - - // Update the value pointer - value = p; - count ++; - } - } - else - { - ret = 1; - } - - return ret; -} - -// Fetch a geometry item for an absolute position -int mlt_geometry_fetch( mlt_geometry self, mlt_geometry_item item, float position ) -{ - // Get the local geometry - geometry g = self->local; - - // Need to find the nearest key to the position specified - geometry_item key = g->item; - - // Iterate through the keys until we reach last or have - while( key != NULL && key->next != NULL && position >= key->next->data.frame ) - key = key->next; - - if ( key != NULL ) - { - // Position is situated before the first key - all zeroes - if ( position < key->data.frame ) - { - memset( item, 0, sizeof( struct mlt_geometry_item_s ) ); - item->mix = 100; - } - // Position is a key itself - no iterpolation need - else if ( position == key->data.frame ) - { - memcpy( item, &key->data, sizeof( struct mlt_geometry_item_s ) ); - } - // Position is after the last key - no interpolation, but not a key frame - else if ( key->next == NULL ) - { - memcpy( item, &key->data, sizeof( struct mlt_geometry_item_s ) ); - item->key = 0; - item->f[ 0 ] = 0; - item->f[ 1 ] = 0; - item->f[ 2 ] = 0; - item->f[ 3 ] = 0; - item->f[ 4 ] = 0; - } - // Interpolation is needed - position > key and there is a following key - else - { - item->key = 0; - item->frame = position; - position -= key->data.frame; - item->x = linearstep( key->data.x, key->next->data.x, position, key->next->data.frame - key->data.frame ); - item->y = linearstep( key->data.y, key->next->data.y, position, key->next->data.frame - key->data.frame ); - item->w = linearstep( key->data.w, key->next->data.w, position, key->next->data.frame - key->data.frame ); - item->h = linearstep( key->data.h, key->next->data.h, position, key->next->data.frame - key->data.frame ); - item->mix = linearstep( key->data.mix, key->next->data.mix, position, key->next->data.frame - key->data.frame ); - item->distort = key->data.distort; - position += key->data.frame; - } - - item->frame = position; - } - else - { - memset( item, 0, sizeof( struct mlt_geometry_item_s ) ); - item->frame = position; - item->mix = 100; - } - - return key == NULL; -} - -// Specify a geometry item at an absolute position -int mlt_geometry_insert( mlt_geometry self, mlt_geometry_item item ) -{ - // Get the local/private geometry structure - geometry g = self->local; - - // Create a new local item (this may be removed if a key already exists at self position) - geometry_item gi = calloc( 1, sizeof( struct geometry_item_s ) ); - memcpy( &gi->data, item, sizeof( struct mlt_geometry_item_s ) ); - gi->data.key = 1; - - // Determine if we need to insert or append to the list, or if it's a new list - if ( g->item != NULL ) - { - // Get the first item - geometry_item place = g->item; - - // Locate an existing nearby item - while ( place->next != NULL && item->frame > place->data.frame ) - place = place->next; - - if ( item->frame < place->data.frame ) - { - if ( place == g->item ) - g->item = gi; - if ( place->prev ) - place->prev->next = gi; - gi->next = place; - gi->prev = place->prev; - place->prev = gi; - } - else if ( item->frame > place->data.frame ) - { - if ( place->next ) - place->next->prev = gi; - gi->next = place->next; - gi->prev = place; - place->next = gi; - } - else - { - memcpy( &place->data, &gi->data, sizeof( struct mlt_geometry_item_s ) ); - free( gi ); - } - } - else - { - // Set the first item - g->item = gi; - - // To ensure correct seeding, ensure all values are fixed - g->item->data.f[0] = 1; - g->item->data.f[1] = 1; - g->item->data.f[2] = 1; - g->item->data.f[3] = 1; - g->item->data.f[4] = 1; - } - - // TODO: Error checking - return 0; -} - -// Remove the key at the specified position -int mlt_geometry_remove( mlt_geometry self, int position ) -{ - int ret = 1; - - // Get the local/private geometry structure - geometry g = self->local; - - // Get the first item - geometry_item place = g->item; - - while( place != NULL && position != place->data.frame ) - place = place->next; - - if ( place != NULL && position == place->data.frame ) - ret = mlt_geometry_drop( self, place ); - - return ret; -} - -// Get the key at the position or the next following -int mlt_geometry_next_key( mlt_geometry self, mlt_geometry_item item, int position ) -{ - // Get the local/private geometry structure - geometry g = self->local; - - // Get the first item - geometry_item place = g->item; - - while( place != NULL && position > place->data.frame ) - place = place->next; - - if ( place != NULL ) - memcpy( item, &place->data, sizeof( struct mlt_geometry_item_s ) ); - - return place == NULL; -} - -// Get the key at the position or the previous key -int mlt_geometry_prev_key( mlt_geometry self, mlt_geometry_item item, int position ) -{ - // Get the local/private geometry structure - geometry g = self->local; - - // Get the first item - geometry_item place = g->item; - - while( place != NULL && place->next != NULL && position >= place->next->data.frame ) - place = place->next; - - if ( place != NULL ) - memcpy( item, &place->data, sizeof( struct mlt_geometry_item_s ) ); - - return place == NULL; -} - -char *mlt_geometry_serialise_cut( mlt_geometry self, int in, int out ) -{ - geometry g = self->local; - struct mlt_geometry_item_s item; - char *ret = malloc( 1000 ); - int used = 0; - int size = 1000; - - if ( in == -1 ) - in = 0; - if ( out == -1 ) - out = mlt_geometry_get_length( self ); - - if ( ret != NULL ) - { - char temp[ 100 ]; - - strcpy( ret, "" ); - - item.frame = in; - - while( 1 ) - { - strcpy( temp, "" ); - - // If it's the first frame, then it's not necessarily a key - if ( item.frame == in ) - { - if ( mlt_geometry_fetch( self, &item, item.frame ) ) - break; - - // If the first key is larger than the current position - // then do nothing here - if ( g->item->data.frame > item.frame ) - { - item.frame ++; - continue; - } - - // To ensure correct seeding, ensure all values are fixed - item.f[0] = 1; - item.f[1] = 1; - item.f[2] = 1; - item.f[3] = 1; - item.f[4] = 1; - } - // Typically, we move from key to key - else if ( item.frame < out ) - { - if ( mlt_geometry_next_key( self, &item, item.frame ) ) - break; - - // Special case - crop at the out point - if ( item.frame > out ) - mlt_geometry_fetch( self, &item, out ); - } - // We've handled the last key - else - { - break; - } - - if ( item.frame - in != 0 ) - sprintf( temp, "%d=", item.frame - in ); - - if ( item.f[0] ) - sprintf( temp + strlen( temp ), "%g", item.x ); - if ( item.f[1] ) { - strcat( temp, "/" ); - sprintf( temp + strlen( temp ), "%g", item.y ); - } - if ( item.f[2] ) { - strcat( temp, ":" ); - sprintf( temp + strlen( temp ), "%g", item.w ); - } - if ( item.f[3] ) { - strcat( temp, "x" ); - sprintf( temp + strlen( temp ), "%g", item.h ); - } - if ( item.f[4] ) { - strcat( temp, ":" ); - sprintf( temp + strlen( temp ), "%g", item.mix ); - } - - if ( used + strlen( temp ) + 2 > size ) // +2 for ';' and NULL - { - size += 1000; - ret = realloc( ret, size ); - } - - if ( ret != NULL && used != 0 ) - { - used ++; - strcat( ret, ";" ); - } - if ( ret != NULL ) - { - used += strlen( temp ); - strcat( ret, temp ); - } - - item.frame ++; - } - } - - return ret; -} - -// Serialise the current geometry -char *mlt_geometry_serialise( mlt_geometry self ) -{ - geometry g = self->local; - char *ret = mlt_geometry_serialise_cut( self, 0, g->length ); - if ( ret ) - { - free( g->data ); - g->data = ret; - } - return strdup( ret ); -} - -// Close the geometry -void mlt_geometry_close( mlt_geometry self ) -{ - if ( self != NULL ) - { - mlt_geometry_clean( self ); - free( self->local ); - free( self ); - } -} - - diff --git a/src/framework/mlt_geometry.h b/src/framework/mlt_geometry.h deleted file mode 100644 index c15531e55..000000000 --- a/src/framework/mlt_geometry.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * \file mlt_geometry.h - * \brief geometry animation API (deprecated) - * \deprecated use mlt_animation_s instead - * - * Copyright (C) 2004-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MLT_GEOMETRY_H -#define MLT_GEOMETRY_H - -#include "mlt_types.h" - -/** geometry animation item (deprecated) - * \deprecated use mlt_animation_s instead - */ - -struct mlt_geometry_item_s -{ - /* Will be 1 when this is a key frame */ - int key; - /* The actual frame this corresponds to */ - int frame; - /* Distort */ - int distort; - /* x,y are upper left */ - float x, y, w, h, mix; - /* Indicates which values are fixed */ - int f[ 5 ]; -}; - -/** geometry object (deprecated) - * \deprecated use mlt_animation_s instead - */ - -struct mlt_geometry_s -{ - void *local; -}; - -/* Create a new geometry structure */ -extern mlt_geometry mlt_geometry_init( ); -/* Parse the geometry specification for a given length and normalised width/height (-1 for default) */ -extern int mlt_geometry_parse( mlt_geometry self, char *data, int length, int nw, int nh ); -/* Conditionally refresh the geometry if it's modified */ -extern int mlt_geometry_refresh( mlt_geometry self, char *data, int length, int nw, int nh ); -/* Get and set the length */ -extern int mlt_geometry_get_length( mlt_geometry self ); -extern void mlt_geometry_set_length( mlt_geometry self, int length ); -/* Parse an item - doesn't affect the geometry itself but uses current information for evaluation */ -/* (item->frame should be specified if not included in the data itself) */ -extern int mlt_geometry_parse_item( mlt_geometry self, mlt_geometry_item item, char *data ); -/* Fetch a geometry item for an absolute position */ -extern int mlt_geometry_fetch( mlt_geometry self, mlt_geometry_item item, float position ); -/* Specify a geometry item at an absolute position */ -extern int mlt_geometry_insert( mlt_geometry self, mlt_geometry_item item ); -/* Remove the key at the specified position */ -extern int mlt_geometry_remove( mlt_geometry self, int position ); -/* Typically, re-interpolate after a series of insertions or removals. */ -extern void mlt_geometry_interpolate( mlt_geometry self ); -/* Get the key at the position or the next following */ -extern int mlt_geometry_next_key( mlt_geometry self, mlt_geometry_item item, int position ); -extern int mlt_geometry_prev_key( mlt_geometry self, mlt_geometry_item item, int position ); -/* Serialise the current geometry */ -extern char *mlt_geometry_serialise_cut( mlt_geometry self, int in, int out ); -extern char *mlt_geometry_serialise( mlt_geometry self ); -/* Close the geometry */ -extern void mlt_geometry_close( mlt_geometry self ); - -#endif - diff --git a/src/framework/mlt_property.c b/src/framework/mlt_property.c index bcc8909a8..5b02daa18 100644 --- a/src/framework/mlt_property.c +++ b/src/framework/mlt_property.c @@ -3,7 +3,7 @@ * \brief Property class definition * \see mlt_property_s * - * Copyright (C) 2003-2020 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1606,7 +1606,7 @@ mlt_animation mlt_property_get_animation( mlt_property self ) /** Convert a rectangle value into a string. * - * Unlike the deprecated mlt_geometry API, the canonical form of a mlt_rect + * The canonical form of a mlt_rect * is a space delimited "x y w h o" even though many kinds of field delimiters * may be used to convert a string to a rectangle. * \private \memberof mlt_property_s diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index 9a7138538..8dd0f5dd0 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -13,7 +13,6 @@ set(MLTPP_PUPLIC_HEADERS MltFilteredConsumer.h MltFilteredProducer.h MltFrame.h - MltGeometry.h MltImage.h MltLink.h MltMultitrack.h @@ -43,7 +42,6 @@ add_library(mlt++ SHARED MltFilteredConsumer.cpp MltFilteredProducer.cpp MltFrame.cpp - MltGeometry.cpp MltImage.cpp MltLink.cpp MltMultitrack.cpp diff --git a/src/mlt++/Makefile b/src/mlt++/Makefile index a883d5790..29adbbded 100644 --- a/src/mlt++/Makefile +++ b/src/mlt++/Makefile @@ -38,7 +38,6 @@ OBJS = MltAudio.o \ MltFilteredConsumer.o \ MltFilteredProducer.o \ MltFrame.o \ - MltGeometry.o \ MltImage.o \ MltLink.o \ MltMultitrack.o \ diff --git a/src/mlt++/Mlt.h b/src/mlt++/Mlt.h index 68ebf3798..9253b408a 100644 --- a/src/mlt++/Mlt.h +++ b/src/mlt++/Mlt.h @@ -32,7 +32,6 @@ #include "MltFilter.h" #include "MltFilteredConsumer.h" #include "MltFrame.h" -#include "MltGeometry.h" #include "MltImage.h" #include "MltMultitrack.h" #include "MltParser.h" diff --git a/src/mlt++/MltGeometry.cpp b/src/mlt++/MltGeometry.cpp deleted file mode 100644 index 254e1f172..000000000 --- a/src/mlt++/MltGeometry.cpp +++ /dev/null @@ -1,105 +0,0 @@ -/** - * MltGeometry.cpp - MLT Wrapper - * Copyright (C) 2004-2015 Meltytech, LLC - * Author: Charles Yates - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include "MltGeometry.h" -using namespace Mlt; - -Geometry::Geometry( char *data, int length, int nw, int nh ) -{ - geometry = mlt_geometry_init( ); - parse( data, length, nw, nh ); -} - -Geometry::~Geometry( ) -{ - mlt_geometry_close( geometry ); -} - -int Geometry::parse( char *data, int length, int nw, int nh ) -{ - return mlt_geometry_parse( geometry, data, length, nw, nh ); -} - -// Fetch a geometry item for an absolute position -int Geometry::fetch( GeometryItem &item, float position ) -{ - return mlt_geometry_fetch( geometry, item.get_item( ), position ); -} - -int Geometry::fetch( GeometryItem *item, float position ) -{ - return mlt_geometry_fetch( geometry, item->get_item( ), position ); -} - -// Specify a geometry item at an absolute position -int Geometry::insert( GeometryItem &item ) -{ - return mlt_geometry_insert( geometry, item.get_item( ) ); -} - -int Geometry::insert( GeometryItem *item ) -{ - return mlt_geometry_insert( geometry, item->get_item( ) ); -} - -// Remove the key at the specified position -int Geometry::remove( int position ) -{ - return mlt_geometry_remove( geometry, position ); -} - -void Geometry::interpolate( ) -{ - mlt_geometry_interpolate( geometry ); -} - -// Get the key at the position or the next following -int Geometry::next_key( GeometryItem &item, int position ) -{ - return mlt_geometry_next_key( geometry, item.get_item( ), position ); -} - -int Geometry::next_key( GeometryItem *item, int position ) -{ - return mlt_geometry_next_key( geometry, item->get_item( ), position ); -} - -int Geometry::prev_key( GeometryItem &item, int position ) -{ - return mlt_geometry_prev_key( geometry, item.get_item( ), position ); -} - -int Geometry::prev_key( GeometryItem *item, int position ) -{ - return mlt_geometry_prev_key( geometry, item->get_item( ), position ); -} - -// Serialise the current geometry -char *Geometry::serialise( int in, int out ) -{ - return mlt_geometry_serialise_cut( geometry, in, out ); -} - -char *Geometry::serialise( ) -{ - return mlt_geometry_serialise( geometry ); -} - diff --git a/src/mlt++/MltGeometry.h b/src/mlt++/MltGeometry.h deleted file mode 100644 index 509061363..000000000 --- a/src/mlt++/MltGeometry.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * MltGeometry.h - MLT Wrapper - * Copyright (C) 2004-2015 Meltytech, LLC - * Author: Charles Yates - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef MLTPP_GEOMETRY_H -#define MLTPP_GEOMETRY_H - -#include "MltConfig.h" - -#include - -namespace Mlt -{ - // Just for consistent naming purposes - class MLTPP_DECLSPEC GeometryItem - { - private: - struct mlt_geometry_item_s item; - public: - mlt_geometry_item get_item( ) { return &item; } - bool key( ) { return item.key != 0; } - int frame( ) { return item.frame; } - void frame( int value ) { item.frame = value; } - float x( ) { return item.x; } - void x( float value ) { item.f[0] = 1; item.x = value; } - float y( ) { return item.y; } - void y( float value ) { item.f[1] = 1; item.y = value; } - float w( ) { return item.w; } - void w( float value ) { item.f[2] = 1; item.w = value; } - float h( ) { return item.h; } - void h( float value ) { item.f[3] = 1; item.h = value; } - float mix( ) { return item.mix; } - void mix( float value ) { item.f[4] = 1; item.mix = value; } - }; - - class MLTPP_DECLSPEC Geometry - { - private: - mlt_geometry geometry; - public: - Geometry( char *data = NULL, int length = 0, int nw = -1, int nh = -1 ); - ~Geometry( ); - int parse( char *data, int length, int nw = -1, int nh = -1 ); - // Fetch a geometry item for an absolute position - int fetch( GeometryItem &item, float position ); - int fetch( GeometryItem *item, float position ); - // Specify a geometry item at an absolute position - int insert( GeometryItem &item ); - int insert( GeometryItem *item ); - // Remove the key at the specified position - int remove( int position ); - void interpolate( ); - // Get the key at the position or the next following - int next_key( GeometryItem &item, int position ); - int next_key( GeometryItem *item, int position ); - int prev_key( GeometryItem &item, int position ); - int prev_key( GeometryItem *item, int position ); - // Serialise the current geometry - char *serialise( int in, int out ); - char *serialise( ); - }; -} - -#endif - diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index f382ba1b8..636902864 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -1,6 +1,6 @@ /* * transition_composite.c -- compose one image over another using alpha channel - * Copyright (C) 2003-2020 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,6 +26,7 @@ #include #include #include +#include typedef void ( *composite_line_fn )( uint8_t *dest, uint8_t *src, int width_src, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int softness, uint32_t step ); @@ -34,7 +35,7 @@ typedef void ( *composite_line_fn )( uint8_t *dest, uint8_t *src, int width_src, struct geometry_s { - struct mlt_geometry_item_s item; + mlt_rect item; int nw; // normalised width int nh; // normalised height int sw; // scaled width, not including consumer scale based upon w/nw @@ -63,105 +64,6 @@ static int alignment_parse( char* align ) return ret; } -/** Calculate real geometry. -*/ - -static void geometry_calculate( mlt_transition self, struct geometry_s *output, double position ) -{ - mlt_properties properties = MLT_TRANSITION_PROPERTIES( self ); - mlt_geometry geometry = mlt_properties_get_data( properties, "geometries", NULL ); - int mirror_off = mlt_properties_get_int( properties, "mirror_off" ); - int repeat_off = mlt_properties_get_int( properties, "repeat_off" ); - int length = mlt_geometry_get_length( geometry ); - - // Allow wrapping - if ( !repeat_off && position >= length && length != 0 ) - { - int section = position / length; - position -= section * length; - if ( !mirror_off && section % 2 == 1 ) - position = length - position; - } - - // Fetch the key for the position - mlt_geometry_fetch( geometry, &output->item, position ); -} - -static mlt_geometry transition_parse_keys( mlt_transition self, int normalised_width, int normalised_height ) -{ - // Loop variable for property interrogation - int i = 0; - - // Get the properties of the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( self ); - - // Create an empty geometries object - mlt_geometry geometry = mlt_geometry_init( ); - - // Get the duration - mlt_position length = mlt_transition_get_length( self ); - double cycle = mlt_properties_get_double( properties, "cycle" ); - - // Get the new style geometry string - char *property = mlt_properties_get( properties, "geometry" ); - - // Allow a geometry repeat cycle - if ( cycle >= 1 ) - length = cycle; - else if ( cycle > 0 ) - length *= cycle; - - // Parse the geometry if we have one - mlt_geometry_parse( geometry, property, length, normalised_width, normalised_height ); - - // Check if we're using the old style geometry - if ( property == NULL ) - { - // DEPRECATED: Multiple keys for geometry information is inefficient and too rigid for - // practical use - while deprecated, it has been slightly extended too - keys can now - // be specified out of order, and can be blanked or NULL to simulate removal - - // Structure to use for parsing and inserting - struct mlt_geometry_item_s item; - - // Parse the start property - item.frame = 0; - if ( mlt_geometry_parse_item( geometry, &item, mlt_properties_get( properties, "start" ) ) == 0 ) - mlt_geometry_insert( geometry, &item ); - - // Parse the keys in between - for ( i = 0; i < mlt_properties_count( properties ); i ++ ) - { - // Get the name of the property - char *name = mlt_properties_get_name( properties, i ); - - // Check that it's valid - if ( !strncmp( name, "key[", 4 ) ) - { - // Get the value of the property - char *value = mlt_properties_get_value( properties, i ); - - // Determine the frame number - item.frame = atoi( name + 4 ); - - // Parse and add to the list - if ( mlt_geometry_parse_item( geometry, &item, value ) == 0 ) - mlt_geometry_insert( geometry, &item ); - else - fprintf( stderr, "Invalid Key - skipping %s = %s\n", name, value ); - } - } - - // Parse the end - item.frame = -1; - if ( mlt_geometry_parse_item( geometry, &item, mlt_properties_get( properties, "end" ) ) == 0 ) - mlt_geometry_insert( geometry, &item ); - mlt_geometry_interpolate( geometry ); - } - - return geometry; -} - /** Adjust position according to scaled size and alignment properties. */ @@ -371,8 +273,8 @@ static int composite_yuv( uint8_t *p_dest, int width_dest, int height_dest, uint int stride_src = geometry->sw * bpp; int stride_dest = width_dest * bpp; int i_softness = ( 1 << 16 ) * softness; - int weight = ( ( 1 << 16 ) * geometry->item.mix + 50 ) / 100; - uint32_t luma_step = ( ( ( 1 << 16 ) - 1 ) * geometry->item.mix + 50 ) / 100 * ( 1.0 + softness ); + int weight = ( ( 1 << 16 ) * geometry->item.o + 50 ) / 100; + uint32_t luma_step = ( ( ( 1 << 16 ) - 1 ) * geometry->item.o + 50 ) / 100 * ( 1.0 + softness ); // Adjust to consumer scale int x = rint( geometry->item.x * width_dest / geometry->nw ); @@ -770,7 +672,7 @@ static int get_b_frame_image( mlt_transition self, mlt_frame b_frame, uint8_t ** geometry->sh = scaled_height; } // Normalise aspect ratios and scale preserving aspect ratio - else if ( mlt_properties_get_int( properties, "aligned" ) && mlt_properties_get_int( properties, "distort" ) == 0 && mlt_properties_get_int( b_props, "distort" ) == 0 && geometry->item.distort == 0 ) + else if ( mlt_properties_get_int( properties, "aligned" ) && mlt_properties_get_int( properties, "distort" ) == 0 && mlt_properties_get_int( b_props, "distort" ) == 0 ) { // Adjust b_frame pixel aspect int normalised_width = geometry->item.w; @@ -856,228 +758,105 @@ static int get_b_frame_image( mlt_transition self, mlt_frame b_frame, uint8_t ** return !error && image; } -static void crop_calculate( mlt_transition self, mlt_properties properties, struct geometry_s *result, double position ) +static void crop_calculate( mlt_transition self, struct geometry_s *result, double position ) { + // Get the properties from the transition + mlt_properties properties = MLT_TRANSITION_PROPERTIES( self ); + // Initialize panning info result->x_src = 0; result->y_src = 0; if ( mlt_properties_get( properties, "crop" ) ) { - mlt_geometry crop = mlt_properties_get_data( properties, "crop_geometry", NULL ); - if ( !crop ) - { - crop = mlt_geometry_init(); - mlt_position length = mlt_transition_get_length( self ); - double cycle = mlt_properties_get_double( properties, "cycle" ); - - // Allow a geometry repeat cycle - if ( cycle >= 1 ) - length = cycle; - else if ( cycle > 0 ) - length *= cycle; - mlt_geometry_parse( crop, mlt_properties_get( properties, "crop" ), length, result->sw, result->sh ); - mlt_properties_set_data( properties, "crop_geometry", crop, 0, (mlt_destructor)mlt_geometry_close, NULL ); - } + mlt_position length = mlt_transition_get_length( self ); + double cycle = mlt_properties_get_double( properties, "cycle" ); + + // Allow a geometry repeat cycle + if ( cycle >= 1 ) + length = cycle; + else if ( cycle > 0 ) + length *= cycle; + + mlt_rect crop = mlt_properties_anim_get_rect(properties, "crop", position, length); // Repeat processing - int length = mlt_geometry_get_length( crop ); + mlt_animation animation = mlt_properties_get_animation(properties, "crop"); + int anim_length = mlt_animation_get_length(animation); int mirror_off = mlt_properties_get_int( properties, "mirror_off" ); int repeat_off = mlt_properties_get_int( properties, "repeat_off" ); - if ( !repeat_off && position >= length && length != 0 ) + if ( !repeat_off && position >= anim_length && anim_length != 0 ) { - int section = position / length; - position -= section * length; + int section = position / anim_length; + position -= section * anim_length; if ( !mirror_off && section % 2 == 1 ) - position = length - position; + position = anim_length - position; } // Compute the pan - struct mlt_geometry_item_s crop_item; - mlt_geometry_fetch( crop, &crop_item, position ); - result->x_src = rint( crop_item.x ); - result->y_src = rint( crop_item.y ); + crop = mlt_properties_anim_get_rect(properties, "crop", position, length); + if (mlt_properties_get(properties, "crop") && strchr(mlt_properties_get(properties, "crop"), '%')) { + mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( self ) ); + crop.x *= profile->width; + crop.y *= profile->height; + } + result->x_src = rint( crop.x ); + result->y_src = rint( crop.y ); } } -static mlt_geometry composite_calculate( mlt_transition self, struct geometry_s *result, mlt_frame a_frame, double position ) +static void composite_calculate( mlt_transition self, struct geometry_s *result, double position ) { // Get the properties from the transition mlt_properties properties = MLT_TRANSITION_PROPERTIES( self ); - // Get the properties from the frame - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - - // Structures for geometry - mlt_geometry start = mlt_properties_get_data( properties, "geometries", NULL ); - // Obtain the normalised width and height from the a_frame mlt_profile profile = mlt_service_profile( MLT_TRANSITION_SERVICE( self ) ); int normalised_width = profile->width; int normalised_height = profile->height; - char *name = mlt_properties_get( properties, "_unique_id" ); - char key[ 256 ]; - - snprintf( key, sizeof(key), "composite %s.in", name ); - if ( mlt_properties_get( a_props, key ) ) - { - sscanf( mlt_properties_get( a_props, key ), "%f %f %f %f %f %d %d", &result->item.x, &result->item.y, &result->item.w, &result->item.h, &result->item.mix, &result->nw, &result->nh ); - } - else - { - // Now parse the geometries - if ( start == NULL ) - { - // Parse the transitions properties - start = transition_parse_keys( self, normalised_width, normalised_height ); - - // Assign to properties to ensure we get destroyed - mlt_properties_set_data( properties, "geometries", start, 0, ( mlt_destructor )mlt_geometry_close, NULL ); - } - else - { - mlt_position length = mlt_transition_get_length( self ); - double cycle = mlt_properties_get_double( properties, "cycle" ); - if ( cycle > 1 ) - length = cycle; - else if ( cycle > 0 ) - length *= cycle; - mlt_geometry_refresh( start, mlt_properties_get( properties, "geometry" ), length, normalised_width, normalised_height ); - } - - // Do the calculation - geometry_calculate( self, result, position ); - - // Assign normalised info - result->nw = normalised_width; - result->nh = normalised_height; - } - - // Now parse the alignment - result->halign = alignment_parse( mlt_properties_get( properties, "halign" ) ); - result->valign = alignment_parse( mlt_properties_get( properties, "valign" ) ); - - crop_calculate( self, properties, result, position ); - - return start; -} - -mlt_frame composite_copy_region( mlt_transition self, mlt_frame a_frame, mlt_position frame_position ) -{ - // Create a frame to return - mlt_frame b_frame = mlt_frame_init( MLT_TRANSITION_SERVICE( self ) ); - b_frame->convert_image = a_frame->convert_image; - - // Get the properties of the a frame - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - - // Get the properties of the b frame - mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); - - // Get the position - int position = position_calculate( self, frame_position ); - - // Get the unique id of the transition - char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( self ), "_unique_id" ); - char key[ 256 ]; - - // Destination image - uint8_t *dest = NULL; - - // Get the image and dimensions - uint8_t *image = NULL; - int width = mlt_properties_get_int( a_props, "width" ); - int height = mlt_properties_get_int( a_props, "height" ); - mlt_image_format format = mlt_image_yuv422; - - mlt_frame_get_image( a_frame, &image, &format, &width, &height, 0 ); - if ( !image ) - return b_frame; - - // Pointers for copy operation - uint8_t *p; - - // Coordinates - int w = 0; - int h = 0; - int x = 0; - int y = 0; - - int ss = 0; - int ds = 0; - - // Will need to know region to copy - struct geometry_s result; - - // Calculate the region now - composite_calculate( self, &result, a_frame, position ); - - // Need to scale down to actual dimensions - x = rint( result.item.x * width / result.nw ); - y = rint( result.item.y * height / result.nh ); - w = rint( result.item.w * width / result.nw ); - h = rint( result.item.h * height / result.nh ); - - if ( x % 2 ) - { - x --; - w ++; - } - - // Store the key - snprintf( key, sizeof(key), "composite %s.in=%d %d %d %d %f %d %d", name, x, y, w, h, result.item.mix, width, height ); - mlt_properties_parse( a_props, key ); - snprintf( key, sizeof(key), "composite %s.out=%d %d %d %d %f %d %d", name, x, y, w, h, result.item.mix, width, height ); - mlt_properties_parse( a_props, key ); - - ds = w * 2; - ss = width * 2; + // Now parse the geometries + mlt_position length = mlt_transition_get_length( self ); + double cycle = mlt_properties_get_double( properties, "cycle" ); - // Now we need to create a new destination image - dest = mlt_pool_alloc( w * h * 2 ); + // Allow a geometry repeat cycle + if ( cycle >= 1 ) + length = cycle; + else if ( cycle > 0 ) + length *= cycle; - // Assign to the new frame - mlt_frame_set_image( b_frame, dest, w * h * 2, mlt_pool_release ); - mlt_properties_set_int( b_props, "width", w ); - mlt_properties_set_int( b_props, "height", h ); - mlt_properties_set_int( b_props, "format", format ); + result->item = mlt_properties_anim_get_rect(properties, "geometry", position, length); - if ( y < 0 ) + // Repeat processing + mlt_animation animation = mlt_properties_get_animation(properties, "geometry"); + int anim_length = mlt_animation_get_length(animation); + int mirror_off = mlt_properties_get_int( properties, "mirror_off" ); + int repeat_off = mlt_properties_get_int( properties, "repeat_off" ); + if ( !repeat_off && position >= anim_length && anim_length != 0 ) { - dest += ( ds * -y ); - h += y; - y = 0; + int section = position / anim_length; + position -= section * anim_length; + if ( !mirror_off && section % 2 == 1 ) + position = anim_length - position; } + result->item = mlt_properties_anim_get_rect(properties, "geometry", position, length); - if ( y + h > height ) - h -= ( y + h - height ); - - if ( x < 0 ) - { - dest += -x * 2; - w += x; - x = 0; + if (mlt_properties_get(properties, "geometry") && strchr(mlt_properties_get(properties, "geometry"), '%')) { + result->item.x *= normalised_width; + result->item.y *= normalised_height; + result->item.w *= normalised_width; + result->item.h *= normalised_height; } + result->item.o = 100.0 * (result->item.o == DBL_MIN ? 1.0 : MIN(result->item.o, 1.0)); - if ( w > 0 && h > 0 ) - { - // Copy the region of the image - p = image + y * ss + x * 2; + // Assign normalised info + result->nw = normalised_width; + result->nh = normalised_height; - while ( h -- ) - { - memcpy( dest, p, w * 2 ); - dest += ds; - p += ss; - } - } - - // Assign this position to the b frame - mlt_frame_set_position( b_frame, frame_position ); - mlt_properties_set_int( b_props, "distort", 1 ); + // Now parse the alignment + result->halign = alignment_parse( mlt_properties_get( properties, "halign" ) ); + result->valign = alignment_parse( mlt_properties_get( properties, "valign" ) ); - // Return the frame - return b_frame; + crop_calculate( self, result, position ); } /** Get the image. @@ -1145,7 +924,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // Do the calculation // NB: Locks needed here since the properties are being modified mlt_service_lock( MLT_TRANSITION_SERVICE( self ) ); - composite_calculate( self, &result, a_frame, position ); + composite_calculate( self, &result, position ); mlt_service_unlock( MLT_TRANSITION_SERVICE( self ) ); // Manual option to deinterlace @@ -1157,7 +936,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // TODO: Dangerous/temporary optimisation - if nothing to do, then do nothing if ( mlt_properties_get_int( properties, "no_alpha" ) && - result.item.x == 0 && result.item.y == 0 && result.item.w == *width && result.item.h == *height && result.item.mix == 100 ) + result.item.x == 0 && result.item.y == 0 && result.item.w == *width && result.item.h == *height && result.item.o == 100 ) { mlt_frame_get_image( b_frame, image, format, width, height, 1 ); if ( !mlt_frame_is_test_card( a_frame ) ) @@ -1178,7 +957,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f alpha_a = mlt_frame_get_alpha( a_frame ); // Optimisation - no compositing required - if ( result.item.mix == 0 || ( result.item.w == 0 && result.item.h == 0 ) ) + if ( result.item.o == 0 || ( result.item.w == 0 && result.item.h == 0 ) ) return 0; // Need to keep the width/height of the a_frame on the b_frame for titling @@ -1251,7 +1030,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // Do the calculation if we need to // NB: Locks needed here since the properties are being modified mlt_service_lock( MLT_TRANSITION_SERVICE( self ) ); - composite_calculate( self, &result, a_frame, field_position ); + composite_calculate( self, &result, field_position ); mlt_service_unlock( MLT_TRANSITION_SERVICE( self ) ); if ( mlt_properties_get_int( properties, "titles" ) ) @@ -1344,7 +1123,7 @@ mlt_transition transition_composite_init( mlt_profile profile, mlt_service_type self->process = composite_process; // Default starting motion and zoom - mlt_properties_set( properties, "start", arg != NULL ? arg : "0/0:100%x100%" ); + mlt_properties_set( properties, "geometry", arg != NULL ? arg : "0/0:100%x100%" ); // Default factory mlt_properties_set( properties, "factory", mlt_environment( "MLT_PRODUCER" ) ); diff --git a/src/modules/core/transition_composite.h b/src/modules/core/transition_composite.h index e13be2331..d86a1b08b 100644 --- a/src/modules/core/transition_composite.h +++ b/src/modules/core/transition_composite.h @@ -1,6 +1,6 @@ /* * transition_composite.h -- compose one image over another using alpha channel - * Copyright (C) 2003-2014 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -24,8 +24,6 @@ extern mlt_transition transition_composite_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -// Courtesy functionality - allows regionalised filtering -extern mlt_frame composite_copy_region( mlt_transition, mlt_frame, mlt_position ); extern void composite_line_yuv( uint8_t *dest, uint8_t *src, int width, uint8_t *alpha_b, uint8_t *alpha_a, int weight, uint16_t *luma, int soft, uint32_t step ); diff --git a/src/modules/core/transition_composite.yml b/src/modules/core/transition_composite.yml index 7affb3974..622e349aa 100644 --- a/src/modules/core/transition_composite.yml +++ b/src/modules/core/transition_composite.yml @@ -2,7 +2,7 @@ schema_version: 0.3 type: transition identifier: composite title: Composite -version: 1 +version: 2 copyright: Meltytech, LLC creator: Dan Dennedy license: LGPLv2.1 @@ -32,10 +32,8 @@ parameters: - identifier: geometry title: Geometry - type: geometry - description: > - Key frame specification. This is a ";" delimited form of the deprecated - start, key[n], end properties. + type: rect + description: A possibly keyframed rectangle mutable: yes - identifier: progressive @@ -126,29 +124,6 @@ parameters: readonly: no mutable: yes - - identifier: start - title: Start geometry - description: > - (deprecated) A geometry specification as X/Y:WxH[!][:mix] - - X, Y, W, H are assumed to pixel units unless they have the suffix '%'. - - '!' is a shortcut to specify distort. - - Mix is always a 2 digit percentage, defaults to 100. - type: geometry - default: "0%/0%:100%x100%" - readonly: no - mutable: yes - - - identifier: end - title: End geometry - description: > - (deprecated) X/Y:WxH[:mix] - The end geometry specification (see "start"). - type: geometry - readonly: no - mutable: yes - - identifier: sliced_composite title: Use sliced compositing description: > @@ -159,16 +134,6 @@ parameters: mutable: yes widget: checkbox - - identifier: key[F] - title: Key frame geometry - description: > - (deprecated) X/Y:WxH[:mix] - set a key frame for geometry between the in - and out. F is a frame number and can be negative to make it relative to - the out point. - type: geometry - readonly: no - mutable: yes - - identifier: fill title: Fill geometry description: > diff --git a/src/modules/gdk/producer_pango.c b/src/modules/gdk/producer_pango.c index c91b7e713..0cead7fdd 100644 --- a/src/modules/gdk/producer_pango.c +++ b/src/modules/gdk/producer_pango.c @@ -1,6 +1,6 @@ /* * producer_pango.c -- a pango-based titler - * Copyright (C) 2003-2020 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,9 +19,9 @@ #include #include -#include #include #include +#include #include #include #include @@ -227,11 +227,14 @@ mlt_producer producer_pango_init( const char *filename ) int i = 0; mlt_position out_point = 0; mlt_properties contents = mlt_properties_load( filename ); - mlt_geometry key_frames = mlt_geometry_init( ); - struct mlt_geometry_item_s item; + + mlt_animation key_frames = mlt_animation_new(); + struct mlt_animation_item_s item; + item.property = NULL; + item.keyframe_type = mlt_keyframe_discrete; mlt_properties_set_string( properties, "resource", filename ); mlt_properties_set_data( properties, "contents", contents, 0, ( mlt_destructor )mlt_properties_close, NULL ); - mlt_properties_set_data( properties, "key_frames", key_frames, 0, ( mlt_destructor )mlt_geometry_close, NULL ); + mlt_properties_set_data( properties, "key_frames", key_frames, 0, ( mlt_destructor )mlt_animation_close, NULL ); // Make sure we have at least one entry if ( mlt_properties_get( contents, "0" ) == NULL ) @@ -244,10 +247,10 @@ mlt_producer producer_pango_init( const char *filename ) while ( value != NULL && strchr( value, '~' ) ) ( *strchr( value, '~' ) ) = '\n'; item.frame = atoi( name ); - mlt_geometry_insert( key_frames, &item ); + mlt_animation_insert( key_frames, &item ); out_point = MAX( out_point, item.frame ); } - mlt_geometry_interpolate( key_frames ); + mlt_animation_interpolate( key_frames ); mlt_properties_set_position( properties, "length", out_point + 1 ); mlt_properties_set_position( properties, "out", out_point ); } @@ -426,12 +429,13 @@ static void refresh_image( producer_pango self, mlt_frame frame, int width, int { // Check for file support mlt_properties contents = mlt_properties_get_data( producer_props, "contents", NULL ); - mlt_geometry key_frames = mlt_properties_get_data( producer_props, "key_frames", NULL ); - struct mlt_geometry_item_s item; + mlt_animation key_frames = mlt_properties_get_data( producer_props, "key_frames", NULL ); if ( contents != NULL ) { char temp[ 20 ]; - mlt_geometry_prev_key( key_frames, &item, mlt_frame_original_position( frame ) ); + struct mlt_animation_item_s item; + item.property = NULL; + mlt_animation_prev_key( key_frames, &item, mlt_frame_original_position( frame ) ); sprintf( temp, "%d", item.frame ); markup = mlt_properties_get( contents, temp ); } diff --git a/src/modules/plus/transition_affine.c b/src/modules/plus/transition_affine.c index 1b4c28a43..0fc24baf5 100644 --- a/src/modules/plus/transition_affine.c +++ b/src/modules/plus/transition_affine.c @@ -78,83 +78,6 @@ static double anim_get_angle(mlt_properties properties, const char* name, mlt_po return result; } -/** Calculate real geometry. -*/ - -static void geometry_calculate( mlt_transition transition, const char *store, struct mlt_geometry_item_s *output, double position ) -{ - mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition ); - mlt_geometry geometry = mlt_properties_get_data( properties, store, NULL ); - int mirror_off = mlt_properties_get_int( properties, "mirror_off" ); - int repeat_off = mlt_properties_get_int( properties, "repeat_off" ); - int length = mlt_geometry_get_length( geometry ); - - // Allow wrapping - if ( !repeat_off && position >= length && length != 0 ) - { - int section = position / length; - position -= section * length; - if ( !mirror_off && section % 2 == 1 ) - position = length - position; - } - - // Fetch the key for the position - mlt_geometry_fetch( geometry, output, position ); -} - - -static mlt_geometry transition_parse_keys( mlt_transition transition, const char *name, const char *store, int normalised_width, int normalised_height ) -{ - // Get the properties of the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition ); - - // Try to fetch it first - mlt_geometry geometry = mlt_properties_get_data( properties, store, NULL ); - - // Determine length and obtain cycle - mlt_position length = mlt_transition_get_length( transition ); - double cycle = mlt_properties_get_double( properties, "cycle" ); - - // Allow a geometry repeat cycle - if ( cycle >= 1 ) - length = cycle; - else if ( cycle > 0 ) - length *= cycle; - - if ( geometry == NULL ) - { - // Get the new style geometry string - char *property = mlt_properties_get( properties, name ); - - // Create an empty geometries object - geometry = mlt_geometry_init( ); - - // Parse the geometry if we have one - mlt_geometry_parse( geometry, property, length, normalised_width, normalised_height ); - - // Store it - mlt_properties_set_data( properties, store, geometry, 0, ( mlt_destructor )mlt_geometry_close, NULL ); - } - else - { - // Check for updates and refresh if necessary - mlt_geometry_refresh( geometry, mlt_properties_get( properties, name ), length, normalised_width, normalised_height ); - } - - return geometry; -} - -static mlt_geometry composite_calculate( mlt_transition transition, struct mlt_geometry_item_s *result, int nw, int nh, double position ) -{ - // Structures for geometry - mlt_geometry start = transition_parse_keys( transition, "geometry", "geometries", nw, nh ); - - // Do the calculation - geometry_calculate( transition, "geometries", result, position ); - - return start; -} - typedef struct { double matrix[3][3]; @@ -497,18 +420,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f mlt_service_lock( MLT_TRANSITION_SERVICE( transition ) ); - if (mlt_properties_get(properties, "geometry")) - { - // Structures for geometry - struct mlt_geometry_item_s geometry; - composite_calculate( transition, &geometry, normalised_width, normalised_height, ( double )position ); - result.x = geometry.x; - result.y = geometry.y; - result.w = geometry.w; - result.h = geometry.h; - result.o = geometry.mix / 100.0f; - } - else if (mlt_properties_get(properties, "rect")) + if (mlt_properties_get(properties, "rect")) { // Determine length and obtain cycle double cycle = mlt_properties_get_double( properties, "cycle" ); diff --git a/src/modules/plus/transition_affine.yml b/src/modules/plus/transition_affine.yml index aa3d2ecf5..2cf4109f6 100644 --- a/src/modules/plus/transition_affine.yml +++ b/src/modules/plus/transition_affine.yml @@ -1,8 +1,8 @@ -schema_version: 0.2 +schema_version: 7.0 type: transition identifier: affine title: Transform -version: 5 +version: 6 copyright: Meltytech, LLC creator: Charles Yates contributor: @@ -12,16 +12,11 @@ language: en tags: - Video parameters: - - identifier: geometry - title: Rectangle - type: geometry - description: This property is deprecated. Use rect instead. - - identifier: distort title: Ignore aspect ratio description: > Determines whether the image aspect ratio will be distorted while scaling - to completely fill the geometry rectangle. + to completely fill the rectangle. type: boolean default: 0 mutable: yes @@ -72,10 +67,7 @@ parameters: - identifier: keyed title: Key-framed - description: > - Whether rotate, shear, and offset are key-framed or not. - This ("key-framed") refers to the legacy, deprecated, mlt_geometry-based - property evaluation. Most of the properties support mlt_animation now. + description: Whether rotate, shear, and offset are key-framed or not. type: boolean default: 0 mutable: yes @@ -217,7 +209,7 @@ parameters: - identifier: scale title: Scale description: > - Whether to automatic upscale B frame image to ensure the geometry area + Whether to automatic upscale B frame image to ensure the rectangle is filled. type: boolean default: 0 @@ -261,12 +253,12 @@ parameters: mutable: yes - identifier: fill - title: Fill geometry + title: Fill rectangle description: > - Determines whether the image will be scaled up to fill the geometry. - Otherwise, if the B frame image fits within the geometry, it will not - be scaled. If 0, and the B frame image exceeds the geometry, then it is - scaled down to fit within the geometry. + Determines whether the image will be scaled up to fill the rectangle. + Otherwise, if the B frame image fits within the rectangle, it will not + be scaled. If 0, and the B frame image exceeds the rectangle, then it is + scaled down to fit within the rectangle. type: boolean default: 1 mutable: yes @@ -275,7 +267,7 @@ parameters: - identifier: halign title: Horizontal alignment description: > - Set the horizontal alignment within the geometry rectangle. + Set the horizontal alignment within the rectangle. type: string default: left values: @@ -288,7 +280,7 @@ parameters: - identifier: valign title: Vertical alignment description: > - Set the vertical alignment within the geometry rectangle. + Set the vertical alignment within the rectangle. type: string default: top values: @@ -309,10 +301,9 @@ parameters: - identifier: rect title: Rectangle description: > - This replaces the geometry property and specifies a specifies a rectangle - for the size and position of the image. The format of this is + This specifies the size and position of the image. The format of this is "X/Y:WxH[:opacity]" and can be animated with key frames. - Unlike the geometry property, if you use percentages you must use them for + If you use percentages you must use them for every field in the above format. For example, you cannot mix and match usage of absolute coordinates and percentages for size and opacity. type: rect diff --git a/src/swig/mlt.i b/src/swig/mlt.i index ca8e85a12..8b5046425 100644 --- a/src/swig/mlt.i +++ b/src/swig/mlt.i @@ -91,7 +91,6 @@ void mlt_log_set_level( int ); %include %include %include -%include %include %include %include From 34a4b940b38f6b8fbd53dc0be78fd0b757ac52bf Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Tue, 16 Mar 2021 20:18:39 -0700 Subject: [PATCH 077/122] add --without-jack to jackrack module This makes it build for LADSPA producers and filters only and no JACK services. --- src/modules/jackrack/Makefile | 12 +++++---- src/modules/jackrack/configure | 46 ++++++++++++++++++++++------------ src/modules/jackrack/factory.c | 8 +++++- src/modules/jackrack/plugin.c | 22 +++++++++++++--- src/modules/jackrack/plugin.h | 6 ++++- src/modules/jackrack/process.c | 36 ++++++++++++++++++++++---- src/modules/jackrack/process.h | 11 +++++++- 7 files changed, 108 insertions(+), 33 deletions(-) diff --git a/src/modules/jackrack/Makefile b/src/modules/jackrack/Makefile index c29739e6a..dc020e971 100644 --- a/src/modules/jackrack/Makefile +++ b/src/modules/jackrack/Makefile @@ -15,18 +15,20 @@ GPL_OBJS = jack_rack.o \ plugin_settings.o \ process.o \ producer_ladspa.o \ - filter_jackrack.o \ filter_ladspa.o -OBJS = factory.o \ - consumer_jack.o +OBJS = factory.o -CFLAGS += $(shell pkg-config --cflags jack) +ifdef WITH_JACK +GPL_OBJS += filter_jackrack.o +OBJS += consumer_jack.o +CFLAGS += -DWITH_JACK $(shell pkg-config --cflags jack) LDFLAGS += $(shell pkg-config --libs jack) +endif ifdef GPL OBJS += $(GPL_OBJS) -CFLAGS += -DGPL +CFLAGS += -DGPL $(LADSPA_PREFIX) CFLAGS += $(shell pkg-config --cflags libxml-2.0) CFLAGS += $(shell pkg-config $(PKGCONFIG_PREFIX) --cflags glib-2.0) diff --git a/src/modules/jackrack/configure b/src/modules/jackrack/configure index 9d18d0b90..21998cc2c 100755 --- a/src/modules/jackrack/configure +++ b/src/modules/jackrack/configure @@ -6,38 +6,52 @@ then JACK Rack options: --gdk-prefix=path - Override the gdk prefix for pkg-config + --ladspa-prefix=path - Overrride the LADSPA path prefix + --without-jack - Build only the LADSPA producer and filter EOF else - pkg-config jack - disable_jack=$? - echo > config.mak + export without_jack=false + + for i in "$@" + do + case $i in + --gdk-prefix=* ) pkgconfig_prefix="${i#--gdk-prefix=}" ;; + --ladspa-prefix=*) ladspa_prefix="${i#--ladspa-prefix=}" ;; + --without-jack ) without_jack=true ;; + esac + done + + if [ "$without_jack" = "false" ]; then + pkg-config jack + disable_jack=$? + [ "$disable_jack" != "1" ] && "WITH_JACK=1" >> config.mak + fi + if [ "$gpl" = "true" ] then pkg-config libxml-2.0 > /dev/null 2>&1 disable_xml2=$? - ladspa_prefix=`which listplugins 2> /dev/null` - if [ "$ladspa_prefix" != "" ] - then - ladspa_prefix=`dirname "$ladspa_prefix"` - ladspa_prefix=`dirname "$ladspa_prefix"` + if [ "$ladspa_prefix" = "" ]; then + ladspa_prefix=`which listplugins 2> /dev/null` + if [ "$ladspa_prefix" != "" ]; then + ladspa_prefix=`dirname "$ladspa_prefix"` + ladspa_prefix=`dirname "$ladspa_prefix"` + fi else + echo "LADSPA_PREFIX=\"-I$ladspa_prefix/include\"" >> config.mak + fi + if [ "$ladspa_prefix" = "" ]; then ladspa_prefix=`pkg-config --variable=prefix jack` fi disable_ladspa=`[ -f "$ladspa_prefix/include/ladspa.h" ] && echo 0 || echo 1` - echo GPL=1 > config.mak - - for i in "$@" - do - case $i in - --gdk-prefix=* ) pkgconfig_prefix="${i#--gdk-prefix=}" ;; - esac - done + echo GPL=1 >> config.mak + [ "$pkgconfig_prefix" != "" ] && echo "PKGCONFIG_PREFIX=--define-variable=prefix=\"$pkgconfig_prefix\"" >> config.mak fi diff --git a/src/modules/jackrack/factory.c b/src/modules/jackrack/factory.c index e7338dfe6..e5a2824c9 100644 --- a/src/modules/jackrack/factory.c +++ b/src/modules/jackrack/factory.c @@ -1,6 +1,6 @@ /* * factory.c -- the factory method interfaces - * Copyright (C) 2003-2019 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * 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 @@ -32,7 +32,9 @@ extern mlt_consumer consumer_jack_init( mlt_profile profile, mlt_service_type ty #include #include "plugin_mgr.h" +#ifdef WITH_JACK extern mlt_filter filter_jackrack_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); +#endif extern mlt_filter filter_ladspa_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_producer producer_ladspa_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); @@ -206,12 +208,16 @@ MLT_REPOSITORY } mlt_factory_register_for_clean_up( g_jackrack_plugin_mgr, (mlt_destructor) plugin_mgr_destroy ); +# ifdef WITH_JACK MLT_REGISTER( mlt_service_filter_type, "jack", filter_jackrack_init ); MLT_REGISTER( mlt_service_filter_type, "jackrack", filter_jackrack_init ); MLT_REGISTER_METADATA( mlt_service_filter_type, "jackrack", metadata, "filter_jackrack.yml" ); +# endif MLT_REGISTER( mlt_service_filter_type, "ladspa", filter_ladspa_init ); MLT_REGISTER_METADATA( mlt_service_filter_type, "ladspa", metadata, "filter_ladspa.yml" ); #endif +#ifdef WITH_JACK MLT_REGISTER( mlt_service_consumer_type, "jack", consumer_jack_init ); MLT_REGISTER_METADATA( mlt_service_consumer_type, "jack", metadata, "consumer_jack.yml" ); +#endif } diff --git a/src/modules/jackrack/plugin.c b/src/modules/jackrack/plugin.c index 397b7a55b..ffaea1241 100644 --- a/src/modules/jackrack/plugin.c +++ b/src/modules/jackrack/plugin.c @@ -5,7 +5,7 @@ * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) * * Modification for MLT: - * Copyright (C) 2004-2014 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * 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 @@ -37,8 +37,7 @@ #define CONTROL_FIFO_SIZE 128 - - +#ifdef WITH_JACK /* swap over the jack ports in two plugins */ static void plugin_swap_aux_ports (plugin_t * plugin, plugin_t * other) @@ -53,6 +52,7 @@ plugin_swap_aux_ports (plugin_t * plugin, plugin_t * other) plugin->holders[copy].aux_ports = aux_ports_tmp; } } +#endif /** connect up the ladspa instance's input buffers to the previous plugin's audio memory. make sure to check that plugin->prev @@ -141,6 +141,7 @@ process_remove_plugin (process_info_t * procinfo, plugin_t *plugin) else procinfo->chain_end = plugin->prev; +#ifdef WITH_JACK /* sort out the aux ports */ if (procinfo->jack_client && plugin->desc->aux_channels > 0) { @@ -150,6 +151,7 @@ process_remove_plugin (process_info_t * procinfo, plugin_t *plugin) if (other->desc->id == plugin->desc->id) plugin_swap_aux_ports (plugin, other); } +#endif return plugin; } @@ -230,7 +232,8 @@ process_move_plugin (process_info_t * procinfo, plugin_t *plugin, gint up) else procinfo->chain_end = plugin; } - + +#ifdef WITH_JACK if (procinfo->jack_client && plugin->desc->aux_channels > 0) { plugin_t * other; @@ -240,6 +243,7 @@ process_move_plugin (process_info_t * procinfo, plugin_t *plugin, gint up) if (other->desc->id == plugin->desc->id) plugin_swap_aux_ports (plugin, other); } +#endif } /** exchange an existing plugin for a newly created one */ @@ -260,6 +264,7 @@ process_change_plugin (process_info_t * procinfo, else procinfo->chain_end = new_plugin; +#ifdef WITH_JACK /* sort out the aux ports */ if (procinfo->jack_client && plugin->desc->aux_channels > 0) { @@ -269,6 +274,7 @@ process_change_plugin (process_info_t * procinfo, if (other->desc->id == plugin->desc->id) plugin_swap_aux_ports (plugin, other); } +#endif return plugin; } @@ -364,6 +370,8 @@ plugin_instantiate (const LADSPA_Descriptor * descriptor, return 0; } +#ifdef WITH_JACK + static void plugin_create_aux_ports (plugin_t * plugin, guint copy, jack_rack_t * jack_rack) { @@ -430,6 +438,8 @@ plugin_create_aux_ports (plugin_t * plugin, guint copy, jack_rack_t * jack_rack) g_free (plugin_name); } +#endif + static void plugin_init_holder (plugin_t * plugin, guint copy, @@ -481,8 +491,10 @@ plugin_init_holder (plugin_t * plugin, connect_port (instance, desc->status_port_indicies[i], holder->status_memory + i); } +#ifdef WITH_JACK if (jack_rack->procinfo->jack_client && plugin->desc->aux_channels > 0) plugin_create_aux_ports (plugin, copy, jack_rack); +#endif if (plugin->descriptor->activate) plugin->descriptor->activate (instance); @@ -581,6 +593,7 @@ plugin_destroy (plugin_t * plugin) g_free (plugin->holders[i].status_memory); } +#ifdef WITH_JACK /* aux ports */ if (plugin->jack_rack->procinfo->jack_client && plugin->desc->aux_channels > 0) { @@ -595,6 +608,7 @@ plugin_destroy (plugin_t * plugin) g_free (plugin->holders[i].aux_ports); } +#endif } g_free (plugin->holders); diff --git a/src/modules/jackrack/plugin.h b/src/modules/jackrack/plugin.h index 672608fb9..6e469c4a0 100644 --- a/src/modules/jackrack/plugin.h +++ b/src/modules/jackrack/plugin.h @@ -5,7 +5,7 @@ * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) * * Modification for MLT: - * Copyright (C) 2004-2014 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * 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 @@ -28,7 +28,9 @@ #include #include #include +#ifdef WITH_JACK #include +#endif #include "process.h" #include "plugin_desc.h" @@ -43,7 +45,9 @@ struct _ladspa_holder LADSPA_Data * control_memory; LADSPA_Data * status_memory; +#ifdef WITH_JACK jack_port_t ** aux_ports; +#endif }; struct _plugin diff --git a/src/modules/jackrack/process.c b/src/modules/jackrack/process.c index 574e2e6c5..fc0280deb 100644 --- a/src/modules/jackrack/process.c +++ b/src/modules/jackrack/process.c @@ -5,7 +5,7 @@ * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) * * Modification for MLT: - * Copyright (C) 2004-2014 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * 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 @@ -23,7 +23,9 @@ */ #include +#ifdef WITH_JACK #include +#endif #include #include #include @@ -52,6 +54,8 @@ extern pthread_mutex_t g_activate_mutex; jack_nframes_t sample_rate; jack_nframes_t buffer_size; +#ifdef WITH_JACK + static void jack_shutdown_cb (void * data) { @@ -60,6 +64,8 @@ jack_shutdown_cb (void * data) procinfo->quit = TRUE; } +#endif + /** process messages for plugins' control ports */ void process_control_port_messages (process_info_t * procinfo) { plugin_t * plugin; @@ -88,7 +94,9 @@ void process_control_port_messages (process_info_t * procinfo) { } } -int get_jack_buffers (process_info_t * procinfo, jack_nframes_t frames) { +#ifdef WITH_JACK + +static int get_jack_buffers (process_info_t * procinfo, jack_nframes_t frames) { unsigned long channel; for (channel = 0; channel < procinfo->channels; channel++) @@ -111,6 +119,8 @@ int get_jack_buffers (process_info_t * procinfo, jack_nframes_t frames) { return 0; } +#endif + plugin_t * get_first_enabled_plugin (process_info_t * procinfo) { @@ -164,6 +174,7 @@ connect_chain (process_info_t * procinfo, jack_nframes_t frames) { if (plugin->desc->aux_channels > 0 && plugin->enabled) { +#ifdef WITH_JACK if (procinfo->jack_client) { for (copy = 0; copy < plugin->copies; copy++) @@ -174,6 +185,7 @@ connect_chain (process_info_t * procinfo, jack_nframes_t frames) jack_port_get_buffer (plugin->holders[copy].aux_ports[channel], frames)); } else +#endif { for (copy = 0; copy < frames; copy++) procinfo->silent_buffer[copy] = 0.0; @@ -218,6 +230,7 @@ process_chain (process_info_t * procinfo, jack_nframes_t frames) unsigned long channel; unsigned long i; +#ifdef WITH_JACK if (procinfo->jack_client) { LADSPA_Data zero_signal[frames]; @@ -237,6 +250,7 @@ process_chain (process_info_t * procinfo, jack_nframes_t frames) memcpy (jack_port_get_buffer (plugin->holders[copy].aux_ports[channel], frames), zero_signal, sizeof (LADSPA_Data) * frames); } +#endif first_enabled = get_first_enabled_plugin (procinfo); @@ -337,6 +351,8 @@ int process_ladspa (process_info_t * procinfo, jack_nframes_t frames, return 0; } +#ifdef WITH_JACK + int process_jack (jack_nframes_t frames, void * data) { int err; process_info_t * procinfo; @@ -442,7 +458,7 @@ process_info_connect_port (process_info_t * procinfo, free (jack_ports); } -int +static int process_info_set_port_count (process_info_t * procinfo, unsigned long port_count, gboolean connect_inputs, gboolean connect_outputs) { @@ -509,11 +525,15 @@ process_info_set_port_count (process_info_t * procinfo, return 0; } +#endif + void process_info_set_channels (process_info_t * procinfo, unsigned long channels, gboolean connect_inputs, gboolean connect_outputs) { +#ifdef WITH_JACK process_info_set_port_count (procinfo, channels, connect_inputs, connect_outputs); +#endif procinfo->channels = channels; } @@ -529,10 +549,12 @@ process_info_new (const char * client_name, unsigned long rack_channels, procinfo->chain = NULL; procinfo->chain_end = NULL; +#ifdef WITH_JACK procinfo->jack_client = NULL; procinfo->port_count = 0; procinfo->jack_input_ports = NULL; procinfo->jack_output_ports = NULL; +#endif procinfo->channels = rack_channels; procinfo->quit = FALSE; @@ -562,7 +584,8 @@ process_info_new (const char * client_name, unsigned long rack_channels, else if (isupper (jack_client_name[err])) jack_client_name[err] = tolower (jack_client_name[err]); } - + +#ifdef WITH_JACK err = process_info_connect_jack (procinfo); if (err) { @@ -584,22 +607,25 @@ process_info_new (const char * client_name, unsigned long rack_channels, err = process_info_set_port_count (procinfo, rack_channels, connect_inputs, connect_outputs); if (err) return NULL; +#endif return procinfo; } void process_info_destroy (process_info_t * procinfo) { +#ifdef WITH_JACK if (procinfo->jack_client) { jack_deactivate (procinfo->jack_client); jack_client_close (procinfo->jack_client); } - g_free (procinfo->silent_buffer); g_free (procinfo->jack_input_ports); g_free (procinfo->jack_output_ports); +#endif g_free (procinfo->jack_input_buffers); g_free (procinfo->jack_output_buffers); + g_free (procinfo->silent_buffer); g_free (procinfo); } diff --git a/src/modules/jackrack/process.h b/src/modules/jackrack/process.h index 807acb5e2..1d4cb589d 100644 --- a/src/modules/jackrack/process.h +++ b/src/modules/jackrack/process.h @@ -5,7 +5,7 @@ * Copyright (C) Robert Ham 2002, 2003 (node@users.sourceforge.net) * * Modification for MLT: - * Copyright (C) 2004-2014 Meltytech, LLC + * Copyright (C) 2004-2021 Meltytech, LLC * * 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 @@ -26,7 +26,9 @@ #define __JLH_PROCESS_H__ #include +#ifdef WITH_JACK #include +#endif #include #include "lock_free_fifo.h" @@ -41,10 +43,12 @@ struct _process_info { struct _plugin * chain; struct _plugin * chain_end; +#ifdef WITH_JACK jack_client_t * jack_client; unsigned long port_count; jack_port_t ** jack_input_ports; jack_port_t ** jack_output_ports; +#endif unsigned long channels; LADSPA_Data ** jack_input_buffers; @@ -55,6 +59,9 @@ struct _process_info { int quit; }; +#ifndef WITH_JACK +typedef guint32 jack_nframes_t; +#endif extern jack_nframes_t sample_rate; extern jack_nframes_t buffer_size; @@ -68,7 +75,9 @@ void process_info_set_channels (process_info_t * procinfo, int process_ladspa (process_info_t * procinfo, jack_nframes_t frames, LADSPA_Data ** inputs, LADSPA_Data ** outputs); +#ifdef WITH_JACK int process_jack (jack_nframes_t frames, void * data); +#endif void process_quit (process_info_t * procinfo); From f8cc09193456c2d5d3e4b6432d39de41a5d28447 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Tue, 16 Mar 2021 22:49:08 -0500 Subject: [PATCH 078/122] Do not create alpha buffer if not needed Remove use of mlt_frame_get_alpha_mask() --- src/modules/avformat/consumer_avformat.c | 50 ++++++++++++++++-------- 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/src/modules/avformat/consumer_avformat.c b/src/modules/avformat/consumer_avformat.c index a88abdb21..1b2296d33 100644 --- a/src/modules/avformat/consumer_avformat.c +++ b/src/modules/avformat/consumer_avformat.c @@ -1991,30 +1991,46 @@ static void *consumer_thread( void *arg ) c->pix_fmt == AV_PIX_FMT_BGRA ) { uint8_t *p; - uint8_t *alpha = mlt_frame_get_alpha_mask( frame ); - register int n; + uint8_t *alpha = mlt_frame_get_alpha( frame ); + if ( alpha ) + { + register int n; + for ( i = 0; i < height; i ++ ) + { + n = ( width + 7 ) / 8; + p = converted_avframe->data[ 0 ] + i * converted_avframe->linesize[ 0 ] + 3; + + switch( width % 8 ) + { + case 0: do { *p = *alpha++; p += 4; + case 7: *p = *alpha++; p += 4; + case 6: *p = *alpha++; p += 4; + case 5: *p = *alpha++; p += 4; + case 4: *p = *alpha++; p += 4; + case 3: *p = *alpha++; p += 4; + case 2: *p = *alpha++; p += 4; + case 1: *p = *alpha++; p += 4; + } + while( --n ); + } + } + } + } + else + { for ( i = 0; i < height; i ++ ) { - n = ( width + 7 ) / 8; - p = converted_avframe->data[ 0 ] + i * converted_avframe->linesize[ 0 ] + 3; - - switch( width % 8 ) + int n = width; + uint8_t* p = converted_avframe->data[ 0 ] + i * converted_avframe->linesize[ 0 ] + 3; + while ( n ) { - case 0: do { *p = *alpha++; p += 4; - case 7: *p = *alpha++; p += 4; - case 6: *p = *alpha++; p += 4; - case 5: *p = *alpha++; p += 4; - case 4: *p = *alpha++; p += 4; - case 3: *p = *alpha++; p += 4; - case 2: *p = *alpha++; p += 4; - case 1: *p = *alpha++; p += 4; - } - while( --n ); + *p = 255; + p += 4; + n--; } } } - #if defined(AVFILTER) && LIBAVUTIL_VERSION_MAJOR >= 56 if (AV_PIX_FMT_VAAPI == c->pix_fmt) { AVFilterContext *vfilter_in = mlt_properties_get_data(properties, "vfilter_in", NULL); From ff9728c15b746b92256a8168a1cb513afd9554b8 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 20 Mar 2021 14:22:00 -0500 Subject: [PATCH 079/122] Deprecate start/end parameters when a keyframable alternative exists --- src/modules/core/filter_brightness.yml | 4 ++-- src/modules/core/filter_panner.yml | 4 ++-- src/modules/kdenlive/filter_boxblur.yml | 4 ++-- src/modules/kdenlive/filter_wave.yml | 4 ++-- src/modules/normalize/filter_volume.yml | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/modules/core/filter_brightness.yml b/src/modules/core/filter_brightness.yml index 443584c98..f8a6ad1f7 100644 --- a/src/modules/core/filter_brightness.yml +++ b/src/modules/core/filter_brightness.yml @@ -12,14 +12,14 @@ tags: - Video parameters: - identifier: start - title: Start level + title: Start level (*deprecated*) type: float argument: yes minimum: 0.0 maximum: 15.0 default: 1.0 - - identifier: end + - identifier: end (*deprecated*) title: End level type: float minimum: 0.0 diff --git a/src/modules/core/filter_panner.yml b/src/modules/core/filter_panner.yml index fd4a4a644..6f2eb79f6 100644 --- a/src/modules/core/filter_panner.yml +++ b/src/modules/core/filter_panner.yml @@ -12,7 +12,7 @@ tags: description: Pan an audio channel, adjust balance, or adjust fade. notes: Only handles up to 6 channels. Needs more work balance for surround and other channel layouts. parameters: - - identifier: start + - identifier: start (*deprecated*) title: Start description: > The position of the audio relative to its neighbor channel. For example, @@ -26,7 +26,7 @@ parameters: minimum: 0 maximum: 1 - - identifier: end + - identifier: end (*deprecated*) title: End description: > The ending value of the audio position. It will be interpolated from diff --git a/src/modules/kdenlive/filter_boxblur.yml b/src/modules/kdenlive/filter_boxblur.yml index 70ffe6ee3..53a2a3227 100644 --- a/src/modules/kdenlive/filter_boxblur.yml +++ b/src/modules/kdenlive/filter_boxblur.yml @@ -10,7 +10,7 @@ language: en tags: - Video parameters: - - identifier: start + - identifier: start (*deprecated*) title: Size argument: yes type: integer @@ -28,7 +28,7 @@ parameters: default: 2 minimum: 1 - - identifier: end + - identifier: end (*deprecated*) title: End size type: integer unit: pixels diff --git a/src/modules/kdenlive/filter_wave.yml b/src/modules/kdenlive/filter_wave.yml index 6d4c99d66..e5f2ef90f 100644 --- a/src/modules/kdenlive/filter_wave.yml +++ b/src/modules/kdenlive/filter_wave.yml @@ -10,7 +10,7 @@ language: en tags: - Video parameters: - - identifier: start + - identifier: start (*deprecated*) title: Amplitude argument: yes type: integer @@ -25,7 +25,7 @@ parameters: default: 10 minimum: 1 - - identifier: end + - identifier: end (*deprecated*) title: End amplitude type: integer mutable: yes diff --git a/src/modules/normalize/filter_volume.yml b/src/modules/normalize/filter_volume.yml index d7c1fbe2b..851dae0f0 100644 --- a/src/modules/normalize/filter_volume.yml +++ b/src/modules/normalize/filter_volume.yml @@ -13,7 +13,7 @@ description: > Adjust an audio stream's volume level. This filter is based on the 'normalize' utility parameters: - - identifier: argument + - identifier: argument (*deprecated*) title: Gain type: string description: > @@ -68,7 +68,7 @@ parameters: applied during normalisation. default: 20dB mutable: yes - - identifier: end + - identifier: end (*deprecated*) title: End gain type: string description: > From b4e0729cdbf9762327cb12f8c71f587eb82d45f7 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 20 Mar 2021 16:31:25 -0500 Subject: [PATCH 080/122] Fix DTD for chain and link --- src/modules/xml/mlt-xml.dtd | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/modules/xml/mlt-xml.dtd b/src/modules/xml/mlt-xml.dtd index 6090260c6..67fa85409 100644 --- a/src/modules/xml/mlt-xml.dtd +++ b/src/modules/xml/mlt-xml.dtd @@ -2,7 +2,7 @@ - + @@ -69,14 +70,14 @@ a_track CDATA #IMPLIED b_track CDATA #IMPLIED > - + - + - + - + Date: Sat, 20 Mar 2021 17:26:00 -0500 Subject: [PATCH 081/122] Remove deprecated functions in mlt_audio --- src/framework/mlt_audio.c | 60 ------------------------------- src/framework/mlt_audio.h | 8 ----- src/modules/core/link_timeremap.c | 8 ++--- 3 files changed, 4 insertions(+), 72 deletions(-) diff --git a/src/framework/mlt_audio.c b/src/framework/mlt_audio.c index ec1fe41be..727327b71 100644 --- a/src/framework/mlt_audio.c +++ b/src/framework/mlt_audio.c @@ -712,63 +712,3 @@ mlt_channel_layout mlt_audio_channel_layout_default( int channels ) } return mlt_channel_independent; } - -/** Determine the number of samples that belong in a frame at a time position. - * - * \deprecated since 6.22. Prefer mlt_audio_calculate_samples() - */ - -int mlt_sample_calculator( float fps, int frequency, int64_t position ) -{ - return mlt_audio_calculate_frame_samples( fps, frequency, position ); -} - -/** Determine the number of samples that belong before a time position. - * - * \deprecated since 6.22. Prefer mlt_audio_calculate_samples_to_position() - */ - -int64_t mlt_sample_calculator_to_now( float fps, int frequency, int64_t position ) -{ - return mlt_audio_calculate_samples_to_position( fps, frequency, position ); -} - -/** Get the short name for a channel layout. - * - * \deprecated since 6.22. Prefer mlt_audio_channel_layout_name() - */ - -const char * mlt_channel_layout_name( mlt_channel_layout layout ) -{ - return mlt_audio_channel_layout_name( layout ); -} - -/** Get the id of channel layout from short name. - * - * \deprecated since 6.22. Prefer mlt_audio_channel_layout_id() - */ - -mlt_channel_layout mlt_channel_layout_id( const char * name ) -{ - return mlt_audio_channel_layout_id( name ); -} - -/** Get the number of channels for a channel layout. - * - * \deprecated since 6.22. Prefer mlt_audio_channel_layout_channels() - */ - -int mlt_channel_layout_channels( mlt_channel_layout layout ) -{ - return mlt_audio_channel_layout_channels( layout ); -} - -/** Get a default channel layout for a given number of channels. - * - * \deprecated since 6.22. Prefer mlt_audio_channel_layout_default() - */ - -mlt_channel_layout mlt_channel_layout_default( int channels ) -{ - return mlt_audio_channel_layout_default( channels ); -} diff --git a/src/framework/mlt_audio.h b/src/framework/mlt_audio.h index 7cd72e086..89dc06ffb 100644 --- a/src/framework/mlt_audio.h +++ b/src/framework/mlt_audio.h @@ -64,12 +64,4 @@ extern mlt_channel_layout mlt_audio_channel_layout_id( const char * name ); extern int mlt_audio_channel_layout_channels( mlt_channel_layout layout ); extern mlt_channel_layout mlt_audio_channel_layout_default( int channels ); -// Deprecated functions -extern int mlt_sample_calculator( float fps, int frequency, int64_t position ); -extern int64_t mlt_sample_calculator_to_now( float fps, int frequency, int64_t position ); -extern const char * mlt_channel_layout_name( mlt_channel_layout layout ); -extern mlt_channel_layout mlt_channel_layout_id( const char * name ); -extern int mlt_channel_layout_channels( mlt_channel_layout layout ); -extern mlt_channel_layout mlt_channel_layout_default( int channels ); - #endif diff --git a/src/modules/core/link_timeremap.c b/src/modules/core/link_timeremap.c index eb04b67b2..24d1882c9 100644 --- a/src/modules/core/link_timeremap.c +++ b/src/modules/core/link_timeremap.c @@ -65,7 +65,7 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form { // Return silent samples for speeds less than 0.1 or > 10 mlt_position position = mlt_frame_original_position( frame ); - *samples = mlt_sample_calculator( link_fps, *frequency, position ); + *samples = mlt_audio_calculate_frame_samples( link_fps, *frequency, position ); int size = mlt_audio_format_size( *format, *samples, *channels ); *audio = mlt_pool_alloc( size ); memset( *audio, 0, size ); @@ -75,7 +75,7 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form else { // Calculate the samples to get from the input frames - int link_sample_count = mlt_sample_calculator( link_fps, *frequency, mlt_frame_get_position( frame ) ); + int link_sample_count = mlt_audio_calculate_frame_samples( link_fps, *frequency, mlt_frame_get_position( frame ) ); int sample_count = lrint( (double)link_sample_count * source_speed ); mlt_position in_frame_pos = floor( source_time * source_fps ); int64_t first_out_sample = llrint(source_time * (double)*frequency); @@ -105,7 +105,7 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form } } - int64_t first_in_sample = mlt_sample_calculator_to_now( source_fps, *frequency, in_frame_pos ); + int64_t first_in_sample = mlt_audio_calculate_samples_to_position( source_fps, *frequency, in_frame_pos ); int samples_to_skip = first_out_sample - first_in_sample; if ( samples_to_skip < 0 ) { @@ -133,7 +133,7 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form break; } - int in_samples = mlt_sample_calculator( source_fps, *frequency, in_frame_pos ); + int in_samples = mlt_audio_calculate_frame_samples( source_fps, *frequency, in_frame_pos ); struct mlt_audio_s in; mlt_audio_set_values( &in, NULL, *frequency, *format, in_samples, *channels ); From a097f3e4fa113eb42317266e7fbca8e1a21ea5f6 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 20 Mar 2021 17:33:32 -0500 Subject: [PATCH 082/122] Remove deprecated functions from mlt_playlist --- src/framework/mlt_playlist.c | 19 ------------------- src/framework/mlt_playlist.h | 1 - src/mlt++/MltPlaylist.cpp | 6 ------ src/mlt++/MltPlaylist.h | 1 - 4 files changed, 27 deletions(-) diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c index 0359ab167..2593d3228 100644 --- a/src/framework/mlt_playlist.c +++ b/src/framework/mlt_playlist.c @@ -2024,25 +2024,6 @@ int mlt_playlist_remove_region( mlt_playlist self, mlt_position position, int le return index; } -/** Not implemented - * - * \deprecated not implemented - * \public \memberof mlt_playlist_s - * \param self - * \param position - * \param length - * \param new_position - * \return - */ - -int mlt_playlist_move_region( mlt_playlist self, mlt_position position, int length, int new_position ) -{ - if ( self != NULL ) - { - } - return 0; -} - /** Get the current frame. * * The implementation of the get_frame virtual function. diff --git a/src/framework/mlt_playlist.h b/src/framework/mlt_playlist.h index 784e517dd..20be7bafb 100644 --- a/src/framework/mlt_playlist.h +++ b/src/framework/mlt_playlist.h @@ -126,7 +126,6 @@ extern int mlt_playlist_clip_start( mlt_playlist self, int clip ); extern int mlt_playlist_clip_length( mlt_playlist self, int clip ); extern int mlt_playlist_blanks_from( mlt_playlist self, int clip, int bounded ); extern int mlt_playlist_remove_region( mlt_playlist self, mlt_position position, int length ); -extern int mlt_playlist_move_region( mlt_playlist self, mlt_position position, int length, int new_position ); extern void mlt_playlist_close( mlt_playlist self ); #endif diff --git a/src/mlt++/MltPlaylist.cpp b/src/mlt++/MltPlaylist.cpp index a1730680f..6b0698e29 100644 --- a/src/mlt++/MltPlaylist.cpp +++ b/src/mlt++/MltPlaylist.cpp @@ -335,9 +335,3 @@ int Playlist::remove_region( int position, int length ) { return mlt_playlist_remove_region( get_playlist( ), position, length ); } - -int Playlist::move_region( int position, int length, int new_position ) -{ - return mlt_playlist_move_region( get_playlist( ), position, length, new_position ); -} - diff --git a/src/mlt++/MltPlaylist.h b/src/mlt++/MltPlaylist.h index 738ad3c37..b7b3c309f 100644 --- a/src/mlt++/MltPlaylist.h +++ b/src/mlt++/MltPlaylist.h @@ -107,7 +107,6 @@ namespace Mlt int clip_length( int clip ); int blanks_from( int clip, int bounded = 0 ); int remove_region( int position, int length ); - int move_region( int position, int length, int new_position ); }; } From f00fbbc3db146420bc6a46c3180d9734e5a64e60 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 20 Mar 2021 17:36:39 -0500 Subject: [PATCH 083/122] Remove deprecated "font" parameter from producer_pango --- src/modules/gdk/producer_pango.c | 15 +++------------ src/modules/gdk/producer_pango.yml | 11 ----------- 2 files changed, 3 insertions(+), 23 deletions(-) diff --git a/src/modules/gdk/producer_pango.c b/src/modules/gdk/producer_pango.c index 0cead7fdd..95ec6edb4 100644 --- a/src/modules/gdk/producer_pango.c +++ b/src/modules/gdk/producer_pango.c @@ -797,18 +797,9 @@ static GdkPixbuf *pango_get_pixbuf( const char *markup, const char *text, const FT_Bitmap bitmap; PangoFontDescription *desc = NULL; - if( font ) - { - // Support for deprecated "font" property. - desc = pango_font_description_from_string( font ); - pango_ft2_font_map_set_resolution( fontmap, 72, 72 ); - } - else - { - desc = pango_font_description_from_string( family ); - pango_font_description_set_size( desc, PANGO_SCALE * size ); - pango_font_description_set_style( desc, (PangoStyle) style ); - } + desc = pango_font_description_from_string( family ); + pango_font_description_set_size( desc, PANGO_SCALE * size ); + pango_font_description_set_style( desc, (PangoStyle) style ); pango_font_description_set_weight( desc, ( PangoWeight ) weight ); diff --git a/src/modules/gdk/producer_pango.yml b/src/modules/gdk/producer_pango.yml index d270e4423..81f030514 100644 --- a/src/modules/gdk/producer_pango.yml +++ b/src/modules/gdk/producer_pango.yml @@ -143,17 +143,6 @@ parameters: mutable: yes widget: textbox - - identifier: font - title: Font - type: string - description: > - The default typeface to use when not using markup. - FreeType2 renders at 72 dpi. - This property is deprecated. Use family, size and style instead. - readonly: no - mutable: yes - widget: combo - - identifier: family title: Font family type: string From 20be7dd0b971e0dcfc2507ce63d5424b8b2825cf Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 20 Mar 2021 17:54:27 -0500 Subject: [PATCH 084/122] Remove deprecated producer_sdl_image --- CMakeLists.txt | 1 - src/framework/mlt_types.h | 2 - src/modules/sdl/CMakeLists.txt | 7 - src/modules/sdl/Makefile | 6 - src/modules/sdl/configure | 9 - src/modules/sdl/factory.c | 7 - src/modules/sdl/producer_sdl_image.c | 254 ------------------------- src/modules/sdl/producer_sdl_image.yml | 12 -- 8 files changed, 298 deletions(-) delete mode 100644 src/modules/sdl/producer_sdl_image.c delete mode 100644 src/modules/sdl/producer_sdl_image.yml diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f1602154..faa3ea3c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -306,7 +306,6 @@ endif() if(MOD_SDL1) pkg_check_modules(sdl IMPORTED_TARGET sdl) if(TARGET PkgConfig::sdl) - pkg_check_modules(sdl_image IMPORTED_TARGET SDL_image) list(APPEND MLT_SUPPORTED_COMPONENTS sdl) else() set(MOD_SDL1 OFF) diff --git a/src/framework/mlt_types.h b/src/framework/mlt_types.h index 9e0db8510..d1dfd768a 100644 --- a/src/framework/mlt_types.h +++ b/src/framework/mlt_types.h @@ -61,7 +61,6 @@ mlt_image_format; typedef enum { mlt_audio_none = 0,/**< audio not available */ - mlt_audio_pcm = 1, /**< \deprecated signed 16-bit interleaved PCM */ mlt_audio_s16 = 1, /**< signed 16-bit interleaved PCM */ mlt_audio_s32, /**< signed 32-bit non-interleaved PCM */ mlt_audio_float, /**< 32-bit non-interleaved floating point */ @@ -129,7 +128,6 @@ typedef enum mlt_time_frames = 0, /**< frame count */ mlt_time_clock, /**< SMIL clock-value as [[hh:]mm:]ss[.fraction] */ mlt_time_smpte_df, /**< SMPTE timecode as [[[hh:]mm:]ss{:|;}]frames */ - mlt_time_smpte = mlt_time_smpte_df, /**< Deprecated */ mlt_time_smpte_ndf /**< SMPTE NDF timecode as [[[hh:]mm:]ss:]frames */ } mlt_time_format; diff --git a/src/modules/sdl/CMakeLists.txt b/src/modules/sdl/CMakeLists.txt index cf2a2c09e..cf8cee39b 100644 --- a/src/modules/sdl/CMakeLists.txt +++ b/src/modules/sdl/CMakeLists.txt @@ -10,13 +10,6 @@ target_compile_options(mltsdl PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltsdl PRIVATE mlt m Threads::Threads PkgConfig::sdl) -if(TARGET PkgConfig::sdl_image) - target_sources(mltsdl PRIVATE producer_sdl_image.c) - target_link_libraries(mltsdl PRIVATE PkgConfig::sdl_image) - target_compile_definitions(mltsdl PRIVATE WITH_SDL_IMAGE) - install(FILES producer_sdl_image.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/sdl) -endif() - set_target_properties(mltsdl PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltsdl LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) diff --git a/src/modules/sdl/Makefile b/src/modules/sdl/Makefile index b789750f1..dd86262b0 100644 --- a/src/modules/sdl/Makefile +++ b/src/modules/sdl/Makefile @@ -34,12 +34,6 @@ CFLAGS += $(shell sdl-config --cflags) LDFLAGS += $(shell sdl-config --libs) endif -ifeq ($(WITH_SDL_IMAGE),1) -OBJS += producer_sdl_image.o -CFLAGS += -DWITH_SDL_IMAGE -LDFLAGS += -lSDL_image -endif - SRCS := $(OBJS:.o=.c) ifeq ($(targetos),Darwin) OBJS += consumer_sdl_osx.o diff --git a/src/modules/sdl/configure b/src/modules/sdl/configure index f1d693d2b..8ac51cd6e 100755 --- a/src/modules/sdl/configure +++ b/src/modules/sdl/configure @@ -6,19 +6,10 @@ if [ "$help" != "1" ]; then echo " - using SDL version $(pkg-config --modversion sdl)" echo "USE_PKG_CONFIG=1" > config.mak echo "HAVE_SDL1=1" >> config.mak - image=`pkg-config --variable=prefix sdl`/include/SDL/SDL_image.h - if [ -f "$image" ]; then - echo " - found SDL_image" - echo "WITH_SDL_IMAGE=1" >> config.mak - fi elif sdl-config --version > /dev/null 2>&1 ; then echo " - using SDL version $(sdl-config --version)" echo "USE_PKG_CONFIG=0" > config.mak echo "HAVE_SDL1=1" >> config.mak - image=`sdl-config --prefix`/include/SDL/SDL_image.h - if [ -f "$image" ]; then - echo "WITH_SDL_IMAGE=1" >> config.mak - fi else echo "- SDL development libs not found: disabling" touch ../disable-sdl diff --git a/src/modules/sdl/factory.c b/src/modules/sdl/factory.c index 6fe2d43c2..f69416c1a 100644 --- a/src/modules/sdl/factory.c +++ b/src/modules/sdl/factory.c @@ -27,9 +27,6 @@ extern mlt_consumer consumer_sdl_audio_init( mlt_profile profile, mlt_service_ty extern mlt_consumer consumer_sdl_still_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); extern mlt_consumer consumer_sdl_preview_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -#ifdef WITH_SDL_IMAGE -extern mlt_producer producer_sdl_image_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ); -#endif static mlt_properties metadata( mlt_service_type type, const char *id, void *data ) { @@ -49,8 +46,4 @@ MLT_REPOSITORY MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdl_preview", metadata, "consumer_sdl_preview.yml" ); MLT_REGISTER( mlt_service_consumer_type, "sdl_still", consumer_sdl_still_init ); MLT_REGISTER_METADATA( mlt_service_consumer_type, "sdl_still", metadata, "consumer_sdl_still.yml" ); -#ifdef WITH_SDL_IMAGE - MLT_REGISTER( mlt_service_producer_type, "sdl_image", producer_sdl_image_init ); - MLT_REGISTER_METADATA( mlt_service_producer_type, "sdl_image", metadata, "consumer_sdl_image.yml" ); -#endif } diff --git a/src/modules/sdl/producer_sdl_image.c b/src/modules/sdl/producer_sdl_image.c deleted file mode 100644 index 24742590e..000000000 --- a/src/modules/sdl/producer_sdl_image.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * producer_sdl_image.c -- Image loader which wraps SDL_image - * Copyright (C) 2005-2014 Meltytech, LLC - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -static int producer_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) -{ - mlt_properties properties = MLT_FRAME_PROPERTIES( frame ); - SDL_Surface *surface = mlt_properties_get_data( properties, "surface", NULL ); - SDL_Surface *converted = NULL; - - *width = surface->w; - *height = surface->h; - int image_size = *width * *height * 3; - - if ( surface->format->BitsPerPixel != 32 && surface->format->BitsPerPixel != 24 ) - { - SDL_PixelFormat fmt; - fmt.BitsPerPixel = 24; - fmt.BytesPerPixel = 3; - fmt.Rshift = 16; - fmt.Gshift = 8; - fmt.Bshift = 0; - fmt.Rmask = 0xff << 16; - fmt.Gmask = 0xff << 8; - fmt.Bmask = 0xff; - converted = SDL_ConvertSurface( surface, &fmt, 0 ); - } - - switch( surface->format->BitsPerPixel ) - { - case 32: - *format = mlt_image_rgba; - image_size = *width * *height * 4; - *image = mlt_pool_alloc( image_size ); - memcpy( *image, surface->pixels, image_size ); - break; - default: - *format = mlt_image_rgb; - *image = mlt_pool_alloc( image_size ); - memcpy( *image, surface->pixels, image_size ); - break; - } - - if ( converted ) - SDL_FreeSurface( converted ); - - // Update the frame - mlt_frame_set_image( frame, *image, image_size, mlt_pool_release ); - - return 0; -} - -static int filter_files( const struct dirent *de ) -{ - return de->d_name[ 0 ] != '.'; -} - -static mlt_properties parse_file_names( char *resource ) -{ - mlt_properties properties = mlt_properties_new( ); - - if ( strstr( resource, "/.all." ) != NULL ) - { - char *dir_name = strdup( resource ); - char *extension = strrchr( resource, '.' ); - *( strstr( dir_name, "/.all." ) + 1 ) = '\0'; - char fullname[ 1024 ]; - strcpy( fullname, dir_name ); - struct dirent **de = NULL; - int n = scandir( fullname, &de, filter_files, alphasort ); - int i; - struct stat info; - - for (i = 0; i < n; i++ ) - { - snprintf( fullname, 1023, "%s%s", dir_name, de[i]->d_name ); - if ( strstr( fullname, extension ) && lstat( fullname, &info ) == 0 && - ( S_ISREG( info.st_mode ) || info.st_mode | S_IXUSR ) ) - { - char temp[ 20 ]; - sprintf( temp, "%d", i ); - mlt_properties_set( properties, temp, fullname ); - } - free( de[ i ] ); - } - - free( de ); - free( dir_name ); - } - else - { - mlt_properties_set( properties, "0", resource ); - } - - return properties; -} - -static SDL_Surface *load_image( mlt_producer producer ) -{ - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - char *resource = mlt_properties_get( properties, "resource" ); - char *last_resource = mlt_properties_get( properties, "_last_resource" ); - int image_idx = 0; - char *this_resource = NULL; - double ttl = mlt_properties_get_int( properties, "ttl" ); - mlt_position position = mlt_producer_position( producer ); - SDL_Surface *surface = mlt_properties_get_data( properties, "_surface", NULL ); - mlt_properties filenames = mlt_properties_get_data( properties, "_filenames", NULL ); - - if ( filenames == NULL ) - { - filenames = parse_file_names( resource ); - mlt_properties_set_data( properties, "_filenames", filenames, 0, ( mlt_destructor )mlt_properties_close, 0 ); - mlt_properties_set_data( properties, "_surface", surface, 0, ( mlt_destructor )SDL_FreeSurface, 0 ); - } - - if ( mlt_properties_count( filenames ) ) - { - image_idx = ( int )floor( ( double )position / ttl ) % mlt_properties_count( filenames ); - this_resource = mlt_properties_get_value( filenames, image_idx ); - - if ( surface == NULL || last_resource == NULL || strcmp( last_resource, this_resource ) ) - { - surface = IMG_Load( this_resource ); - if ( surface != NULL ) - { - surface->refcount ++; - mlt_properties_set_data( properties, "_surface", surface, 0, ( mlt_destructor )SDL_FreeSurface, 0 ); - mlt_properties_set( properties, "_last_resource", this_resource ); - mlt_properties_set_int( properties, "meta.media.width", surface->w ); - mlt_properties_set_int( properties, "meta.media.height", surface->h ); - } - } - else if ( surface != NULL ) - { - surface->refcount ++; - } - } - - return surface; -} - -static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int index ) -{ - // Generate a frame - *frame = mlt_frame_init( MLT_PRODUCER_SERVICE( producer ) ); - - if ( *frame != NULL ) - { - // Create the surface for the current image - SDL_Surface *surface = load_image( producer ); - - if ( surface != NULL ) - { - // Obtain properties of frame and producer - mlt_properties properties = MLT_FRAME_PROPERTIES( *frame ); - - // Obtain properties of producer - mlt_properties producer_props = MLT_PRODUCER_PROPERTIES( producer ); - - // Update timecode on the frame we're creating - mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); - - // Set producer-specific frame properties - mlt_properties_set_int( properties, "progressive", 1 ); - mlt_properties_set_double( properties, "aspect_ratio", mlt_properties_get_double( producer_props, "aspect_ratio" ) ); - mlt_properties_set_data( properties, "surface", surface, 0, ( mlt_destructor )SDL_FreeSurface, NULL ); - - // Push the get_image method - mlt_frame_push_get_image( *frame, producer_get_image ); - } - } - - // Calculate the next timecode - mlt_producer_prepare_next( producer ); - - return 0; -} - -static void producer_close( mlt_producer producer ) -{ - producer->close = NULL; - mlt_producer_close( producer ); - free( producer ); -} - -mlt_producer producer_sdl_image_init( mlt_profile profile, mlt_service_type type, const char *id, char *file ) -{ - mlt_producer producer = calloc( 1, sizeof( struct mlt_producer_s ) ); - if ( producer != NULL && mlt_producer_init( producer, NULL ) == 0 ) - { - // Get the properties interface - mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer ); - - // Callback registration - producer->get_frame = producer_get_frame; - producer->close = ( mlt_destructor )producer_close; - - // Set the default properties - mlt_properties_set( properties, "resource", file ); - mlt_properties_set( properties, "_resource", "" ); - mlt_properties_set_double( properties, "aspect_ratio", 1 ); - mlt_properties_set_int( properties, "ttl", 25 ); - mlt_properties_set_int( properties, "progressive", 1 ); - - // Validate the resource - SDL_Surface *surface = NULL; - if ( file && ( surface = load_image( producer ) ) ) - { - SDL_FreeSurface( surface ); - mlt_properties_set_data( properties, "_surface", NULL, 0, NULL, NULL ); - } - else - { - producer_close( producer ); - producer = NULL; - } - return producer; - } - free( producer ); - return NULL; -} - - diff --git a/src/modules/sdl/producer_sdl_image.yml b/src/modules/sdl/producer_sdl_image.yml deleted file mode 100644 index 2e85a3732..000000000 --- a/src/modules/sdl/producer_sdl_image.yml +++ /dev/null @@ -1,12 +0,0 @@ -schema_version: 0.1 -type: producer -identifier: sdl_image -title: SDL Image -version: 1 -copyright: Meltytech, LLC -creator: Charles Yates -license: LGPLv2.1 -language: en -notes: DEPRECATED -tags: - - Video From 038e7777024bfa51d07181cd05bd1482d86ac103 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 20 Mar 2021 22:56:44 -0500 Subject: [PATCH 085/122] Fix unused variable warning --- src/modules/plus/filter_pillar_echo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/modules/plus/filter_pillar_echo.c b/src/modules/plus/filter_pillar_echo.c index 7016d19a9..31c6916fb 100644 --- a/src/modules/plus/filter_pillar_echo.c +++ b/src/modules/plus/filter_pillar_echo.c @@ -1,6 +1,6 @@ /* * filter_pillar_echo.c -- filter to interpolate pixels outside an area of interest - * Copyright (c) 2020 Meltytech, LLC + * Copyright (c) 2020-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -107,7 +107,6 @@ static void bilinear_scale_rgba( uint8_t* src, uint8_t* dst, int width, int heig double factorSum[] = {0.0, 0.0, 0.0, 0.0}; uint8_t* s = src + (srcYindex * linesize) + (srcXindex * 4); - uint8_t* st = s; // Top Left double ftl = ftop * fleft; From 93d698d99d98fe77d368b513be3bd13e8bac59cd Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 20 Mar 2021 22:57:07 -0500 Subject: [PATCH 086/122] Convert filter_brightness to use mlt_image Also remove the use of deprecated mlt_frame_get_alpha_mask() Only create an alpha mask it if is necessary --- src/framework/mlt.vers | 1 + src/framework/mlt_image.c | 35 +++++++++- src/framework/mlt_image.h | 1 + src/modules/core/filter_brightness.c | 98 +++++++++++++++++----------- 4 files changed, 94 insertions(+), 41 deletions(-) diff --git a/src/framework/mlt.vers b/src/framework/mlt.vers index 8da30f67d..732118673 100644 --- a/src/framework/mlt.vers +++ b/src/framework/mlt.vers @@ -603,6 +603,7 @@ MLT_7.0.0 { mlt_image_alloc_alpha; mlt_image_calculate_size; mlt_image_fill_black; + mlt_image_fill_opaque; mlt_audio_silence; mlt_event_data_none; mlt_event_data_from_int; diff --git a/src/framework/mlt_image.c b/src/framework/mlt_image.c index fd8a786f1..37640d212 100644 --- a/src/framework/mlt_image.c +++ b/src/framework/mlt_image.c @@ -3,7 +3,7 @@ * \brief Image class * \see mlt_mlt_image_s * - * Copyright (C) 2020 Meltytech, LLC + * Copyright (C) 2020-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -187,6 +187,9 @@ int mlt_image_calculate_size( mlt_image self ) return 4; case mlt_image_yuv422p16: return 4 * self->width * self->height; + case mlt_image_none: + case mlt_image_invalid: + return 0; } return 0; } @@ -245,8 +248,9 @@ void mlt_image_fill_black( mlt_image self ) { if ( !self->data) return; - switch( self->format ) + switch( self->format ) { + case mlt_image_invalid: case mlt_image_none: case mlt_image_movit: case mlt_image_opengl_texture: @@ -302,8 +306,33 @@ void mlt_image_fill_black( mlt_image self ) } break; } +} + +/** Fill an image alpha channel with opaque if it exists. + * + * \public \memberof mlt_image_s + */ +void mlt_image_fill_opaque( mlt_image self ) +{ + if ( !self->data) return; - } + if ( self->format == mlt_image_rgba && self->planes[0] != NULL ) + { + for ( int line = 0; line < self->height; line++ ) + { + uint8_t* pLine = self->planes[0] + ( self->strides[0] * line ) + 3; + for ( int pixel = 0; pixel < self->width; pixel++ ) + { + *pLine = 0xff; + *pLine += 4; + } + } + } + else if ( self->planes[3] != NULL ) + { + memset( self->planes[3], 255, self->height * self->strides[3] ); + } +} /** Get the number of bytes needed for an image. * diff --git a/src/framework/mlt_image.h b/src/framework/mlt_image.h index 9cb6ece01..2800a0c31 100644 --- a/src/framework/mlt_image.h +++ b/src/framework/mlt_image.h @@ -54,6 +54,7 @@ extern void mlt_image_alloc_data( mlt_image self ); extern void mlt_image_alloc_alpha( mlt_image self ); extern int mlt_image_calculate_size( mlt_image self ); extern void mlt_image_fill_black( mlt_image self ); +extern void mlt_image_fill_opaque( mlt_image self ); extern const char * mlt_image_format_name( mlt_image_format format ); extern mlt_image_format mlt_image_format_id( const char * name ); diff --git a/src/modules/core/filter_brightness.c b/src/modules/core/filter_brightness.c index a7f632e6e..413a17e89 100644 --- a/src/modules/core/filter_brightness.c +++ b/src/modules/core/filter_brightness.c @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -28,49 +29,56 @@ struct sliced_desc { - uint8_t *image; - int rgba; - int width, height; + mlt_image image; double level; double alpha_level; - uint8_t* alpha; }; static int sliced_proc(int id, int index, int jobs, void* cookie) { (void) id; // unused - struct sliced_desc ctx = *((struct sliced_desc*) cookie); - int slice_height = (ctx.height + jobs - 1) / jobs; - int slice_offset = index * slice_height * ctx.width; - slice_height = MIN(slice_height, ctx.height - index * slice_height); + struct sliced_desc* ctx = ((struct sliced_desc*) cookie); + int slice_height = (ctx->image->height + jobs - 1) / jobs; + int slice_line_start = index * slice_height; + slice_height = MIN(slice_height, ctx->image->height - slice_line_start); // Only process if level is something other than 1 - if (ctx.level != 1.0) { - int i = ctx.width * slice_height + 1; - uint8_t *p = ctx.image + (slice_offset * 2); - int32_t m = ctx.level * (1 << 16); + if (ctx->level != 1.0 && ctx->image->format == mlt_image_yuv422) { + int32_t m = ctx->level * (1 << 16); int32_t n = 128 * ((1 << 16 ) - m); - - for (; --i; p += 2) { - p[0] = CLAMP((p[0] * m) >> 16, 16, 235); - p[1] = CLAMP((p[1] * m + n) >> 16, 16, 240); + for ( int line = 0; line < slice_height; line++ ) + { + uint8_t* p = ctx->image->planes[0] + ( (slice_line_start + line) * ctx->image->strides[0]); + for ( int pixel = 0; pixel < ctx->image->width; pixel++ ) + { + *p++ = CLAMP((*p * m) >> 16, 16, 235); + *p++ = CLAMP((*p * m + n) >> 16, 16, 240); + } } + } // Process the alpha channel if requested. - if (ctx.alpha_level != 1.0) { - int32_t m = ctx.alpha_level * (1 << 16); - int i = ctx.width * slice_height + 1; - - if (ctx.rgba) { - uint8_t *p = ctx.image + (slice_offset * 4) + 3; - for (; --i; p += 4) { - p[0] = (p[0] * m) >> 16; + if (ctx->alpha_level != 1.0) { + int32_t m = ctx->alpha_level * (1 << 16); + if (ctx->image->format == mlt_image_rgba) { + for ( int line = 0; line < slice_height; line++ ) + { + uint8_t* p = ctx->image->planes[0] + ( (slice_line_start + line) * ctx->image->strides[0]) + 3; + for ( int pixel = 0; pixel < ctx->image->width; pixel++ ) + { + *p = (*p * m) >> 16; + p += 4; + } } } else { - uint8_t *p = ctx.alpha + slice_offset; - for (; --i; ++p) { - p[0] = (p[0] * m) >> 16; + for ( int line = 0; line < slice_height; line++ ) + { + uint8_t* p = ctx->image->planes[3] + ( (slice_line_start + line) * ctx->image->strides[3]); + for ( int pixel = 0; pixel < ctx->image->width; pixel++ ) + { + *p++ = (*p * m) >> 16; + } } } } @@ -87,6 +95,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_position position = mlt_filter_get_position( filter, frame ); mlt_position length = mlt_filter_get_length2( filter, frame ); double level = 1.0; + double alpha_level = 1.0; // Use animated "level" property only if it has been set since init char* level_property = mlt_properties_get( properties, "level" ); @@ -116,20 +125,33 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // Get the image int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); + level = (*format == mlt_image_yuv422) ? level : 1.0; + alpha_level = mlt_properties_get(properties, "alpha")? MIN(mlt_properties_anim_get_double(properties, "alpha", position, length), 1.0) : 1.0; + if (alpha_level < 0.0) { + alpha_level = level; + } + // Only process if we have no error. - if (!error) { + if (!error && (level != 1.0 || alpha_level != 1.0)) { int threads = mlt_properties_get_int(properties, "threads"); + struct sliced_desc desc; + struct mlt_image_s proc_image; + mlt_image_set_values( &proc_image, *image, *format, *width, *height ); + if (alpha_level != 1.0 && proc_image.format != mlt_image_rgba) { + proc_image.planes[3] = mlt_frame_get_alpha(frame); + proc_image.strides[3] = proc_image.width; + if (!proc_image.planes[3]) { + // Alpha will be needed but it does not exist yet. Create opaque alpha. + mlt_image_alloc_alpha( &proc_image ); + mlt_image_fill_opaque( &proc_image ); + mlt_frame_set_alpha( frame, proc_image.planes[3], 0, proc_image.release_alpha ); + } + } + desc.level = level; + desc.alpha_level = alpha_level; + desc.image = &proc_image; + threads = CLAMP(threads, 0, mlt_slices_count_normal()); - double alpha = mlt_properties_get(properties, "alpha")? MIN(mlt_properties_anim_get_double(properties, "alpha", position, length), 1.0) : 1.0; - struct sliced_desc desc = { - .image = *image, - .rgba = (*format == mlt_image_rgba), - .width = *width, - .height = *height, - .level = (*format == mlt_image_yuv422)? level : 1.0, - .alpha_level = alpha >= 0.0 ? alpha : level, - .alpha = mlt_frame_get_alpha_mask(frame) - }; if (threads == 1) { sliced_proc(0, 0, 1, &desc); } else { From 92c2aeefcce138909158de2dcfa83ddd50b6a3bb Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 20 Mar 2021 23:16:12 -0500 Subject: [PATCH 087/122] Remove deprecated functions in mlt_slices The functions are still used internally so they have been removed from the public interface. --- src/framework/mlt_slices.c | 11 ++++------- src/framework/mlt_slices.h | 8 +------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/src/framework/mlt_slices.c b/src/framework/mlt_slices.c index 60b17cd40..a2e5727cf 100644 --- a/src/framework/mlt_slices.c +++ b/src/framework/mlt_slices.c @@ -3,7 +3,7 @@ * \brief sliced threading processing helper * \see mlt_slices_s * - * Copyright (C) 2016-2017 Meltytech, LLC + * Copyright (C) 2016-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -136,14 +136,13 @@ static void* mlt_slices_worker( void* p ) /** Initialize a sliced threading context * * \public \memberof mlt_slices_s - * \deprecated * \param threads number of threads to use for job list, 0 for #cpus * \param policy scheduling policy of processing threads, -1 for normal * \param priority priority value that can be used with the scheduling algorithm, -1 for maximum * \return the context pointer */ -mlt_slices mlt_slices_init( int threads, int policy, int priority ) +static mlt_slices mlt_slices_init( int threads, int policy, int priority ) { pthread_attr_t tattr; struct sched_param param; @@ -220,11 +219,10 @@ mlt_slices mlt_slices_init( int threads, int policy, int priority ) /** Destroy sliced threading context * * \public \memberof mlt_slices_s - * \deprecated * \param ctx context pointer */ -void mlt_slices_close( mlt_slices ctx ) +static void mlt_slices_close( mlt_slices ctx ) { int j; @@ -265,13 +263,12 @@ void mlt_slices_close( mlt_slices ctx ) /** Run sliced execution * * \public \memberof mlt_slices_s - * \deprecated * \param ctx context pointer * \param jobs number of jobs to process * \param proc number of jobs to process */ -void mlt_slices_run( mlt_slices ctx, int jobs, mlt_slices_proc proc, void* cookie ) +static void mlt_slices_run( mlt_slices ctx, int jobs, mlt_slices_proc proc, void* cookie ) { struct mlt_slices_runtime_s runtime, *r = &runtime; diff --git a/src/framework/mlt_slices.h b/src/framework/mlt_slices.h index 25ffd4404..ad4b2ebce 100644 --- a/src/framework/mlt_slices.h +++ b/src/framework/mlt_slices.h @@ -3,7 +3,7 @@ * \brief sliced threading processing helper * \see mlt_slices_s * - * Copyright (C) 2016-2017 Meltytech, LLC + * Copyright (C) 2016-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -34,12 +34,6 @@ struct mlt_slices_s; typedef int (*mlt_slices_proc)( int id, int idx, int jobs, void* cookie ); -extern mlt_slices mlt_slices_init( int threads, int policy, int priority ); - -extern void mlt_slices_close( mlt_slices ctx ); - -extern void mlt_slices_run( mlt_slices ctx, int jobs, mlt_slices_proc proc, void* cookie ); - extern int mlt_slices_count_normal(); extern int mlt_slices_count_rr(); From 7846f12085623fdbff53bec87f036db9f7d5c759 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 21 Mar 2021 19:10:20 -0500 Subject: [PATCH 088/122] Refactor filter_imageconvert * Use mlt_image class * Remove the use of deprecated function mlt_frame_get_alpha_mask() * Add some missing conversion functions * Do not leave alpha buffers on frames with mlt_image_rgba * Do not create alpha buffers if they are not needed Tested to work with conversions needed by Shotcut --- src/modules/core/filter_imageconvert.c | 537 ++++++++++++++++--------- 1 file changed, 341 insertions(+), 196 deletions(-) diff --git a/src/modules/core/filter_imageconvert.c b/src/modules/core/filter_imageconvert.c index 3993266b4..1f836e86d 100644 --- a/src/modules/core/filter_imageconvert.c +++ b/src/modules/core/filter_imageconvert.c @@ -1,6 +1,6 @@ /* * filter_imageconvert.c -- colorspace and pixel format converter - * Copyright (C) 2009-2014 Meltytech, LLC + * Copyright (C) 2009-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -54,256 +55,410 @@ #define YUV2RGB_601 YUV2RGB_601_UNSCALED #endif -static int convert_yuv422_to_rgb24a( uint8_t *yuv, uint8_t *rgba, uint8_t *alpha, int width, int height ) +static void convert_yuv422_to_rgba( mlt_image src, mlt_image dst ) { - int ret = 0; int yy, uu, vv; int r,g,b; - int total = width * height / 2 + 1; - while ( --total ) + mlt_image_set_values( dst, NULL, mlt_image_rgba, src->width, src->height ); + mlt_image_alloc_data( dst ); + + for ( int line = 0; line < src->height; line++ ) { - yy = yuv[0]; - uu = yuv[1]; - vv = yuv[3]; - YUV2RGB_601( yy, uu, vv, r, g, b ); - rgba[0] = r; - rgba[1] = g; - rgba[2] = b; - rgba[3] = *alpha++; - yy = yuv[2]; - YUV2RGB_601( yy, uu, vv, r, g, b ); - rgba[4] = r; - rgba[5] = g; - rgba[6] = b; - rgba[7] = *alpha++; - yuv += 4; - rgba += 8; + uint8_t* pSrc = src->planes[0] + src->strides[0] * line; + uint8_t* pAlpha = src->planes[3] + src->strides[3] * line; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + int total = src->width / 2 + 1; + + if ( pAlpha ) + while ( --total ) + { + yy = pSrc[0]; + uu = pSrc[1]; + vv = pSrc[3]; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[0] = r; + pDst[1] = g; + pDst[2] = b; + pDst[3] = *pAlpha++; + yy = pSrc[2]; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[4] = r; + pDst[5] = g; + pDst[6] = b; + pDst[7] = *pAlpha++; + pSrc += 4; + pDst += 8; + } + else + while ( --total ) + { + yy = pSrc[0]; + uu = pSrc[1]; + vv = pSrc[3]; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[0] = r; + pDst[1] = g; + pDst[2] = b; + pDst[3] = 0xff; + yy = pSrc[2]; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[4] = r; + pDst[5] = g; + pDst[6] = b; + pDst[7] = 0xff; + pSrc += 4; + pDst += 8; + } } - return ret; } -static int convert_yuv422_to_rgb24( uint8_t *yuv, uint8_t *rgb, uint8_t *alpha, int width, int height ) +static void convert_yuv422_to_rgb( mlt_image src, mlt_image dst ) { - int ret = 0; int yy, uu, vv; int r,g,b; - int total = width * height / 2 + 1; - while ( --total ) + mlt_image_set_values( dst, NULL, mlt_image_rgb, src->width, src->height ); + mlt_image_alloc_data( dst ); + + for ( int line = 0; line < src->height; line++ ) { - yy = yuv[0]; - uu = yuv[1]; - vv = yuv[3]; - YUV2RGB_601( yy, uu, vv, r, g, b ); - rgb[0] = r; - rgb[1] = g; - rgb[2] = b; - yy = yuv[2]; - YUV2RGB_601( yy, uu, vv, r, g, b ); - rgb[3] = r; - rgb[4] = g; - rgb[5] = b; - yuv += 4; - rgb += 6; + uint8_t* pSrc = src->planes[0] + src->strides[0] * line; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + int total = src->width / 2 + 1; + while ( --total ) + { + yy = pSrc[0]; + uu = pSrc[1]; + vv = pSrc[3]; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[0] = r; + pDst[1] = g; + pDst[2] = b; + yy = pSrc[2]; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[3] = r; + pDst[4] = g; + pDst[5] = b; + pSrc += 4; + pDst += 6; + } } - return ret; } -static int convert_rgb24a_to_yuv422( uint8_t *rgba, uint8_t *yuv, uint8_t *alpha, int width, int height ) +static void convert_rgba_to_yuv422( mlt_image src, mlt_image dst ) { - int ret = 0; - int stride = width * 4; int y0, y1, u0, u1, v0, v1; int r, g, b; - uint8_t *s, *d = yuv; - int i, j, n = width / 2 + 1; - if ( alpha ) - for ( i = 0; i < height; i++ ) + mlt_image_set_values( dst, NULL, mlt_image_yuv422, src->width, src->height ); + mlt_image_alloc_data( dst ); + mlt_image_alloc_alpha( dst ); + + for ( int line = 0; line < src->height; line++ ) { - s = rgba + ( stride * i ); - j = n; + uint8_t* pSrc = src->planes[0] + src->strides[0] * line; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + uint8_t* pAlpha = dst->planes[3] + dst->strides[3] * line; + int j = src->width / 2 + 1; while ( --j ) { - r = *s++; - g = *s++; - b = *s++; - *alpha++ = *s++; + r = *pSrc++; + g = *pSrc++; + b = *pSrc++; + *pAlpha++ = *pSrc++; RGB2YUV_601( r, g, b, y0, u0 , v0 ); - r = *s++; - g = *s++; - b = *s++; - *alpha++ = *s++; + r = *pSrc++; + g = *pSrc++; + b = *pSrc++; + *pAlpha++ = *pSrc++; RGB2YUV_601( r, g, b, y1, u1 , v1 ); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; + *pDst++ = y0; + *pDst++ = (u0+u1) >> 1; + *pDst++ = y1; + *pDst++ = (v0+v1) >> 1; } - if ( width % 2 ) + if ( src->width % 2 ) { - r = *s++; - g = *s++; - b = *s++; - *alpha++ = *s++; + r = *pSrc++; + g = *pSrc++; + b = *pSrc++; + *pAlpha++ = *pSrc++; RGB2YUV_601( r, g, b, y0, u0 , v0 ); - *d++ = y0; - *d++ = u0; + *pDst++ = y0; + *pDst++ = u0; } } - else - for ( i = 0; i < height; i++ ) +} + +static void convert_rgb_to_yuv422( mlt_image src, mlt_image dst ) +{ + int y0, y1, u0, u1, v0, v1; + int r, g, b; + + mlt_image_set_values( dst, NULL, mlt_image_yuv422, src->width, src->height ); + mlt_image_alloc_data( dst ); + + for ( int line = 0; line < src->height; line++ ) { - s = rgba + ( stride * i ); - j = n; + uint8_t* pSrc = src->planes[0] + src->strides[0] * line; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + int j = src->width / 2 + 1; while ( --j ) { - r = *s++; - g = *s++; - b = *s++; - s++; + r = *pSrc++; + g = *pSrc++; + b = *pSrc++; RGB2YUV_601( r, g, b, y0, u0 , v0 ); - r = *s++; - g = *s++; - b = *s++; - s++; + r = *pSrc++; + g = *pSrc++; + b = *pSrc++; RGB2YUV_601( r, g, b, y1, u1 , v1 ); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; + *pDst++ = y0; + *pDst++ = (u0+u1) >> 1; + *pDst++ = y1; + *pDst++ = (v0+v1) >> 1; } - if ( width % 2 ) + if ( src->width % 2 ) { - r = *s++; - g = *s++; - b = *s++; - s++; + r = *pSrc++; + g = *pSrc++; + b = *pSrc++; RGB2YUV_601( r, g, b, y0, u0 , v0 ); - *d++ = y0; - *d++ = u0; + *pDst++ = y0; + *pDst++ = u0; } } - - return ret; } -static int convert_rgb24_to_yuv422( uint8_t *rgb, uint8_t *yuv, uint8_t *alpha, int width, int height ) +static void convert_yuv420p_to_yuv422( mlt_image src, mlt_image dst ) { - int ret = 0; - int stride = width * 3; - int y0, y1, u0, u1, v0, v1; - int r, g, b; - uint8_t *s, *d = yuv; - int i, j, n = width / 2 + 1; + mlt_image_set_values( dst, NULL, mlt_image_yuv422, src->width, src->height ); + mlt_image_alloc_data( dst ); - for ( i = 0; i < height; i++ ) + for ( int line = 0; line < src->height; line++ ) { - s = rgb + ( stride * i ); - j = n; + uint8_t* pSrcY = src->planes[0] + src->strides[0] * line; + uint8_t* pSrcU = src->planes[1] + src->strides[1] * line / 2; + uint8_t* pSrcV = src->planes[2] + src->strides[2] * line / 2; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + int j = src->width / 2 + 1; while ( --j ) { - r = *s++; - g = *s++; - b = *s++; - RGB2YUV_601( r, g, b, y0, u0 , v0 ); - r = *s++; - g = *s++; - b = *s++; - RGB2YUV_601( r, g, b, y1, u1 , v1 ); - *d++ = y0; - *d++ = (u0+u1) >> 1; - *d++ = y1; - *d++ = (v0+v1) >> 1; + *pDst++ = *pSrcY++; + *pDst++ = *pSrcU++; + *pDst++ = *pSrcY++; + *pDst++ = *pSrcV++; } - if ( width % 2 ) + } +} + +static void convert_yuv420p_to_rgb( mlt_image src, mlt_image dst ) +{ + int yy, uu, vv; + int r,g,b; + + mlt_image_set_values( dst, NULL, mlt_image_rgb, src->width, src->height ); + mlt_image_alloc_data( dst ); + + for ( int line = 0; line < src->height; line++ ) + { + uint8_t* pSrcY = src->planes[0] + src->strides[0] * line; + uint8_t* pSrcU = src->planes[1] + src->strides[1] * line / 2; + uint8_t* pSrcV = src->planes[2] + src->strides[2] * line / 2; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + int total = src->width / 2 + 1; + while ( --total ) { - r = *s++; - g = *s++; - b = *s++; - RGB2YUV_601( r, g, b, y0, u0 , v0 ); - *d++ = y0; - *d++ = u0; + yy = *pSrcY++; + uu = *pSrcU++; + vv = *pSrcV++; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[0] = r; + pDst[1] = g; + pDst[2] = b; + yy = *pSrcY++; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[3] = r; + pDst[4] = g; + pDst[5] = b; + pDst += 6; } } - return ret; } -static int convert_yuv420p_to_yuv422( uint8_t *yuv420p, uint8_t *yuv, uint8_t *alpha, int width, int height ) +static void convert_yuv420p_to_rgba( mlt_image src, mlt_image dst ) { - int ret = 0; - int i, j; - int half = width >> 1; - uint8_t *Y = yuv420p; - uint8_t *U = Y + width * height; - uint8_t *V = U + width * height / 4; - uint8_t *d = yuv; - - for ( i = 0; i < height; i++ ) + int yy, uu, vv; + int r,g,b; + + mlt_image_set_values( dst, NULL, mlt_image_rgba, src->width, src->height ); + mlt_image_alloc_data( dst ); + + for ( int line = 0; line < src->height; line++ ) { - uint8_t *u = U + ( i / 2 ) * ( half ); - uint8_t *v = V + ( i / 2 ) * ( half ); + uint8_t* pSrcY = src->planes[0] + src->strides[0] * line; + uint8_t* pSrcU = src->planes[1] + src->strides[1] * line / 2; + uint8_t* pSrcV = src->planes[2] + src->strides[2] * line / 2; + uint8_t* pSrcA = src->planes[3] + src->strides[3] * line; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + int total = src->width / 2 + 1; + if ( pSrcA ) + while ( --total ) + { + yy = *pSrcY++; + uu = *pSrcU++; + vv = *pSrcV++; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[0] = r; + pDst[1] = g; + pDst[2] = b; + pDst[3] = *pSrcA++; + yy = *pSrcY++; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[4] = r; + pDst[5] = g; + pDst[6] = b; + pDst[7] = *pSrcA++; + pDst += 8; + } + else + while ( --total ) + { + yy = *pSrcY++; + uu = *pSrcU++; + vv = *pSrcV++; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[0] = r; + pDst[1] = g; + pDst[2] = b; + pDst[3] = 0xff; + yy = *pSrcY++; + YUV2RGB_601( yy, uu, vv, r, g, b ); + pDst[4] = r; + pDst[5] = g; + pDst[6] = b; + pDst[7] = 0xff; + pDst += 8; + } + } +} - j = half + 1; - while ( --j ) +static void convert_yuv422_to_yuv420p( mlt_image src, mlt_image dst ) +{ + int lines = src->height; + int pixels = src->width; + + mlt_image_set_values( dst, NULL, mlt_image_yuv420p, src->width, src->height ); + mlt_image_alloc_data( dst ); + + // Y + for ( int line = 0; line < lines; line++ ) + { + uint8_t* pSrc = src->planes[0] + src->strides[0] * line; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + for ( int pixel = 0; pixel < pixels; pixel++ ) { - *d ++ = *Y ++; - *d ++ = *u ++; - *d ++ = *Y ++; - *d ++ = *v ++; + *pDst++ = *pSrc; + pSrc += 2; + } + } + + lines = src->height / 2; + pixels = src->width / 2; + + // U + for ( int line = 0; line < lines; line++ ) + { + uint8_t* pSrc = src->planes[0] + src->strides[0] * line * 2 + 1; + uint8_t* pDst = dst->planes[1] + dst->strides[1] * line; + for ( int pixel = 0; pixel < pixels; pixel++ ) + { + *pDst++ = *pSrc; + pSrc += 4; + } + } + + // V + for ( int line = 0; line < lines; line++ ) + { + uint8_t* pSrc = src->planes[0] + src->strides[0] * line * 2 + 3; + uint8_t* pDst = dst->planes[2] + dst->strides[2] * line; + for ( int pixel = 0; pixel < pixels; pixel++ ) + { + *pDst++ = *pSrc; + pSrc += 4; } } - return ret; } -static int convert_rgb24_to_rgb24a( uint8_t *rgb, uint8_t *rgba, uint8_t *alpha, int width, int height ) +static void convert_rgb_to_rgba( mlt_image src, mlt_image dst ) { - uint8_t *s = rgb; - uint8_t *d = rgba; - int total = width * height + 1; + mlt_image_set_values( dst, NULL, mlt_image_rgba, src->width, src->height ); + mlt_image_alloc_data( dst ); - while ( --total ) + for ( int line = 0; line < src->height; line++ ) { - *d++ = s[0]; - *d++ = s[1]; - *d++ = s[2]; - *d++ = 0xff; - s += 3; + uint8_t* pSrc = src->planes[0] + src->strides[0] * line; + uint8_t* pAlpha = src->planes[3] + src->strides[3] * line; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + int total = src->width + 1; + if ( pAlpha ) + while ( --total ) + { + *pDst++ = pSrc[0]; + *pDst++ = pSrc[1]; + *pDst++ = pSrc[2]; + *pDst++ = *pAlpha++; + pSrc += 3; + } + else + while ( --total ) + { + *pDst++ = pSrc[0]; + *pDst++ = pSrc[1]; + *pDst++ = pSrc[2]; + *pDst++ = 0xff; + pSrc += 3; + } } - return 0; } -static int convert_rgb24a_to_rgb24( uint8_t *rgba, uint8_t *rgb, uint8_t *alpha, int width, int height ) +static void convert_rgba_to_rgb( mlt_image src, mlt_image dst ) { - uint8_t *s = rgba; - uint8_t *d = rgb; - int total = width * height + 1; + mlt_image_set_values( dst, NULL, mlt_image_rgb, src->width, src->height ); + mlt_image_alloc_data( dst ); + mlt_image_alloc_alpha( dst ); - while ( --total ) + for ( int line = 0; line < src->height; line++ ) { - *d++ = s[0]; - *d++ = s[1]; - *d++ = s[2]; - *alpha++ = s[3]; - s += 4; + uint8_t* pSrc = src->planes[0] + src->strides[0] * line; + uint8_t* pDst = dst->planes[0] + dst->strides[0] * line; + uint8_t* pAlpha = dst->planes[3] + dst->strides[3] * line; + int total = src->width + 1; + while ( --total ) + { + *pDst++ = pSrc[0]; + *pDst++ = pSrc[1]; + *pDst++ = pSrc[2]; + *pAlpha++ = pSrc[3]; + pSrc += 4; + } } - return 0; } -typedef int ( *conversion_function )( uint8_t *yuv, uint8_t *rgba, uint8_t *alpha, int width, int height ); +typedef void ( *conversion_function )( mlt_image src, mlt_image dst ); static conversion_function conversion_matrix[ mlt_image_invalid - 1 ][ mlt_image_invalid - 1 ] = { - { NULL, convert_rgb24_to_rgb24a, convert_rgb24_to_yuv422, NULL, convert_rgb24_to_rgb24a, NULL }, - { convert_rgb24a_to_rgb24, NULL, convert_rgb24a_to_yuv422, NULL, NULL, NULL }, - { convert_yuv422_to_rgb24, convert_yuv422_to_rgb24a, NULL, NULL, convert_yuv422_to_rgb24a, NULL }, - { NULL, NULL, convert_yuv420p_to_yuv422, NULL, NULL, NULL }, - { convert_rgb24a_to_rgb24, NULL, convert_rgb24a_to_yuv422, NULL, NULL, NULL }, - { NULL, NULL, NULL, NULL, NULL, NULL }, + { NULL, convert_rgb_to_rgba, convert_rgb_to_yuv422, NULL, NULL, NULL, NULL }, + { convert_rgba_to_rgb, NULL, convert_rgba_to_yuv422, NULL, NULL, NULL, NULL }, + { convert_yuv422_to_rgb, convert_yuv422_to_rgba, NULL, convert_yuv422_to_yuv420p, NULL, NULL, NULL }, + { convert_yuv420p_to_rgb, convert_yuv420p_to_rgba, convert_yuv420p_to_yuv422, NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, + { NULL, NULL, NULL, NULL, NULL, NULL, NULL }, }; -static uint8_t bpp_table[4] = { 3, 4, 2, 0 }; - static int convert_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, mlt_image_format requested_format ) { int error = 0; @@ -320,36 +475,26 @@ static int convert_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *f width, height ); if ( converter ) { - int size = width * height * bpp_table[ requested_format - 1 ]; - int alpha_size = width * height; - uint8_t *image = mlt_pool_alloc( size ); - uint8_t *alpha = ( *format == mlt_image_rgba ) - ? mlt_pool_alloc( width * height ) : NULL; + struct mlt_image_s src; + struct mlt_image_s dst; + mlt_image_set_values( &src, *buffer, *format, width, height ); + converter( &src, &dst ); + mlt_frame_set_image( frame, dst.data, 0, dst.release_data ); if ( requested_format == mlt_image_rgba ) { - if ( alpha ) - mlt_pool_release( alpha ); - alpha = mlt_frame_get_alpha_mask( frame ); - mlt_properties_get_data( properties, "alpha", &alpha_size ); - } - - if ( !( error = converter( *buffer, image, alpha, width, height ) ) ) - { - mlt_frame_set_image( frame, image, size, mlt_pool_release ); - if ( alpha && *format == mlt_image_rgba ) - mlt_frame_set_alpha( frame, alpha, alpha_size, mlt_pool_release ); - *buffer = image; - *format = requested_format; + // Clear the alpha buffer on the frame + mlt_frame_set_alpha( frame, NULL, 0, NULL ); } - else + else if ( dst.alpha ) { - mlt_pool_release( image ); - if ( alpha ) - mlt_pool_release( alpha ); + mlt_frame_set_alpha( frame, dst.alpha, 0, dst.release_alpha ); } + *buffer = dst.data; + *format = dst.format; } else { + mlt_log_error( NULL, "imageconvert: no conversion from %s to %s\n", mlt_image_format_name(*format), mlt_image_format_name(requested_format)); error = 1; } } From b910bb9465c2d0b5a404cb9528f9df9e457354b1 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 21 Mar 2021 20:02:05 -0500 Subject: [PATCH 089/122] Fix regression in filter_avfilter This filter used a workaround for the "height + 1" bug. ae9b7de516627ab660756a8de1c58df5a8e38c54 removed the bug. This commit removes the workaround so the filter works properly again. --- src/modules/avformat/filter_avfilter.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/avformat/filter_avfilter.c b/src/modules/avformat/filter_avfilter.c index dc097e163..12d37936f 100644 --- a/src/modules/avformat/filter_avfilter.c +++ b/src/modules/avformat/filter_avfilter.c @@ -757,7 +757,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format int i; uint8_t* src = *image; uint8_t* dst = pdata->avinframe->data[0]; - int stride = mlt_image_format_size( *format, *width, 0, NULL ); + int stride = mlt_image_format_size( *format, *width, 1, NULL ); for( i = 0; i < *height; i ++ ) { memcpy( dst, src, stride ); @@ -808,7 +808,7 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format int i; uint8_t* dst = *image; uint8_t* src = pdata->avoutframe->data[0]; - int stride = mlt_image_format_size( *format, *width, 0, NULL ); + int stride = mlt_image_format_size( *format, *width, 1, NULL ); for( i = 0; i < *height; i ++ ) { memcpy( dst, src, stride ); From 64081536bce4db8c477a65f53e984adc922c223d Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 21 Mar 2021 20:31:44 -0500 Subject: [PATCH 090/122] Fix alpha pass-through in imageconvert --- src/modules/core/filter_imageconvert.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/modules/core/filter_imageconvert.c b/src/modules/core/filter_imageconvert.c index 1f836e86d..d3ba700bf 100644 --- a/src/modules/core/filter_imageconvert.c +++ b/src/modules/core/filter_imageconvert.c @@ -478,6 +478,14 @@ static int convert_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *f struct mlt_image_s src; struct mlt_image_s dst; mlt_image_set_values( &src, *buffer, *format, width, height ); + if ( requested_format == mlt_image_rgba && mlt_frame_get_alpha( frame ) ) + { + // imageconvert leaves the alpha buffer alone except in the case of rgba. + // For rgba input, an alpha buffer will be created and added to the frame. + // For rgba output, the alpha buffer will be copied to the rgba and the buffer is removed from the frame. + src.planes[3] = mlt_frame_get_alpha( frame ); + src.strides[3] = src.width; + } converter( &src, &dst ); mlt_frame_set_image( frame, dst.data, 0, dst.release_data ); if ( requested_format == mlt_image_rgba ) From 8def31757ab98290d6b95280556a43d9a322e875 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 21 Mar 2021 22:29:34 -0500 Subject: [PATCH 091/122] Refactor filter_mirror * Remove use of deprecated function mlt_frame_get_alpha_mask() * Use mkt_image class --- src/modules/core/filter_mirror.c | 243 +++++++++++++++++-------------- 1 file changed, 137 insertions(+), 106 deletions(-) diff --git a/src/modules/core/filter_mirror.c b/src/modules/core/filter_mirror.c index 04b94a414..90a534d5e 100644 --- a/src/modules/core/filter_mirror.c +++ b/src/modules/core/filter_mirror.c @@ -1,6 +1,6 @@ /* * filter_mirror.c -- mirror filter - * Copyright (C) 2003-2014 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -29,6 +30,9 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable ) { + struct mlt_image_s img; + int i; + // Pop the mirror filter from the stack mlt_filter filter = mlt_frame_pop_service( frame ); @@ -45,29 +49,23 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format = mlt_image_yuv422; int error = mlt_frame_get_image( frame, image, format, width, height, 1 ); - // Get the alpha - uint8_t *alpha = mlt_frame_get_alpha_mask( frame ); - // If we have an image of the right colour space - if ( error == 0 ) + if ( error == 0 && *format == mlt_image_yuv422 ) { - // We'll KISS here - int hh = *height / 2; + mlt_image_set_values( &img, *image, *format, *width, *height ); + if ( mlt_frame_get_alpha( frame ) ) + { + img.planes[3] = mlt_frame_get_alpha( frame ); + img.strides[3] = img.width; + } if ( !strcmp( mirror, "horizontal" ) ) { - uint8_t *p = NULL; - uint8_t *q = NULL; - uint8_t *a = NULL; - uint8_t *b = NULL; - int i; - int uneven_w = ( *width % 2 ) * 2; - for ( i = 0; i < *height; i ++ ) + int uneven_w = ( img.width % 2 ) * 2; + for ( i = 0; i < img.height; i ++ ) { - p = ( uint8_t * )*image + i * *width * 2; - q = p + *width * 2; - a = alpha + i * *width; - b = a + *width - 1; + uint8_t* p = img.planes[0] + img.strides[0] * i; + uint8_t* q = p + img.width * 2; if ( !reverse ) { while ( p < q ) @@ -77,8 +75,6 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *p ++ = *( q - 4 ); *p ++ = *( q - 1 - uneven_w ); q -= 4; - *a ++ = *b --; - *a ++ = *b --; } } else @@ -90,34 +86,48 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *( q - 4 ) = *p ++; *( q - 1 - uneven_w ) = *p ++; q -= 4; - *b -- = *a ++; - *b -- = *a ++; } } } + if ( img.planes[3] ) + { + for ( i = 0; i < img.height; i ++ ) + { + uint8_t* a = img.planes[3] + img.strides[3] * i; + uint8_t* b = a + img.width - 1; + if ( !reverse ) + { + while ( a < b ) + { + *a ++ = *b --; + *a ++ = *b --; + } + } + else + { + while ( a < b ) + { + *b -- = *a ++; + *b -- = *a ++; + } + } + } + } + } else if ( !strcmp( mirror, "vertical" ) ) { - uint16_t *end = ( uint16_t *)*image + *width * *height; - uint16_t *p = NULL; - uint16_t *q = NULL; - uint8_t *a = NULL; - uint8_t *b = NULL; - int i; - int j; + int hh = img.height / 2; for ( i = 0; i < hh; i ++ ) { - p = ( uint16_t * )*image + i * *width; - q = end - ( i + 1 ) * *width; - j = *width; - a = alpha + i * *width; - b = alpha + ( *height - i - 1 ) * *width; + uint16_t* p = (uint16_t*)(img.planes[0] + (img.strides[0] * i)); + uint16_t* q = (uint16_t*)(img.planes[0] + (img.strides[0] * (img.height - i - 1))); + int j = img.width; if ( !reverse ) { while ( j -- ) { *p ++ = *q ++; - *a ++ = *b ++; } } else @@ -125,28 +135,30 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format while ( j -- ) { *q ++ = *p ++; - *b ++ = *a ++; } } } + if ( img.planes[3] ) + { + int j = img.width; + uint8_t* a = img.planes[3] + (img.strides[3] * i); + uint8_t* b = img.planes[3] + (img.strides[3] * (img.height - i - 1)); + if ( !reverse ) + while ( j -- ) + *a ++ = *b ++; + else + while ( j -- ) + *b ++ = *a ++; + } } else if ( !strcmp( mirror, "diagonal" ) ) { - uint8_t *end = ( uint8_t *)*image + *width * *height * 2; - uint8_t *p = NULL; - uint8_t *q = NULL; - uint8_t *a = NULL; - uint8_t *b = NULL; - int i; - int j; - int uneven_w = ( *width % 2 ) * 2; - for ( i = 0; i < *height; i ++ ) + int uneven_w = ( img.width % 2 ) * 2; + for ( i = 0; i < img.height; i ++ ) { - p = ( uint8_t * )*image + i * *width * 2; - q = end - i * *width * 2; - j = ( ( *width * ( *height - i ) ) / *height ) / 2; - a = alpha + i * *width; - b = alpha + ( *height - i - 1 ) * *width; + uint8_t* p = img.planes[0] + (img.strides[0] * i); + uint8_t* q = img.planes[0] + (img.strides[0] * (img.height - i - 1)); + int j = ( ( img.width * ( img.height - i ) ) / img.height ) / 2; if ( !reverse ) { while ( j -- ) @@ -156,8 +168,6 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *p ++ = *( q - 4 ); *p ++ = *( q - 1 - uneven_w ); q -= 4; - *a ++ = *b --; - *a ++ = *b --; } } else @@ -169,29 +179,34 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *( q - 4 ) = *p ++; *( q - 1 - uneven_w ) = *p ++; q -= 4; - *b -- = *a ++; - *b -- = *a ++; } } } + if ( img.planes[3] ) + { + int i; + for ( i = 0; i < img.height; i ++ ) + { + int j = ( img.width * ( img.height - i ) ) / img.height; + uint8_t* a = img.planes[3] + (img.strides[3] * i); + uint8_t* b = img.planes[3] + (img.strides[3] * (img.height - i - 1)); + if ( !reverse ) + while ( j -- ) + *a ++ = *b --; + else + while ( j -- ) + *b -- = *a ++; + } + } } else if ( !strcmp( mirror, "xdiagonal" ) ) { - uint8_t *end = ( uint8_t *)*image + *width * *height * 2; - uint8_t *p = NULL; - uint8_t *q = NULL; - int i; - int j; - uint8_t *a = NULL; - uint8_t *b = NULL; - int uneven_w = ( *width % 2 ) * 2; - for ( i = 0; i < *height; i ++ ) + int uneven_w = ( img.width % 2 ) * 2; + for ( i = 0; i < img.height; i ++ ) { - p = ( uint8_t * )*image + ( i + 1 ) * *width * 2; - q = end - ( i + 1 ) * *width * 2; - j = ( ( *width * ( *height - i ) ) / *height ) / 2; - a = alpha + ( i + 1 ) * *width - 1; - b = alpha + ( *height - i - 1 ) * *width; + uint8_t* p = img.planes[0] + (img.strides[0] * (i + 1)); + uint8_t* q = img.planes[0] + (img.strides[0] * (img.height - i)); + int j = ( ( img.width * ( img.height - i ) ) / img.height ) / 2; if ( !reverse ) { while ( j -- ) @@ -201,8 +216,6 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *q ++ = *( p - 4 ); *q ++ = *( p - 1 - uneven_w ); p -= 4; - *b ++ = *a --; - *b ++ = *a --; } } else @@ -214,28 +227,34 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *( p - 4 ) = *q ++; *( p - 1 - uneven_w ) = *q ++; p -= 4; - *a -- = *b ++; - *a -- = *b ++; } } } + if ( img.planes[3] ) + { + int i; + for ( i = 0; i < img.height; i ++ ) + { + int j = ( ( img.width * ( img.height - i ) ) / img.height ); + uint8_t* a = img.planes[3] + (img.strides[3] * i) + img.width - 1; + uint8_t* b = img.planes[3] + (img.strides[3] * (img.height - i - 1)); + if ( !reverse ) + while ( j -- ) + *b ++ = *a --; + else + while ( j -- ) + *a -- = *b ++; + } + } } else if ( !strcmp( mirror, "flip" ) ) { uint8_t t[ 4 ]; - uint8_t *p = NULL; - uint8_t *q = NULL; - int i; - uint8_t *a = NULL; - uint8_t *b = NULL; - uint8_t c; - int uneven_w = ( *width % 2 ) * 2; - for ( i = 0; i < *height; i ++ ) + int uneven_w = ( img.width % 2 ) * 2; + for ( i = 0; i < img.height; i ++ ) { - p = ( uint8_t * )*image + i * *width * 2; - q = p + *width * 2; - a = alpha + i * *width; - b = a + *width - 1; + uint8_t* p = img.planes[0] + (img.strides[0] * i); + uint8_t* q = p + *width * 2; while ( p < q ) { t[ 0 ] = p[ 0 ]; @@ -250,41 +269,53 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *( -- q ) = t[ 0 ]; *( -- q ) = t[ 1 ]; *( -- q ) = t[ 2 ]; - c = *a; - *a ++ = *b; - *b -- = c; - c = *a; - *a ++ = *b; - *b -- = c; + } + } + if ( img.planes[3] ) + { + uint8_t c; + for ( i = 0; i < img.height; i ++ ) + { + uint8_t* a = img.planes[3] + (img.strides[3] * i); + uint8_t* b = a + img.width - 1; + while ( a < b ) + { + c = *a; + *a ++ = *b; + *b -- = c; + } } } } else if ( !strcmp( mirror, "flop" ) ) { - uint16_t *end = ( uint16_t *)*image + *width * *height; - uint16_t *p = NULL; - uint16_t *q = NULL; uint16_t t; - uint8_t *a = NULL; - uint8_t *b = NULL; - uint8_t c; - int i; - int j; + int hh = *height / 2; for ( i = 0; i < hh; i ++ ) { - p = ( uint16_t * )*image + i * *width; - q = end - ( i + 1 ) * *width; - a = alpha + i * *width; - b = alpha + ( *height - i - 1 ) * *width; - j = *width; + uint16_t* p = (uint16_t*)(img.planes[0] + (img.strides[0] * i)); + uint16_t* q = (uint16_t*)(img.planes[0] + (img.strides[0] * (img.height - i - 1))); + int j = img.width; while ( j -- ) { t = *p; *p ++ = *q; *q ++ = t; - c = *a; - *a ++ = *b; - *b ++ = c; + } + } + if ( img.planes[3] ) + { + uint8_t c; + for ( i = 0; i < img.height; i ++ ) + { + uint8_t* a = img.planes[3] + (img.strides[3] * i); + uint8_t* b = img.planes[3] + (img.strides[3] * (img.height - i - 1)); + while ( a < b ) + { + c = *a; + *a ++ = *b; + *b -- = c; + } } } } From b5aef95c213ccb41854071b08180c8967936b4e7 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Mon, 22 Mar 2021 18:08:21 -0700 Subject: [PATCH 092/122] document as private these formerly public functions --- src/framework/mlt_slices.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/framework/mlt_slices.c b/src/framework/mlt_slices.c index a2e5727cf..77e3cc101 100644 --- a/src/framework/mlt_slices.c +++ b/src/framework/mlt_slices.c @@ -135,7 +135,7 @@ static void* mlt_slices_worker( void* p ) /** Initialize a sliced threading context * - * \public \memberof mlt_slices_s + * \private \memberof mlt_slices_s * \param threads number of threads to use for job list, 0 for #cpus * \param policy scheduling policy of processing threads, -1 for normal * \param priority priority value that can be used with the scheduling algorithm, -1 for maximum @@ -218,7 +218,7 @@ static mlt_slices mlt_slices_init( int threads, int policy, int priority ) /** Destroy sliced threading context * - * \public \memberof mlt_slices_s + * \private \memberof mlt_slices_s * \param ctx context pointer */ @@ -262,7 +262,7 @@ static void mlt_slices_close( mlt_slices ctx ) /** Run sliced execution * - * \public \memberof mlt_slices_s + * \private \memberof mlt_slices_s * \param ctx context pointer * \param jobs number of jobs to process * \param proc number of jobs to process From 34f57ccc1a843c8f55c520e83929216f5737ff9a Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 22 Mar 2021 19:49:53 -0500 Subject: [PATCH 093/122] Remove use of deprecated mlt_frame_get_alpha_mask from watermark --- src/modules/core/filter_watermark.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/modules/core/filter_watermark.c b/src/modules/core/filter_watermark.c index 270e30a9e..77c758cda 100644 --- a/src/modules/core/filter_watermark.c +++ b/src/modules/core/filter_watermark.c @@ -195,9 +195,10 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_properties_set( b_props, "rescale.interp", rescale ); mlt_service_apply_filters( MLT_FILTER_SERVICE( filter ), b_frame, 0 ); error = mlt_frame_get_image( b_frame, image, format, width, height, 1 ); - alpha = mlt_frame_get_alpha_mask( b_frame ); + alpha = mlt_frame_get_alpha( b_frame ); mlt_frame_set_image( frame, *image, *width * *height * 2, NULL ); - mlt_frame_set_alpha( frame, alpha, *width * *height, NULL ); + if ( alpha ) + mlt_frame_set_alpha( frame, alpha, *width * *height, NULL ); mlt_properties_set_int( a_props, "width", *width ); mlt_properties_set_int( a_props, "height", *height ); mlt_properties_set_int( a_props, "progressive", 1 ); From f720e411f0ded34cc9e788c7df3ae7c7ceac589b Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 22 Mar 2021 20:53:20 -0500 Subject: [PATCH 094/122] Remove use of deprecated mlt_frame_get_alpha_mask from luma --- src/modules/core/transition_luma.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/modules/core/transition_luma.c b/src/modules/core/transition_luma.c index f9facfa67..d11b710f2 100644 --- a/src/modules/core/transition_luma.c +++ b/src/modules/core/transition_luma.c @@ -118,9 +118,9 @@ static inline int dissolve_yuv( mlt_frame frame, mlt_frame that, float weight, i if ( mlt_properties_get( &frame->parent, "distort" ) ) mlt_properties_set( &that->parent, "distort", mlt_properties_get( &frame->parent, "distort" ) ); mlt_frame_get_image( frame, &p_dest, &format, &width, &height, 1 ); - alpha_dst = mlt_frame_get_alpha_mask( frame ); + alpha_dst = mlt_frame_get_alpha( frame ); mlt_frame_get_image( that, &p_src, &format, &width_src, &height_src, 0 ); - alpha_src = mlt_frame_get_alpha_mask( that ); + alpha_src = mlt_frame_get_alpha( that ); int is_translucent = ( alpha_dst && !is_opaque(alpha_dst, width, height) ) || ( alpha_src && !is_opaque(alpha_src, width_src, height_src) ); @@ -148,8 +148,8 @@ static inline int dissolve_yuv( mlt_frame frame, mlt_frame that, float weight, i composite_line_yuv( p_dest, p_src, width_src, alpha_src, alpha_dst, mix, NULL, 0, 0 ); p_src += width_src << 1; p_dest += width << 1; - alpha_src += width_src; - alpha_dst += width; + if ( alpha_src ) alpha_src += width_src; + if ( alpha_dst ) alpha_dst += width; } } @@ -205,9 +205,9 @@ static void luma_composite( mlt_frame a_frame, mlt_frame b_frame, int luma_width if ( mlt_properties_get( &a_frame->parent, "distort" ) ) mlt_properties_set( &b_frame->parent, "distort", mlt_properties_get( &a_frame->parent, "distort" ) ); mlt_frame_get_image( a_frame, &p_dest, &format_dest, &width_dest, &height_dest, 1 ); - alpha_dest = mlt_frame_get_alpha_mask( a_frame ); + alpha_dest = mlt_frame_get_alpha( a_frame ); mlt_frame_get_image( b_frame, &p_src, &format_src, &width_src, &height_src, 0 ); - alpha_src = mlt_frame_get_alpha_mask( b_frame ); + alpha_src = mlt_frame_get_alpha( b_frame ); if ( *width == 0 || *height == 0 ) return; From a0a7571f50036455ab9539fd2fc6e78481fe9f6e Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 22 Mar 2021 21:12:00 -0500 Subject: [PATCH 095/122] Remove use of deprecated mlt_frame_get_alpha_mask from matte --- src/modules/core/transition_matte.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/modules/core/transition_matte.c b/src/modules/core/transition_matte.c index 69c86a37d..187acfd7c 100644 --- a/src/modules/core/transition_matte.c +++ b/src/modules/core/transition_matte.c @@ -180,7 +180,14 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // Get the image from the a frame mlt_frame_get_image( b_frame, &image_b, format, &width_b, &height_b, 1 ); - alpha_a = mlt_frame_get_alpha_mask( a_frame ); + alpha_a = mlt_frame_get_alpha( a_frame ); + if ( !alpha_a ) + { + int size = width_a * height_a; + alpha_a = mlt_pool_alloc( size ); + memset( alpha_a, 255, size ); + mlt_frame_set_alpha( a_frame, alpha_a, size, mlt_pool_release ); + } // copy data copy_Y_to_A_scaled_luma From 66b2a775d7ec5289e45cdd5f985b3874e5b53eae Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 22 Mar 2021 21:51:04 -0500 Subject: [PATCH 096/122] Fix whitespace in producer_framebuffer --- src/modules/kdenlive/producer_framebuffer.c | 79 +++++++++++---------- 1 file changed, 40 insertions(+), 39 deletions(-) diff --git a/src/modules/kdenlive/producer_framebuffer.c b/src/modules/kdenlive/producer_framebuffer.c index 90ce589a8..02c59d944 100644 --- a/src/modules/kdenlive/producer_framebuffer.c +++ b/src/modules/kdenlive/producer_framebuffer.c @@ -1,6 +1,7 @@ /* * producer_framebuffer.c -- create subspeed frames * Copyright (C) 2007 Jean-Baptiste Mardelle + * Copyright (C) 2021 Meltytech, LLC * Author: Jean-Baptiste Mardelle, based on the code of motion_est by Zachary Drew * * This library is free software; you can redistribute it and/or @@ -61,7 +62,7 @@ static int framebuffer_get_image( mlt_frame frame, uint8_t **image, mlt_image_fo if ( !freeze || freeze_after || freeze_before ) { double prod_speed = mlt_properties_get_double( properties, "_speed" ); - double actual_position = prod_speed * ( in + mlt_producer_position( producer ) ); + double actual_position = prod_speed * ( in + mlt_producer_position( producer ) ); if ( mlt_properties_get_int( properties, "reverse" ) ) actual_position = mlt_producer_get_playtime( producer ) - actual_position; @@ -95,9 +96,9 @@ static int framebuffer_get_image( mlt_frame frame, uint8_t **image, mlt_image_fo // Get output buffer int buffersize = 0; - int alphasize = *width * *height; + int alphasize = *width * *height; uint8_t *output = mlt_properties_get_data( properties, "output_buffer", &buffersize ); - uint8_t *output_alpha = mlt_properties_get_data( properties, "output_alpha", NULL ); + uint8_t *output_alpha = mlt_properties_get_data( properties, "output_alpha", NULL ); if( buffersize == 0 || buffersize != size ) { // invalidate cached frame @@ -116,15 +117,15 @@ static int framebuffer_get_image( mlt_frame frame, uint8_t **image, mlt_image_fo if ( output && first_position != -1 ) { // Using the cached frame - uint8_t *image_copy = mlt_pool_alloc( size ); + uint8_t *image_copy = mlt_pool_alloc( size ); memcpy( image_copy, output, size ); - uint8_t *alpha_copy = mlt_pool_alloc( alphasize ); - memcpy( alpha_copy, output_alpha, alphasize ); + uint8_t *alpha_copy = mlt_pool_alloc( alphasize ); + memcpy( alpha_copy, output_alpha, alphasize ); // Set the output image *image = image_copy; mlt_frame_set_image( frame, image_copy, size, mlt_pool_release ); - mlt_frame_set_alpha( frame, alpha_copy, alphasize, mlt_pool_release ); + mlt_frame_set_alpha( frame, alpha_copy, alphasize, mlt_pool_release ); *width = mlt_properties_get_int( properties, "_output_width" ); *height = mlt_properties_get_int( properties, "_output_height" ); @@ -154,7 +155,7 @@ static int framebuffer_get_image( mlt_frame frame, uint8_t **image, mlt_image_fo // Which frames are buffered? uint8_t *first_image = mlt_properties_get_data( first_frame_properties, "image", NULL ); - uint8_t *first_alpha = mlt_properties_get_data( first_frame_properties, "alpha", NULL ); + uint8_t *first_alpha = mlt_properties_get_data( first_frame_properties, "alpha", NULL ); if ( !first_image ) { mlt_properties_set( first_frame_properties, "rescale.interp", mlt_properties_get( frame_properties, "rescale.interp" ) ); @@ -177,21 +178,21 @@ static int framebuffer_get_image( mlt_frame frame, uint8_t **image, mlt_image_fo } if ( !first_alpha ) - { - alphasize = *width * *height; - first_alpha = mlt_frame_get_alpha_mask( first_frame ); - output_alpha = mlt_pool_alloc( alphasize ); - memcpy( output_alpha, first_alpha, alphasize ); - mlt_properties_set_data( properties, "output_alpha", output_alpha, alphasize, mlt_pool_release, NULL ); - } + { + alphasize = *width * *height; + first_alpha = mlt_frame_get_alpha_mask( first_frame ); + output_alpha = mlt_pool_alloc( alphasize ); + memcpy( output_alpha, first_alpha, alphasize ); + mlt_properties_set_data( properties, "output_alpha", output_alpha, alphasize, mlt_pool_release, NULL ); + } mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) ); // Create a copy uint8_t *image_copy = mlt_pool_alloc( size ); memcpy( image_copy, first_image, size ); - uint8_t *alpha_copy = mlt_pool_alloc( alphasize ); - memcpy( alpha_copy, first_alpha, alphasize ); + uint8_t *alpha_copy = mlt_pool_alloc( alphasize ); + memcpy( alpha_copy, first_alpha, alphasize ); // Set the output image *image = image_copy; @@ -221,32 +222,32 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i if ( first_frame == NULL ) { - // Get the frame to cache from the real producer - mlt_producer real_producer = mlt_properties_get_data( properties, "producer", NULL ); + // Get the frame to cache from the real producer + mlt_producer real_producer = mlt_properties_get_data( properties, "producer", NULL ); - // Get the producer speed - double prod_speed = mlt_properties_get_double( properties, "_speed" ); + // Get the producer speed + double prod_speed = mlt_properties_get_double( properties, "_speed" ); - // Seek the producer to the correct place - mlt_producer_seek( real_producer, mlt_producer_position( producer ) * prod_speed ); + // Seek the producer to the correct place + mlt_producer_seek( real_producer, mlt_producer_position( producer ) * prod_speed ); - // Get the frame - mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &first_frame, index ); + // Get the frame + mlt_service_get_frame( MLT_PRODUCER_SERVICE( real_producer ), &first_frame, index ); - // Cache the frame - mlt_properties_set_data( properties, "first_frame", first_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); + // Cache the frame + mlt_properties_set_data( properties, "first_frame", first_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); - // Find the original producer's format - int width = 0; - int height = 0; - mlt_image_format format = mlt_image_none; - uint8_t *image = NULL; - int error = mlt_frame_get_image( first_frame, &image, &format, &width, &height, 0 ); - if ( !error ) - { + // Find the original producer's format + int width = 0; + int height = 0; + mlt_image_format format = mlt_image_none; + uint8_t *image = NULL; + int error = mlt_frame_get_image( first_frame, &image, &format, &width, &height, 0 ); + if ( !error ) + { // cache the original producer's pixel format mlt_properties_set_int( properties, "_original_format", (int) format ); - } + } } mlt_properties_inherit( frame_properties, MLT_FRAME_PROPERTIES(first_frame) ); @@ -254,7 +255,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i double force_aspect_ratio = mlt_properties_get_double( properties, "force_aspect_ratio" ); if ( force_aspect_ratio <= 0.0 ) force_aspect_ratio = mlt_properties_get_double( properties, "aspect_ratio" ); mlt_properties_set_double( frame_properties, "aspect_ratio", force_aspect_ratio ); - + // Give the returned frame temporal identity mlt_frame_set_position( *frame, mlt_producer_position( producer ) ); @@ -288,10 +289,10 @@ mlt_producer producer_framebuffer_init( mlt_profile profile, mlt_service_type ty /** * Speed must be appended to the filename with '?'. To play your video at 50%: - melt framebuffer:my_video.mpg?0.5 + melt framebuffer:my_video.mpg?0.5 * Stroboscope effect can be obtained by adding a stobe=x parameter, where - x is the number of frames that will be ignored. + x is the number of frames that will be ignored. * You can play the movie backwards by adding reverse=1 From f5620516fa34cc26b79a938373445ef551a5b06c Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 22 Mar 2021 21:58:57 -0500 Subject: [PATCH 097/122] Remove use of deprecated mlt_frame_get_alpha_mask from framebuffer --- src/modules/kdenlive/producer_framebuffer.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/modules/kdenlive/producer_framebuffer.c b/src/modules/kdenlive/producer_framebuffer.c index 02c59d944..103b8fc7f 100644 --- a/src/modules/kdenlive/producer_framebuffer.c +++ b/src/modules/kdenlive/producer_framebuffer.c @@ -180,7 +180,13 @@ static int framebuffer_get_image( mlt_frame frame, uint8_t **image, mlt_image_fo if ( !first_alpha ) { alphasize = *width * *height; - first_alpha = mlt_frame_get_alpha_mask( first_frame ); + first_alpha = mlt_frame_get_alpha( first_frame ); + if ( !first_alpha ) + { + first_alpha = mlt_pool_alloc( alphasize ); + memset( first_alpha, 255, alphasize ); + mlt_frame_set_alpha( first_frame, first_alpha, alphasize, mlt_pool_release ); + } output_alpha = mlt_pool_alloc( alphasize ); memcpy( output_alpha, first_alpha, alphasize ); mlt_properties_set_data( properties, "output_alpha", output_alpha, alphasize, mlt_pool_release, NULL ); From d0907dce4027961f7c103ac807e4d59c086f3f8f Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 22 Mar 2021 22:09:36 -0500 Subject: [PATCH 098/122] Remove use of deprecated mlt_frame_get_alpha_mask from dust --- src/modules/oldfilm/filter_dust.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/modules/oldfilm/filter_dust.c b/src/modules/oldfilm/filter_dust.c index 138d09430..9d6e04d49 100644 --- a/src/modules/oldfilm/filter_dust.c +++ b/src/modules/oldfilm/filter_dust.c @@ -137,7 +137,14 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "best" );// none/nearest/tiles/hyper mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 ); - alpha = mlt_frame_get_alpha_mask (luma_frame ); + alpha = mlt_frame_get_alpha( luma_frame ); + if ( !alpha ) + { + int alphasize = luma_width * luma_height; + alpha = mlt_pool_alloc( alphasize ); + memset( alpha, 255, alphasize ); + mlt_frame_set_alpha( luma_frame, alpha, alphasize, mlt_pool_release ); + } uint8_t* savealpha = mlt_pool_alloc( luma_width * luma_height ); uint8_t* savepic = mlt_pool_alloc( luma_width * luma_height * 2); From 0584d8bed772e1c6d21914a79e08647e6b5bd7b9 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Mon, 22 Mar 2021 14:34:09 +0100 Subject: [PATCH 099/122] cmake: make jackrack build without jack --- CMakeLists.txt | 10 +++------- src/modules/jackrack/CMakeLists.txt | 27 +++++++++++++++------------ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index faa3ea3c2..c83501757 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -210,13 +210,9 @@ endif() if(MOD_JACKRACK) pkg_check_modules(jack IMPORTED_TARGET jack) - if(TARGET PkgConfig::jack) - pkg_check_modules(glib IMPORTED_TARGET glib-2.0) - check_include_file(ladspa.h ladspa_h_FOUND) - list(APPEND MLT_SUPPORTED_COMPONENTS jackrack) - else() - set(MOD_JACKRACK OFF) - endif() + pkg_check_modules(glib IMPORTED_TARGET glib-2.0) + check_include_file(ladspa.h ladspa_h_FOUND) + list(APPEND MLT_SUPPORTED_COMPONENTS jackrack) endif() if(MOD_KDENLIVE) diff --git a/src/modules/jackrack/CMakeLists.txt b/src/modules/jackrack/CMakeLists.txt index ddc78d8cf..78b715831 100644 --- a/src/modules/jackrack/CMakeLists.txt +++ b/src/modules/jackrack/CMakeLists.txt @@ -1,8 +1,15 @@ -add_library(mltjack MODULE consumer_jack.c factory.c) +add_library(mltjack MODULE factory.c) target_compile_options(mltjack PRIVATE ${MLT_COMPILE_OPTIONS}) -target_link_libraries(mltjack PRIVATE mlt Threads::Threads PkgConfig::jack) +target_link_libraries(mltjack PRIVATE mlt Threads::Threads) + +if(TARGET PkgConfig::jack) + target_sources(mltjack PRIVATE consumer_jack.c) + target_link_libraries(mltjack PRIVATE PkgConfig::jack) + target_compile_definitions(mltjack PRIVATE WITH_JACK) + install(FILES consumer_jack.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) +endif() if(GPL AND TARGET PkgConfig::xml AND TARGET PkgConfig::glib AND ladspa_h_FOUND) target_sources(mltjack PRIVATE @@ -14,22 +21,18 @@ if(GPL AND TARGET PkgConfig::xml AND TARGET PkgConfig::glib AND ladspa_h_FOUND) plugin_settings.c process.c producer_ladspa.c - filter_jackrack.c filter_ladspa.c ) target_link_libraries(mltjack PRIVATE ${CMAKE_DL_LIBS} m PkgConfig::xml PkgConfig::glib) target_compile_definitions(mltjack PRIVATE GPL) - install(FILES - filter_jackrack.yml - filter_jack.yml - filter_ladspa.yml - producer_ladspa.yml - DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack - ) + install(FILES filter_jack.yml filter_ladspa.yml producer_ladspa.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) + + if(TARGET PkgConfig::jack) + target_sources(mltjack PRIVATE filter_jackrack.c) + install(FILES filter_jackrack.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) + endif() endif() set_target_properties(mltjack PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") install(TARGETS mltjack LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) - -install(FILES consumer_jack.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) From e6414b2f87ff6bfaa79ee6e179b86ea1a39eb26e Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 23 Mar 2021 00:19:46 +0100 Subject: [PATCH 100/122] cmake: add --output-def linker option --- src/framework/CMakeLists.txt | 2 ++ src/mlt++/CMakeLists.txt | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index f89b6281c..38a20355d 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -90,6 +90,8 @@ if(WIN32) DESTINATION ${CMAKE_INSTALL_LIBDIR} RENAME libmlt.dll ) + target_link_options(mlt PRIVATE -Wl,--output-def,libmlt.def) + install(FILES "${CMAKE_BINARY_DIR}/libmlt.def" DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() target_sources(mlt PRIVATE ../win32/win32.c ../win32/strptime.c) target_link_libraries(mlt PRIVATE Iconv::Iconv) diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index 8dd0f5dd0..ec0f15c44 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -82,6 +82,8 @@ if(WIN32) DESTINATION ${CMAKE_INSTALL_LIBDIR} RENAME libmlt++.dll ) + target_link_options(mlt++ PRIVATE -Wl,--output-def,libmlt++.def) + install(FILES "${CMAKE_BINARY_DIR}/libmlt++.def" DESTINATION ${CMAKE_INSTALL_LIBDIR}) endif() target_compile_definitions(mlt++ PUBLIC MLTPP_EXPORTS) endif() From 0c7815db123bec291dbbc87cfdf6041e51884516 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 23 Mar 2021 00:24:15 +0100 Subject: [PATCH 101/122] cmake: create data output dir only once --- CMakeLists.txt | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c83501757..404f23bbb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,20 +65,22 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out/lib") set(MLT_MODULE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out/lib/mlt") set(MLT_DATA_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/out/share/mlt") -if(WIN32) # symlinks require admin rights on Windows - file(COPY "${CMAKE_SOURCE_DIR}/src/modules" DESTINATION "${CMAKE_BINARY_DIR}/out/share" FILES_MATCHING REGEX yml|txt) - file(RENAME "${CMAKE_BINARY_DIR}/out/share/modules" "${MLT_DATA_OUTPUT_DIRECTORY}") - file(COPY "${CMAKE_SOURCE_DIR}/presets" DESTINATION "${MLT_DATA_OUTPUT_DIRECTORY}") - file(COPY "${CMAKE_SOURCE_DIR}/profiles" DESTINATION "${MLT_DATA_OUTPUT_DIRECTORY}") -else() - file(MAKE_DIRECTORY "${MLT_DATA_OUTPUT_DIRECTORY}") - file(GLOB MOD_SUBDIRS "${CMAKE_SOURCE_DIR}/src/modules/*") - foreach(MOD_SUBDIR ${MOD_SUBDIRS}) - file(RELATIVE_PATH MOD_NAME "${CMAKE_SOURCE_DIR}/src/modules" ${MOD_SUBDIR}) - file(CREATE_LINK "${CMAKE_SOURCE_DIR}/src/modules/${MOD_NAME}" "${MLT_DATA_OUTPUT_DIRECTORY}/${MOD_NAME}" SYMBOLIC) - endforeach() - file(CREATE_LINK "${CMAKE_SOURCE_DIR}/presets" "${MLT_DATA_OUTPUT_DIRECTORY}/presets" SYMBOLIC) - file(CREATE_LINK "${CMAKE_SOURCE_DIR}/profiles" "${MLT_DATA_OUTPUT_DIRECTORY}/profiles" SYMBOLIC) +if(NOT EXISTS ${MLT_DATA_OUTPUT_DIRECTORY}) + if(WIN32) # symlinks require admin rights on Windows + file(COPY "${CMAKE_SOURCE_DIR}/src/modules" DESTINATION "${CMAKE_BINARY_DIR}/out/share" FILES_MATCHING REGEX yml|txt) + file(RENAME "${CMAKE_BINARY_DIR}/out/share/modules" "${MLT_DATA_OUTPUT_DIRECTORY}") + file(COPY "${CMAKE_SOURCE_DIR}/presets" DESTINATION "${MLT_DATA_OUTPUT_DIRECTORY}") + file(COPY "${CMAKE_SOURCE_DIR}/profiles" DESTINATION "${MLT_DATA_OUTPUT_DIRECTORY}") + else() + file(MAKE_DIRECTORY "${MLT_DATA_OUTPUT_DIRECTORY}") + file(GLOB MOD_SUBDIRS "${CMAKE_SOURCE_DIR}/src/modules/*") + foreach(MOD_SUBDIR ${MOD_SUBDIRS}) + file(RELATIVE_PATH MOD_NAME "${CMAKE_SOURCE_DIR}/src/modules" ${MOD_SUBDIR}) + file(CREATE_LINK "${CMAKE_SOURCE_DIR}/src/modules/${MOD_NAME}" "${MLT_DATA_OUTPUT_DIRECTORY}/${MOD_NAME}" SYMBOLIC) + endforeach() + file(CREATE_LINK "${CMAKE_SOURCE_DIR}/presets" "${MLT_DATA_OUTPUT_DIRECTORY}/presets" SYMBOLIC) + file(CREATE_LINK "${CMAKE_SOURCE_DIR}/profiles" "${MLT_DATA_OUTPUT_DIRECTORY}/profiles" SYMBOLIC) + endif() endif() set(MLT_INSTALL_MODULE_DIR ${CMAKE_INSTALL_LIBDIR}/mlt) From 9b61e4c00be75d67486830c08856d866218fcab2 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 23 Mar 2021 00:54:48 +0100 Subject: [PATCH 102/122] cmake: add feature_summary() --- CMakeLists.txt | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 404f23bbb..a9645ff5f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,6 +53,7 @@ endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include(FeatureSummary) include(GNUInstallDirs) if(WINDOWS_DEPLOY) @@ -458,3 +459,43 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/Mlt${MLT_VERSION_MAJOR}ConfigVersion.cmake" DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Mlt${MLT_VERSION_MAJOR} ) + +add_feature_info("GPLv2" GPL "") +add_feature_info("GPLv3" GPL3 "") +add_feature_info("Tests" BUILD_TESTING "") +add_feature_info("Doxygen" BUILD_DOCS "") +add_feature_info("Module: avformat" MOD_AVFORMAT "") +add_feature_info("Module: DeckLink" MOD_DECKLINK "") +add_feature_info("Module: Frei0r" MOD_FREI0R "") +add_feature_info("Module: GDK" MOD_GDK "") +add_feature_info("Module: JACKRack" MOD_JACKRACK "") +add_feature_info("Module: Kdenlive" MOD_KDENLIVE "") +add_feature_info("Module: NDI" MOD_NDI "") +add_feature_info("Module: Normalize" MOD_NORMALIZE "") +add_feature_info("Module: Oldfilm" MOD_OLDFILM "") +add_feature_info("Module: OpenCV" MOD_OPENCV "") +add_feature_info("Module: Movit" MOD_MOVIT "") +add_feature_info("Module: Plus" MOD_PLUS "") +add_feature_info("Module: PlusGPL" MOD_PLUSGPL "") +add_feature_info("Module: Qt" MOD_QT "") +add_feature_info("Module: Resample" MOD_RESAMPLE "") +add_feature_info("Module: RtAudio" MOD_RTAUDIO "") +add_feature_info("Module: Rubberband" MOD_RUBBERBAND "") +add_feature_info("Module: SDL1" MOD_SDL1 "") +add_feature_info("Module: SDL2" MOD_SDL2 "") +add_feature_info("Module: SoX" MOD_SOX "") +add_feature_info("Module: vid.stab" MOD_VIDSTAB "") +add_feature_info("Module: Vorbis" MOD_VORBIS "") +add_feature_info("Module: XINE" MOD_XINE "") +add_feature_info("Module: XML" MOD_XML "") +add_feature_info("SWIG: C#" SWIG_CSHARP "") +add_feature_info("SWIG: Java" SWIG_JAVA "") +add_feature_info("SWIG: Lua" SWIG_LUA "") +add_feature_info("SWIG: Node.js" SWIG_NODEJS "") +add_feature_info("SWIG: Perl" SWIG_PERL "") +add_feature_info("SWIG: PHP" SWIG_PHP "") +add_feature_info("SWIG: Python" SWIG_PYTHON "") +add_feature_info("SWIG: Ruby" SWIG_RUBY "") +add_feature_info("SWIG: Tcl" SWIG_TCL "") + +feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) From c88a49a69980f10640ad3ce2fdaafc0d900f4f6b Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 23 Mar 2021 14:12:03 +0100 Subject: [PATCH 103/122] cmake: improve option() descriptions --- CMakeLists.txt | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a9645ff5f..2025746e8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,37 +7,37 @@ project(MLT LANGUAGES C CXX ) -option(GPL "Enable GPLv2 modules" ON) -option(GPL3 "Enable GPLv3 modules" ON) +option(GPL "Enable GPLv2 components" ON) +option(GPL3 "Enable GPLv3 components" ON) option(BUILD_TESTING "Enable tests" OFF) option(BUILD_DOCS "Enable Doxygen documentation" OFF) option(MOD_AVFORMAT "Enable avformat module" ON) -option(MOD_DECKLINK "Enable decklink module" ON) -option(MOD_FREI0R "Enable frei0r module" ON) -option(MOD_GDK "Enable gdk module" ON) -option(MOD_JACKRACK "Enable jackrack module" ON) -option(MOD_KDENLIVE "Enable kdenlive module" ON) +option(MOD_DECKLINK "Enable DeckLink module" ON) +option(MOD_FREI0R "Enable Frei0r module" ON) +option(MOD_GDK "Enable GDK module" ON) +option(MOD_JACKRACK "Enable JACK Rack module" ON) +option(MOD_KDENLIVE "Enable Kdenlive module" ON) option(MOD_NDI "Enable NDI module" OFF) -option(MOD_NORMALIZE "Enable normalize module" ON) -option(MOD_OLDFILM "Enable oldfilm module" ON) +option(MOD_NORMALIZE "Enable Normalize module (GPL)" ON) +option(MOD_OLDFILM "Enable Oldfilm module" ON) option(MOD_OPENCV "Enable OpenCV module" OFF) option(MOD_MOVIT "Enable OpenGL module" ON) -option(MOD_PLUS "Enable plus module" ON) -option(MOD_PLUSGPL "Enable plus GPL module" ON) -option(MOD_QT "Enable Qt module" ON) -option(MOD_RESAMPLE "Enable resample module" ON) +option(MOD_PLUS "Enable Plus module" ON) +option(MOD_PLUSGPL "Enable PlusGPL module (GPL)" ON) +option(MOD_QT "Enable Qt module (GPL)" ON) +option(MOD_RESAMPLE "Enable Resample module (GPL)" ON) option(MOD_RTAUDIO "Enable RtAudio module" ON) -option(MOD_RUBBERBAND "Enable rubberband module" ON) +option(MOD_RUBBERBAND "Enable Rubberband module (GPL)" ON) option(MOD_SDL1 "Enable SDL1 module" ON) option(MOD_SDL2 "Enable SDL2 module" ON) option(MOD_SOX "Enable SoX module" ON) -option(MOD_VIDSTAB "Enable vid.stab module" ON) +option(MOD_VIDSTAB "Enable vid.stab module (GPL)" ON) option(MOD_VORBIS "Enable Vorbis module" ON) -option(MOD_XINE "Enable xine module" ON) +option(MOD_XINE "Enable XINE module (GPL)" ON) option(MOD_XML "Enable XML module" ON) -option(SWIG_CSHARP "Enable SWIG CSharp bindings" OFF) +option(SWIG_CSHARP "Enable SWIG C# bindings" OFF) option(SWIG_JAVA "Enable SWIG Java bindings" OFF) option(SWIG_LUA "Enable SWIG Lua bindings" OFF) option(SWIG_NODEJS "Enable SWIG Node.js bindings" OFF) @@ -129,6 +129,7 @@ if(NOT GPL) set(MOD_NORMALIZE OFF) set(MOD_PLUSGPL OFF) set(MOD_QT OFF) + set(MOD_RESAMPLE OFF) set(MOD_RUBBERBAND OFF) set(MOD_VIDSTAB OFF) set(MOD_XINE OFF) From c6bc58a66cb0e14e687751f1fb6961b12664189c Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 23 Mar 2021 14:13:08 +0100 Subject: [PATCH 104/122] cmake: use PkgConfig::sdl2 --- CMakeLists.txt | 4 ++-- src/melt/CMakeLists.txt | 3 +-- src/modules/sdl2/CMakeLists.txt | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2025746e8..fd9a7ebfa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,7 +146,7 @@ if(WIN32) endif() endif() -pkg_check_modules(sdl2 IMPORTED_TARGET GLOBAL sdl2) +pkg_check_modules(sdl2 IMPORTED_TARGET sdl2) if(BUILD_TESTING) find_package(Qt5 REQUIRED COMPONENTS Core Test) @@ -313,7 +313,7 @@ if(MOD_SDL1) endif() if(MOD_SDL2) - if(TARGET sdl2) + if(TARGET PkgConfig::sdl2) list(APPEND MLT_SUPPORTED_COMPONENTS sdl2) else() set(MOD_SDL2 OFF) diff --git a/src/melt/CMakeLists.txt b/src/melt/CMakeLists.txt index c9106c73a..439c38f8e 100644 --- a/src/melt/CMakeLists.txt +++ b/src/melt/CMakeLists.txt @@ -7,8 +7,7 @@ target_link_libraries(melt PRIVATE mlt Threads::Threads) target_compile_definitions(melt PRIVATE VERSION="${MLT_VERSION}") if(TARGET PkgConfig::sdl2) - add_library(sdl2 ALIAS PkgConfig::sdl2) - target_link_libraries(melt PRIVATE sdl2) + target_link_libraries(melt PRIVATE PkgConfig::sdl2) target_compile_definitions(melt PRIVATE HAVE_SDL2) if(MINGW) target_link_libraries(melt PRIVATE mingw32) diff --git a/src/modules/sdl2/CMakeLists.txt b/src/modules/sdl2/CMakeLists.txt index f75bb6721..8200dc74d 100644 --- a/src/modules/sdl2/CMakeLists.txt +++ b/src/modules/sdl2/CMakeLists.txt @@ -7,7 +7,7 @@ add_library(mltsdl2 MODULE target_compile_options(mltsdl2 PRIVATE ${MLT_COMPILE_OPTIONS}) -target_link_libraries(mltsdl2 PRIVATE mlt m Threads::Threads sdl2) +target_link_libraries(mltsdl2 PRIVATE mlt m Threads::Threads PkgConfig::sdl2) set_target_properties(mltsdl2 PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") From c571aaf17a7029fc9b19dbd292bdb89bf1ba1784 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 23 Mar 2021 14:38:35 +0100 Subject: [PATCH 105/122] cmake: use FindJACK.cmake --- CMakeLists.txt | 2 +- cmake/FindJACK.cmake | 36 +++++++++++++++++++++++++++++ src/modules/jackrack/CMakeLists.txt | 6 ++--- 3 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 cmake/FindJACK.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fd9a7ebfa..cb69bca41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,7 +213,7 @@ if(MOD_GDK) endif() if(MOD_JACKRACK) - pkg_check_modules(jack IMPORTED_TARGET jack) + find_package(JACK) pkg_check_modules(glib IMPORTED_TARGET glib-2.0) check_include_file(ladspa.h ladspa_h_FOUND) list(APPEND MLT_SUPPORTED_COMPONENTS jackrack) diff --git a/cmake/FindJACK.cmake b/cmake/FindJACK.cmake new file mode 100644 index 000000000..a30214e78 --- /dev/null +++ b/cmake/FindJACK.cmake @@ -0,0 +1,36 @@ +find_package(PkgConfig) +pkg_check_modules(PC_JACK QUIET jack) + +find_path(JACK_INCLUDE_DIR + NAMES jack/jack.h + PATHS ${PC_JACK_INCLUDE_DIRS} +) +find_library(JACK_LIBRARY + NAMES jack + PATHS ${PC_JACK_LIBRARY_DIRS} +) + +set(JACK_VERSION ${PC_JACK_VERSION}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(JACK + FOUND_VAR JACK_FOUND + REQUIRED_VARS + JACK_LIBRARY + JACK_INCLUDE_DIR + VERSION_VAR JACK_VERSION +) + +if(JACK_FOUND AND NOT TARGET JACK::JACK) + add_library(JACK::JACK UNKNOWN IMPORTED) + set_target_properties(JACK::JACK PROPERTIES + IMPORTED_LOCATION "${JACK_LIBRARY}" + INTERFACE_COMPILE_OPTIONS "${PC_JACK_CFLAGS_OTHER}" + INTERFACE_INCLUDE_DIRECTORIES "${JACK_INCLUDE_DIR}" + ) +endif() + +mark_as_advanced( + JACK_INCLUDE_DIR + JACK_LIBRARY +) diff --git a/src/modules/jackrack/CMakeLists.txt b/src/modules/jackrack/CMakeLists.txt index 78b715831..3ddd1d204 100644 --- a/src/modules/jackrack/CMakeLists.txt +++ b/src/modules/jackrack/CMakeLists.txt @@ -4,9 +4,9 @@ target_compile_options(mltjack PRIVATE ${MLT_COMPILE_OPTIONS}) target_link_libraries(mltjack PRIVATE mlt Threads::Threads) -if(TARGET PkgConfig::jack) +if(TARGET JACK::JACK) target_sources(mltjack PRIVATE consumer_jack.c) - target_link_libraries(mltjack PRIVATE PkgConfig::jack) + target_link_libraries(mltjack PRIVATE JACK::JACK) target_compile_definitions(mltjack PRIVATE WITH_JACK) install(FILES consumer_jack.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) endif() @@ -27,7 +27,7 @@ if(GPL AND TARGET PkgConfig::xml AND TARGET PkgConfig::glib AND ladspa_h_FOUND) target_compile_definitions(mltjack PRIVATE GPL) install(FILES filter_jack.yml filter_ladspa.yml producer_ladspa.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) - if(TARGET PkgConfig::jack) + if(TARGET JACK::JACK) target_sources(mltjack PRIVATE filter_jackrack.c) install(FILES filter_jackrack.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) endif() From 7bc008c6668ef7a5053b859023cfe923ca4aa473 Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 23 Mar 2021 14:45:40 +0100 Subject: [PATCH 106/122] cmake: use correct module name for jackrack --- src/modules/jackrack/CMakeLists.txt | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/modules/jackrack/CMakeLists.txt b/src/modules/jackrack/CMakeLists.txt index 3ddd1d204..e7d9bbb4a 100644 --- a/src/modules/jackrack/CMakeLists.txt +++ b/src/modules/jackrack/CMakeLists.txt @@ -1,18 +1,18 @@ -add_library(mltjack MODULE factory.c) +add_library(mltjackrack MODULE factory.c) -target_compile_options(mltjack PRIVATE ${MLT_COMPILE_OPTIONS}) +target_compile_options(mltjackrack PRIVATE ${MLT_COMPILE_OPTIONS}) -target_link_libraries(mltjack PRIVATE mlt Threads::Threads) +target_link_libraries(mltjackrack PRIVATE mlt Threads::Threads) if(TARGET JACK::JACK) - target_sources(mltjack PRIVATE consumer_jack.c) - target_link_libraries(mltjack PRIVATE JACK::JACK) - target_compile_definitions(mltjack PRIVATE WITH_JACK) + target_sources(mltjackrack PRIVATE consumer_jack.c) + target_link_libraries(mltjackrack PRIVATE JACK::JACK) + target_compile_definitions(mltjackrack PRIVATE WITH_JACK) install(FILES consumer_jack.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) endif() if(GPL AND TARGET PkgConfig::xml AND TARGET PkgConfig::glib AND ladspa_h_FOUND) - target_sources(mltjack PRIVATE + target_sources(mltjackrack PRIVATE jack_rack.c lock_free_fifo.c plugin.c @@ -23,16 +23,16 @@ if(GPL AND TARGET PkgConfig::xml AND TARGET PkgConfig::glib AND ladspa_h_FOUND) producer_ladspa.c filter_ladspa.c ) - target_link_libraries(mltjack PRIVATE ${CMAKE_DL_LIBS} m PkgConfig::xml PkgConfig::glib) - target_compile_definitions(mltjack PRIVATE GPL) + target_link_libraries(mltjackrack PRIVATE ${CMAKE_DL_LIBS} m PkgConfig::xml PkgConfig::glib) + target_compile_definitions(mltjackrack PRIVATE GPL) install(FILES filter_jack.yml filter_ladspa.yml producer_ladspa.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) if(TARGET JACK::JACK) - target_sources(mltjack PRIVATE filter_jackrack.c) + target_sources(mltjackrack PRIVATE filter_jackrack.c) install(FILES filter_jackrack.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) endif() endif() -set_target_properties(mltjack PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") +set_target_properties(mltjackrack PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${MLT_MODULE_OUTPUT_DIRECTORY}") -install(TARGETS mltjack LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) +install(TARGETS mltjackrack LIBRARY DESTINATION ${MLT_INSTALL_MODULE_DIR}) From f773e8902b064b365e165d23f4cdf27f689d21dd Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Tue, 23 Mar 2021 22:00:43 -0500 Subject: [PATCH 107/122] Remove use of deprecated function mlt_frame_get_alpha_mask() --- src/modules/plus/filter_affine.c | 7 +++++-- src/modules/plus/filter_chroma.c | 14 ++++++++++++-- src/modules/plus/filter_invert.c | 3 ++- src/modules/plus/filter_shape.c | 23 ++++++++++++++++++----- src/modules/plus/filter_strobe.c | 20 ++++++++------------ src/modules/plus/filter_threshold.c | 24 ++++++++++++++++++------ src/modules/plusgpl/filter_rotoscoping.c | 9 ++++++++- 7 files changed, 71 insertions(+), 29 deletions(-) diff --git a/src/modules/plus/filter_affine.c b/src/modules/plus/filter_affine.c index 5b1e667c1..b6eebf9e3 100644 --- a/src/modules/plus/filter_affine.c +++ b/src/modules/plus/filter_affine.c @@ -1,6 +1,6 @@ /* * filter_affine.c -- affine filter - * Copyright (C) 2003-2020 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -111,7 +111,10 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format mlt_frame_get_image( a_frame, image, format, width, height, writable ); mlt_properties_set_data( frame_properties, "affine_frame", a_frame, 0, (mlt_destructor)mlt_frame_close, NULL ); mlt_frame_set_image( frame, *image, *width * *height * 4, NULL ); - mlt_frame_set_alpha( frame, mlt_frame_get_alpha_mask( a_frame ), *width * *height, NULL ); + uint8_t* alpha = mlt_frame_get_alpha( a_frame ); + if ( alpha ) { + mlt_frame_set_alpha( frame, alpha, *width * *height, NULL ); + } mlt_service_unlock( MLT_FILTER_SERVICE( filter ) ); } else diff --git a/src/modules/plus/filter_chroma.c b/src/modules/plus/filter_chroma.c index c49c3a600..558f5fdb0 100644 --- a/src/modules/plus/filter_chroma.c +++ b/src/modules/plus/filter_chroma.c @@ -1,6 +1,7 @@ /* * filter_chroma.c -- Maps a chroma key to the alpha channel * Copyright (C) 2005 Visual Media Fx Inc. + * Copyright (C) 2021 Meltytech, LLC * Author: Charles Yates * * This program is free software; you can redistribute it and/or modify @@ -19,11 +20,13 @@ */ #include -#include #include #include #include +#include +#include + static inline int in_range( uint8_t v, uint8_t c, int var ) { return ( ( int )v >= c - var ) && ( ( int )v <= c + var ); @@ -55,7 +58,14 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format *format = mlt_image_yuv422; if ( mlt_frame_get_image( frame, image, format, width, height, writable ) == 0 ) { - uint8_t *alpha = mlt_frame_get_alpha_mask( frame ); + uint8_t *alpha = mlt_frame_get_alpha( frame ); + if ( !alpha ) + { + int alphasize = *width * *height; + alpha = mlt_pool_alloc( alphasize ); + memset( alpha, 255, alphasize ); + mlt_frame_set_alpha( frame, alpha, alphasize, mlt_pool_release ); + } uint8_t *p = *image; int size = *width * *height / 2; while ( size -- ) diff --git a/src/modules/plus/filter_invert.c b/src/modules/plus/filter_invert.c index 31599e9ea..34e2ccff8 100644 --- a/src/modules/plus/filter_invert.c +++ b/src/modules/plus/filter_invert.c @@ -57,9 +57,10 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format if ( mask ) { - uint8_t *alpha = mlt_frame_get_alpha_mask( frame ); int size = *width * *height; + uint8_t* alpha = mlt_pool_alloc( size ); memset( alpha, mask, size ); + mlt_frame_set_alpha( frame, alpha, size, mlt_pool_release ); } } diff --git a/src/modules/plus/filter_shape.c b/src/modules/plus/filter_shape.c index 824a165e6..6209cebbb 100644 --- a/src/modules/plus/filter_shape.c +++ b/src/modules/plus/filter_shape.c @@ -1,6 +1,7 @@ /* * filter_shape.c -- Arbitrary alpha channel shaping * Copyright (C) 2005 Visual Media Fx Inc. + * Copyright (C) 2021 Meltytech, LLC * Author: Charles Yates * * This program is free software; you can redistribute it and/or modify @@ -59,9 +60,6 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format if ( mlt_frame_get_image( frame, image, format, width, height, writable ) == 0 && ( !use_luminance || !use_mix || (int) mix != 1 || invert == 255 ) ) { - // Get the alpha mask of the source - uint8_t *alpha = mlt_frame_get_alpha_mask( frame ); - // Obtain a scaled/distorted mask to match uint8_t *mask_img = NULL; mlt_image_format mask_fmt = mlt_image_yuv422; @@ -71,12 +69,27 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format if ( mlt_frame_get_image( mask, &mask_img, &mask_fmt, width, height, 0 ) == 0 ) { int size = *width * *height; - uint8_t *p = alpha; double a = 0; double b = 0; + uint8_t* p = mlt_frame_get_alpha( frame ); + if ( !p ) + { + int alphasize = *width * *height; + p = mlt_pool_alloc( alphasize ); + memset( p, 255, alphasize ); + mlt_frame_set_alpha( frame, p, alphasize, mlt_pool_release ); + } + if ( !use_luminance ) { - uint8_t *q = mlt_frame_get_alpha_mask( mask ); + uint8_t* q = mlt_frame_get_alpha( mask ); + if ( !q ) + { + int alphasize = *width * *height; + q = mlt_pool_alloc( alphasize ); + memset( q, 255, alphasize ); + mlt_frame_set_alpha( mask, q, alphasize, mlt_pool_release ); + } if ( use_mix ) { while( size -- ) diff --git a/src/modules/plus/filter_strobe.c b/src/modules/plus/filter_strobe.c index 25aa16081..a78cd0d9f 100644 --- a/src/modules/plus/filter_strobe.c +++ b/src/modules/plus/filter_strobe.c @@ -61,18 +61,6 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format assert( *height >= 0 ); size_t pixelCount = *width * *height; - // We always clear the alpha mask, in case there's some optimizations - // that can be applied or other filters modyify the image contents. - uint8_t *alpha_buffer = mlt_frame_get_alpha_mask( frame ); - assert( alpha_buffer != NULL ); - - // We assert because the API contract guarantees that we always get a - // buffer, but don't want to crash in release build if it is broken. - if ( alpha_buffer ) - { - memset( alpha_buffer, 0, pixelCount ); - } - if ( *format == mlt_image_rgba ) { uint8_t *bytes = *image; @@ -80,6 +68,14 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format { bytes[i] = 0; } + // Clear any alpha buffer that may be attached to the frame + mlt_frame_set_alpha( frame, NULL, 0, NULL ); + } + else + { + uint8_t* alpha = mlt_pool_alloc( pixelCount ); + memset( alpha, 0, pixelCount ); + mlt_frame_set_alpha( frame, alpha, pixelCount, mlt_pool_release ); } return 0; diff --git a/src/modules/plus/filter_threshold.c b/src/modules/plus/filter_threshold.c index c3421c0e7..2d4f87530 100644 --- a/src/modules/plus/filter_threshold.c +++ b/src/modules/plus/filter_threshold.c @@ -1,6 +1,7 @@ /* * filter_threshold.c -- Arbitrary alpha channel shaping * Copyright (C) 2005 Visual Media Fx Inc. + * Copyright (C) 2021 Meltytech, LLC * Author: Charles Yates * * This program is free software; you can redistribute it and/or modify @@ -62,14 +63,25 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format } else { - uint8_t *alpha = mlt_frame_get_alpha_mask( frame ); - while (--size) + uint8_t *alpha = mlt_frame_get_alpha( frame ); + if ( alpha ) { - if ( *alpha ++ < midpoint ) - *p ++ = A; - else + while (--size) + { + if ( *alpha ++ < midpoint ) + *p ++ = A; + else + *p ++ = B; + *p ++ = 128; + } + } + else + { + while (--size) + { *p ++ = B; - *p ++ = 128; + *p ++ = 128; + } } } } diff --git a/src/modules/plusgpl/filter_rotoscoping.c b/src/modules/plusgpl/filter_rotoscoping.c index aedd7ec8b..6d493affa 100644 --- a/src/modules/plusgpl/filter_rotoscoping.c +++ b/src/modules/plusgpl/filter_rotoscoping.c @@ -1,6 +1,7 @@ /* * rotoscoping.c -- keyframable vector based rotoscoping * Copyright (C) 2011 Till Theato + * Copyright (C) 2021 Meltytech, LLC * * 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 @@ -470,7 +471,13 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format } break; default: - alpha = mlt_frame_get_alpha_mask( frame ); + alpha = mlt_frame_get_alpha( frame ); + if ( !alpha ) + { + alpha = mlt_pool_alloc( length ); + memset( alpha, 255, length ); + mlt_frame_set_alpha( frame, alpha, length, mlt_pool_release ); + } switch ( mlt_properties_get_int( unique, "alpha_operation" ) ) { case ALPHA_CLEAR: From bb8b80c83e73639779b38561e35488ae4f0cbd72 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Tue, 23 Mar 2021 22:02:46 -0500 Subject: [PATCH 108/122] Remove deprecated function mlt_frame_get_alpha_mask() --- docs/framework.txt | 1 - src/framework/mlt_frame.c | 20 -------------------- src/framework/mlt_frame.h | 1 - 3 files changed, 22 deletions(-) diff --git a/docs/framework.txt b/docs/framework.txt index 57163483f..5f147fd2e 100644 --- a/docs/framework.txt +++ b/docs/framework.txt @@ -1134,7 +1134,6 @@ mlt_frame: mlt_position mlt_frame_get_position( mlt_frame this ); int mlt_frame_set_position( mlt_frame this, mlt_position value ); int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ); - uint8_t *mlt_frame_get_alpha_mask( mlt_frame this ); int mlt_frame_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ); int mlt_frame_push_get_image( mlt_frame this, mlt_get_image get_image ); mlt_get_image mlt_frame_pop_get_image( mlt_frame this ); diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 777a52a91..0d46a6c96 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -533,27 +533,7 @@ int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *for * \return the alpha channel */ -uint8_t *mlt_frame_get_alpha_mask( mlt_frame self ) -{ - uint8_t *alpha = NULL; - if ( self != NULL ) - { - alpha = mlt_properties_get_data( &self->parent, "alpha", NULL ); - if ( alpha == NULL ) - { - int size = mlt_properties_get_int( &self->parent, "width" ) * mlt_properties_get_int( &self->parent, "height" ); - alpha = mlt_pool_alloc( size ); - memset( alpha, 255, size ); - mlt_properties_set_data( &self->parent, "alpha", alpha, size, mlt_pool_release, NULL ); - } - } - return alpha; -} - /** Get the alpha channel associated to the frame (without creating if it has not). - * - * Unlike mlt_frame_get_alpha_mask(), this function does NOT create an alpha - * channel if one does not already exist. * * \public \memberof mlt_frame_s * \param self a frame diff --git a/src/framework/mlt_frame.h b/src/framework/mlt_frame.h index b0e02bc28..df83c77f8 100644 --- a/src/framework/mlt_frame.h +++ b/src/framework/mlt_frame.h @@ -117,7 +117,6 @@ extern int mlt_frame_set_image( mlt_frame self, uint8_t *image, int size, mlt_de extern int mlt_frame_set_alpha( mlt_frame self, uint8_t *alpha, int size, mlt_destructor destroy ); extern void mlt_frame_replace_image( mlt_frame self, uint8_t *image, mlt_image_format format, int width, int height ); extern int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ); -extern uint8_t *mlt_frame_get_alpha_mask( mlt_frame self ); extern uint8_t *mlt_frame_get_alpha( mlt_frame self ); extern int mlt_frame_get_audio( mlt_frame self, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ); extern int mlt_frame_set_audio( mlt_frame self, void *buffer, mlt_audio_format, int size, mlt_destructor ); From 7b38b727535b11d64e56b2548b3da8ea973d69c0 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Tue, 23 Mar 2021 22:28:19 -0500 Subject: [PATCH 109/122] Clean up old comment This was missed when the function was removed. --- src/framework/mlt_frame.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index 0d46a6c96..9bc3a43c9 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -522,17 +522,6 @@ int mlt_frame_get_image( mlt_frame self, uint8_t **buffer, mlt_image_format *for return error; } -/** Get the alpha channel associated to the frame. - * - * Unlike mlt_frame_get_alpha(), this function WILL create an opaque alpha - * channel if one does not already exist. - * - * \public \memberof mlt_frame_s - * \deprecated use mlt_frame_get_alpha() instead - * \param self a frame - * \return the alpha channel - */ - /** Get the alpha channel associated to the frame (without creating if it has not). * * \public \memberof mlt_frame_s From e9bc03702b27f98804d8dcc7f772cc886bf3e491 Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Mon, 22 Mar 2021 18:32:24 -0700 Subject: [PATCH 110/122] drop the special fs: protocol This was previously required to be able to supply a query string of additional open parameters on a file name. Now, an escaped question mark is considered a query string delimiter on file names: \?. It must be esacped to accept a question in the file name. If the resource URL begins with a protocol other than "file:" then the query string delimiter continues to be an unescaped question mark. --- src/modules/avformat/producer_avformat.c | 150 +++++++++++------------ src/modules/core/producer_loader.c | 6 +- 2 files changed, 73 insertions(+), 83 deletions(-) diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index 620e4ea2b..c36ee6283 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -543,97 +543,87 @@ static char* parse_url( mlt_profile profile, const char* URL, AVInputFormat **fo char *protocol = strdup( URL ); char *url = strchr( protocol, ':' ); - // Only if there is not a protocol specification that avformat can handle - if ( url && avio_check( URL, 0 ) < 0 ) - { - // Truncate protocol string - url[0] = 0; + // Truncate protocol string + if (url) { + url[0] = '\0'; ++url; mlt_log_debug( NULL, "%s: protocol=%s resource=%s\n", __FUNCTION__, protocol, url ); - int isFsProtocol = !strcmp( protocol, "fs" ); - // Lookup the format *format = av_find_input_format( protocol ); + } else { + url = protocol; + } - if ( *format || isFsProtocol ) - { - // Eat the format designator - char *result = url; + // Eat the format designator + char *result = url; - // support for legacy width and height parameters - char *width = NULL; - char *height = NULL; + // support for legacy width and height parameters + char *width = NULL; + char *height = NULL; - // Parse out params - char* query = strchr( url, '?' ); - while ( isFsProtocol && query && query > url && query[-1] == '\\' ) - { - // ignore escaped question marks - query = strchr( query + 1, '?' ); - } - url = ( query && query > url && query[-1] != '\\' ) ? query : NULL; - while ( url ) - { - url[0] = 0; - char *name = strdup( ++url ); - char *value = strchr( name, '=' ); - if ( !value ) - // Also accept : as delimiter for backwards compatibility. - value = strchr( name, ':' ); - if ( value ) - { - value[0] = 0; - value++; - char *t = strchr( value, '&' ); - if ( t ) - t[0] = 0; - // translate old parameters to new av_dict names - if ( !strcmp( name, "frame_rate" ) ) - av_dict_set( params, "framerate", value, 0 ); - else if ( !strcmp( name, "pix_fmt" ) ) - av_dict_set( params, "pixel_format", value, 0 ); - else if ( !strcmp( name, "width" ) ) - width = strdup( value ); - else if ( !strcmp( name, "height" ) ) - height = strdup( value ); - else - // generic demux/device option support - av_dict_set( params, name, value, 0 ); - } - free( name ); - url = strchr( url, '&' ); - } - // continued support for legacy width and height parameters - if ( width && height ) - { - char *s = malloc( strlen( width ) + strlen( height ) + 2 ); - strcpy( s, width ); - strcat( s, "x"); - strcat( s, height ); - av_dict_set( params, "video_size", s, 0 ); - free( s ); - } - free( width ); - free( height ); - result = strdup(result); - free( protocol ); - if (isFsProtocol) { - // remove escape backslashes - int reader = 0, writer = 0; - while (result[reader]) - { - if (result[reader] != '\\') - result[writer++] = result[reader]; - reader++; - } - result[writer] = '\0'; - } - return result; + // Parse out params + char* query = strchr( url, '?' ); + if (*format) { + // Query string delimiter is '?' + url = ( query && query > url && query[-1] != '\\' ) ? query : NULL; + } else { + // Ignore unescaped question marks + while ( query && query > url && query[-1] != '\\' ) { + query = strchr( query + 1, '?' ); + } + // Query string delimiter is '\?' + url = ( query && query > url && query[-1] == '\\' ) ? query : NULL; + if (url) url[-1] = '\0'; // null the backslash + } + while ( url ) + { + url[0] = '\0'; + char *name = strdup( ++url ); + char *value = strchr( name, '=' ); + if ( !value ) + // Also accept : as delimiter for backwards compatibility. + value = strchr( name, ':' ); + if ( value ) + { + value[0] = '\0'; + value++; + char *t = strchr( value, '&' ); + if ( t ) + t[0] = 0; + // translate old parameters to new av_dict names + if ( !strcmp( name, "frame_rate" ) ) + av_dict_set( params, "framerate", value, 0 ); + else if ( !strcmp( name, "pix_fmt" ) ) + av_dict_set( params, "pixel_format", value, 0 ); + else if ( !strcmp( name, "width" ) ) + width = strdup( value ); + else if ( !strcmp( name, "height" ) ) + height = strdup( value ); + else + // generic demux/device option support + av_dict_set( params, name, value, 0 ); } + free( name ); + url = strchr( url, '&' ); + } + // continued support for legacy width and height parameters + if ( width && height ) + { + char *s = malloc( strlen( width ) + strlen( height ) + 2 ); + strcpy( s, width ); + strcat( s, "x"); + strcat( s, height ); + av_dict_set( params, "video_size", s, 0 ); + free( s ); } + free( width ); + free( height ); + + result = strdup(result); free( protocol ); - return strdup( URL ); + mlt_log_debug(NULL, "[producer avformat] %s filename = %s\n", __FUNCTION__, result); + return result; } static enum AVPixelFormat pick_pix_fmt( enum AVPixelFormat pix_fmt ) diff --git a/src/modules/core/producer_loader.c b/src/modules/core/producer_loader.c index 97f52052c..1f81cb84f 100644 --- a/src/modules/core/producer_loader.c +++ b/src/modules/core/producer_loader.c @@ -1,6 +1,6 @@ /* * producer_loader.c -- auto-load producer by file name extension - * Copyright (C) 2003-2014 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -107,8 +107,8 @@ static mlt_producer create_producer( mlt_profile profile, char *file ) // Chop off the query string p = strrchr( lookup, '?' ); - if ( p ) - p[0] = '\0'; + if ( p && p > lookup && p[-1] == '\\' ) + p[-1] = '\0'; // Strip file:// prefix p = lookup; From c09a929cfedb517ac16ee76af4afc938a15d9e02 Mon Sep 17 00:00:00 2001 From: Vincent Pinon Date: Sat, 27 Mar 2021 22:50:18 +0100 Subject: [PATCH 111/122] CMake: fix MacOS build and allow relocatable build --- CMakeLists.txt | 4 ++++ src/framework/CMakeLists.txt | 4 +++- src/modules/frei0r/CMakeLists.txt | 3 +++ src/modules/jackrack/CMakeLists.txt | 4 ++++ src/modules/movit/CMakeLists.txt | 3 +++ 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cb69bca41..09d678e46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,6 +50,10 @@ option(SWIG_TCL "Enable SWIG Tcl bindings" OFF) if(WIN32) option(WINDOWS_DEPLOY "Install exes/libs directly to prefix (no subdir /bin)" ON) endif() +if(APPLE) + option(RELOCATABLE "Use standard app bundle layout" ON) +endif() + list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 38a20355d..3c1602e48 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -100,13 +100,15 @@ if(WIN32) endif() endif() -if(NOT (WIN32 OR APPLE)) +if(NOT (WIN32 OR (APPLE AND RELOCATABLE))) target_compile_definitions(mlt PRIVATE $ $ ) target_link_options(mlt PRIVATE -Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/mlt.vers) set_target_properties(mlt PROPERTIES LINK_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/mlt.vers) +elseif(APPLE AND RELOCATABLE) + target_compile_definitions(mlt PRIVATE RELOCATABLE) endif() install(TARGETS mlt diff --git a/src/modules/frei0r/CMakeLists.txt b/src/modules/frei0r/CMakeLists.txt index 352b6a7e3..4af3914c5 100644 --- a/src/modules/frei0r/CMakeLists.txt +++ b/src/modules/frei0r/CMakeLists.txt @@ -8,6 +8,9 @@ add_library(mltfrei0r MODULE ) target_compile_options(mltfrei0r PRIVATE ${MLT_COMPILE_OPTIONS}) +if(APPLE AND RELOCATABLE) + target_compile_definitions(mltfrei0r PRIVATE RELOCATABLE) +endif() target_link_libraries(mltfrei0r PRIVATE mlt m ${CMAKE_DL_LIBS}) diff --git a/src/modules/jackrack/CMakeLists.txt b/src/modules/jackrack/CMakeLists.txt index e7d9bbb4a..fbf2eae62 100644 --- a/src/modules/jackrack/CMakeLists.txt +++ b/src/modules/jackrack/CMakeLists.txt @@ -25,6 +25,10 @@ if(GPL AND TARGET PkgConfig::xml AND TARGET PkgConfig::glib AND ladspa_h_FOUND) ) target_link_libraries(mltjackrack PRIVATE ${CMAKE_DL_LIBS} m PkgConfig::xml PkgConfig::glib) target_compile_definitions(mltjackrack PRIVATE GPL) + if(APPLE AND RELOCATABLE) + target_compile_definitions(mltjackrack PRIVATE RELOCATABLE) + endif() + install(FILES filter_jack.yml filter_ladspa.yml producer_ladspa.yml DESTINATION ${MLT_INSTALL_DATA_DIR}/jackrack) if(TARGET JACK::JACK) diff --git a/src/modules/movit/CMakeLists.txt b/src/modules/movit/CMakeLists.txt index e4fd4fe29..eb05c64d4 100644 --- a/src/modules/movit/CMakeLists.txt +++ b/src/modules/movit/CMakeLists.txt @@ -25,6 +25,9 @@ add_library(mltmovit MODULE ) target_compile_options(mltmovit PRIVATE ${MLT_COMPILE_OPTIONS}) +if(APPLE AND RELOCATABLE) + target_compile_definitions(mltmovit PRIVATE RELOCATABLE) +endif() target_link_libraries(mltmovit PRIVATE m Threads::Threads mlt mlt++ OpenGL::GL PkgConfig::movit) From 74265e918699c3d384d0c422ab4d6bd5bdc6dcca Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Fri, 2 Apr 2021 18:33:33 -0700 Subject: [PATCH 112/122] support PNG and GIF as album art --- src/modules/avformat/producer_avformat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/modules/avformat/producer_avformat.c b/src/modules/avformat/producer_avformat.c index c36ee6283..e9d1b471a 100644 --- a/src/modules/avformat/producer_avformat.c +++ b/src/modules/avformat/producer_avformat.c @@ -1682,7 +1682,9 @@ static int producer_get_image( mlt_frame frame, uint8_t **buffer, mlt_image_form codec_params = stream->codecpar; // Always use the image cache for album art. - int is_album_art = (codec_params->codec_id == AV_CODEC_ID_MJPEG + int is_album_art = ((codec_context->codec_id == AV_CODEC_ID_MJPEG + || codec_context->codec_id == AV_CODEC_ID_GIF + || codec_context->codec_id == AV_CODEC_ID_PNG) && mlt_properties_get_int(properties, "meta.media.frame_rate_num") == 90000 && mlt_properties_get_int(properties, "meta.media.frame_rate_den") == 1); if (is_album_art) From 4113d1d553a21a41399a469ee5a232c6e3373ad4 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sat, 3 Apr 2021 08:35:43 -0500 Subject: [PATCH 113/122] Fix alpha fill in avformat This was a regression from f8cc09193456c2d5d3e4b6432d39de41a5d28447 --- src/modules/avformat/consumer_avformat.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/modules/avformat/consumer_avformat.c b/src/modules/avformat/consumer_avformat.c index 1b2296d33..efd29b29e 100644 --- a/src/modules/avformat/consumer_avformat.c +++ b/src/modules/avformat/consumer_avformat.c @@ -2016,18 +2016,18 @@ static void *consumer_thread( void *arg ) } } } - } - else - { - for ( i = 0; i < height; i ++ ) + else { - int n = width; - uint8_t* p = converted_avframe->data[ 0 ] + i * converted_avframe->linesize[ 0 ] + 3; - while ( n ) + for ( i = 0; i < height; i ++ ) { - *p = 255; - p += 4; - n--; + int n = width; + uint8_t* p = converted_avframe->data[ 0 ] + i * converted_avframe->linesize[ 0 ] + 3; + while ( n ) + { + *p = 255; + p += 4; + n--; + } } } } From 0088b76cc8d424b18cfd25a29ba68202b7b640fc Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Fri, 2 Apr 2021 08:42:02 -0500 Subject: [PATCH 114/122] Refactor resample module * Process data in smaller blocks to reduce static memory allocation * Duplicate samples into the resampler when necessary to precharge the delay through the resampler. This avoids sending silent samples in some cases * Save extra samples that result from the resampler and send them out with the next frame. This avoids discarding samples in some cases * Allocate a significantly smaller static buffer to reduce the filter memory footprint * Use the highest quality resampler algorithm For the timeremap filter, these changes result in significantly less audio artifacts ("ticks") in the output. --- src/modules/resample/filter_resample.c | 262 +++++++++++++++++-------- 1 file changed, 179 insertions(+), 83 deletions(-) diff --git a/src/modules/resample/filter_resample.c b/src/modules/resample/filter_resample.c index 8bd7c0c33..5325f35ea 100644 --- a/src/modules/resample/filter_resample.c +++ b/src/modules/resample/filter_resample.c @@ -1,6 +1,6 @@ /* * filter_resample.c -- adjust audio sample frequency - * Copyright (C) 2003-2014 Meltytech, LLC + * Copyright (C) 2003-2021 Meltytech, LLC * * 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 @@ -21,143 +21,239 @@ #include #include +#include + #include #include -#include #include -// BUFFER_LEN is based on a maximum of 96KHz, 5 fps, 8 channels -// TODO: dynamically allocate larger buffer size -#define BUFFER_LEN ((96000/5) * 8 * sizeof(float)) -#define RESAMPLE_TYPE SRC_SINC_FASTEST +#define PROCESS_BUFF_SIZE (10000 * sizeof(float)) + +// Private Types +typedef struct +{ + SRC_STATE* s; + int error; + int channels; + float buff[PROCESS_BUFF_SIZE]; + int leftover_samples; +} private_data; /** Get the audio. */ static int resample_get_audio( mlt_frame frame, void **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) { - int requested_samples = *samples; - - // Get the filter service mlt_filter filter = mlt_frame_pop_audio( frame ); + private_data* pdata = (private_data*)filter->child; + struct mlt_audio_s in; + struct mlt_audio_s out; + mlt_audio_set_values( &out, NULL, *frequency, *format, *samples, *channels ); - // Get the filter properties - mlt_properties filter_properties = MLT_FILTER_PROPERTIES( filter ); - - // Get the resample information - int output_rate = mlt_properties_get_int( filter_properties, "frequency" ); - - // If no resample frequency is specified, default to requested value - if ( output_rate == 0 ) - output_rate = *frequency; + // Apply user requested rate - else will normalize to consumer requested rate; + if ( mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "frequency" ) ) + { + out.frequency = mlt_properties_get_int( MLT_FILTER_PROPERTIES( filter ), "frequency" ); + } // Get the producer's audio int error = mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); - if ( error ) return error; + if ( error || *format == mlt_audio_none || *frequency <= 0 || out.frequency <= 0 || *channels <= 0 ) + { + // Error situation. Do not attempt to convert. + mlt_log_error( MLT_FILTER_SERVICE(filter), "Invalid Parameters: %dS - %dHz %dC %s -> %dHz %dC %s\n", *samples, *frequency, *channels, mlt_audio_format_name( *format ), out.frequency, out.channels, mlt_audio_format_name( out.format ) ); + return error; + } - // Return now if no work to do - if ( output_rate != *frequency && *frequency > 0 && *channels > 0 ) + if ( *samples == 0 ) { - mlt_log_debug( MLT_FILTER_SERVICE(filter), "channels %d samples %d frequency %d -> %d\n", - *channels, *samples, *frequency, output_rate ); + // Noting to convert. No error message needed. + return error; + } + + if( *frequency == out.frequency && !pdata ) + { + // No frequency change, and there is no stored state. + return error; + } + // *Proceed to convert the sampling frequency* + + // The converter operates on interleaved float. Convert the samples if necessary + if ( *format != mlt_audio_f32le ) + { // Do not convert to float unless we need to change the rate - if ( *format != mlt_audio_f32le ) - frame->convert_audio( frame, buffer, format, mlt_audio_f32le ); + frame->convert_audio( frame, buffer, format, mlt_audio_f32le ); + } + + // Set up audio structures and allocate output buffer + mlt_audio_set_values( &in, *buffer, *frequency, *format, *samples, *channels ); + out.format = in.format; + out.channels = in.channels; + mlt_audio_alloc_data( &out ); + mlt_log_debug( MLT_FILTER_SERVICE(filter), "%dHz -> %dHz\n", in.frequency, out.frequency ); + + mlt_service_lock( MLT_FILTER_SERVICE(filter) ); + + // Create the private data if it does not exist + if ( !pdata ) + { + pdata = (private_data*)calloc( 1, sizeof(private_data) ); + pdata->s = NULL; + pdata->channels = 0; + pdata->leftover_samples = 0; + filter->child = pdata; + } - mlt_service_lock( MLT_FILTER_SERVICE(filter) ); + // Recreate the resampler if necessary + if ( !pdata->s || pdata->channels != in.channels ) + { + mlt_log_debug( MLT_FILTER_SERVICE(filter), "Create resample state %d channels\n", in.channels ); + pdata->s = src_delete( pdata->s ); + pdata->s = src_new( SRC_SINC_BEST_QUALITY, in.channels, &pdata->error ); + pdata->channels = in.channels; + } + + int total_consumed_samples = 0; + int consumed_samples = 0; + int received_samples = 0; + int process_buff_samples = PROCESS_BUFF_SIZE / sizeof(float) / in.channels; + + // First copy samples that are leftover from the previous frame + if ( pdata->leftover_samples ) + { + int samples_to_copy = pdata->leftover_samples; + if ( samples_to_copy > out.samples ) + { + samples_to_copy = out.samples; + } + memcpy( out.data, pdata->buff, samples_to_copy * out.channels * sizeof(float) ); + received_samples += samples_to_copy; + pdata->leftover_samples -= samples_to_copy; + } + + // Process all input samples + while ( total_consumed_samples < in.samples || received_samples < out.samples ) + { + if ( pdata->leftover_samples ) + { + mlt_log_error( MLT_FILTER_SERVICE(filter), "Discard leftover samples %d\n", pdata->leftover_samples ); + pdata->leftover_samples = 0; + } + + if ( consumed_samples >= in.samples ) + { + // Continue to repeat input samples into the resampler until it + // provides the desired number of samples out. + consumed_samples = 0; + mlt_log_debug( MLT_FILTER_SERVICE(filter), "Repeat samples\n"); + } SRC_DATA data; - data.data_in = *buffer; - data.data_out = mlt_properties_get_data( filter_properties, "output_buffer", NULL ); - data.src_ratio = ( float ) output_rate / ( float ) *frequency; - data.input_frames = *samples; - data.output_frames = BUFFER_LEN / sizeof(float) / *channels; data.end_of_input = 0; - - SRC_STATE *state = mlt_properties_get_data( filter_properties, "state", NULL ); - if ( !state || mlt_properties_get_int( filter_properties, "channels" ) != *channels ) + data.src_ratio = (double)out.frequency / (double)in.frequency; + data.data_in = (float*)in.data + (consumed_samples * in.channels); + data.input_frames = in.samples - consumed_samples; + data.data_out = pdata->buff; + data.output_frames = process_buff_samples; + if ( total_consumed_samples >= in.samples ) { - // Recreate the resampler if the number of channels changed - state = src_new( RESAMPLE_TYPE, *channels, &error ); - mlt_properties_set_data( filter_properties, "state", state, 0, (mlt_destructor) src_delete, NULL ); - mlt_properties_set_int( filter_properties, "channels", *channels ); + // All input samples have been read once. + // Limit the output frames to the minimum necessary to fill the output frame. + // Limit the input frames to 1 at a time to minimize the duplicated samples. + // Sometimes one input frame can cause many frames to be output from the resampler. + data.input_frames = 1; + if ( data.output_frames > (out.samples - received_samples) ) + { + data.output_frames = out.samples - received_samples; + } } // Resample the audio - src_set_ratio ( state, ( double ) output_rate / ( double ) *frequency ); - error = src_process( state, &data ); - if ( !error ) + src_set_ratio ( pdata->s, data.src_ratio ); + error = src_process( pdata->s, &data ); + if ( error ) + { + mlt_log_error( MLT_FILTER_SERVICE( filter ), "%s %d,%d,%d\n", src_strerror( error ), in.frequency, in.samples, out.frequency ); + break; + } + + // Copy resampled samples from buff to output + if ( data.output_frames_gen ) { - if (data.output_frames_gen < requested_samples) + float* dst = (float*)out.data + (received_samples * out.channels); + int samples_to_copy = data.output_frames_gen; + if ( samples_to_copy > (out.samples - received_samples) ) { - // Duplicate samples to provide the exact requested number of samples to help maintain lipsync. - int bytes_to_copy = data.output_frames_gen * sizeof(float) * *channels; - int byte_offset = (requested_samples* sizeof(float) * *channels) - bytes_to_copy; - if( data.output_frames_gen + byte_offset < BUFFER_LEN ) - { - memmove ( data.data_out + byte_offset, data.data_out, bytes_to_copy ); - data.output_frames_gen += byte_offset; - } + samples_to_copy = out.samples - received_samples; } - else if (data.output_frames_gen > requested_samples) + int bytes_to_copy = samples_to_copy * out.channels * sizeof(float); + memcpy( dst, pdata->buff, bytes_to_copy ); + if ( samples_to_copy < data.output_frames_gen ) { - // Drop samples to provide the exact requested number of samples. - data.output_frames_gen = requested_samples; + // Move leftover samples to the beginning of buff to use next time + pdata->leftover_samples = data.output_frames_gen - samples_to_copy; + float* src = pdata->buff + (samples_to_copy * out.channels); + memmove ( pdata->buff, src , pdata->leftover_samples * out.channels * sizeof(float) ); } - // Update output variables - *samples = data.output_frames_gen; - *frequency = output_rate; - *buffer = data.data_out; - } - else - { - mlt_log_error( MLT_FILTER_SERVICE( filter ), "%s %d,%d,%d\n", src_strerror( error ), *frequency, *samples, output_rate ); + received_samples += samples_to_copy; } - mlt_service_unlock( MLT_FILTER_SERVICE(filter) ); + consumed_samples += data.input_frames_used; + total_consumed_samples += data.input_frames_used; } + mlt_frame_set_audio( frame, out.data, out.format, 0, out.release_data ); + mlt_audio_get_values( &out, buffer, frequency, format, samples, channels ); + + mlt_service_unlock( MLT_FILTER_SERVICE(filter) ); + return error; } /** Filter processing. */ -static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) +static mlt_frame filter_process( mlt_filter filter, mlt_frame frame ) { if ( mlt_frame_is_test_audio( frame ) == 0 ) { - mlt_frame_push_audio( frame, this ); + mlt_frame_push_audio( frame, filter ); mlt_frame_push_audio( frame, resample_get_audio ); } return frame; } +static void close_filter( mlt_filter filter ) +{ + private_data* pdata = (private_data*)filter->child; + if ( pdata ) + { + if ( pdata->s ) + { + src_delete( pdata->s ); + } + free( pdata ); + filter->child = NULL; + } +} + /** Constructor for the filter. */ mlt_filter filter_resample_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) { - mlt_filter this = mlt_filter_new( ); - if ( this != NULL ) + mlt_filter filter = mlt_filter_new(); + + if( filter ) { - int error; - SRC_STATE *state = src_new( RESAMPLE_TYPE, 2 /* channels */, &error ); - if ( error == 0 ) - { - void *output_buffer = mlt_pool_alloc( BUFFER_LEN ); - this->process = filter_process; - if ( arg != NULL ) - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "frequency", atoi( arg ) ); - mlt_properties_set_int( MLT_FILTER_PROPERTIES( this ), "channels", 2 ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "state", state, 0, (mlt_destructor)src_delete, NULL ); - mlt_properties_set_data( MLT_FILTER_PROPERTIES( this ), "output_buffer", output_buffer, BUFFER_LEN, mlt_pool_release, NULL ); - } - else - { - fprintf( stderr, "filter_resample_init: %s\n", src_strerror( error ) ); - } + filter->process = filter_process; + filter->close = close_filter; + filter->child = NULL; + } + else + { + mlt_log_error( MLT_FILTER_SERVICE(filter), "Failed to initialize\n" ); } - return this; + return filter; } From 4988c60073c8deb0bce1dd26e7107f0d8ba779ed Mon Sep 17 00:00:00 2001 From: Dan Dennedy Date: Sun, 4 Apr 2021 23:44:42 -0700 Subject: [PATCH 115/122] fix cmake linking errors on macOS --- src/modules/decklink/CMakeLists.txt | 1 + src/modules/movit/CMakeLists.txt | 2 +- src/modules/plusgpl/CMakeLists.txt | 2 +- src/modules/rtaudio/CMakeLists.txt | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/modules/decklink/CMakeLists.txt b/src/modules/decklink/CMakeLists.txt index 8c6a74166..36580f0d6 100644 --- a/src/modules/decklink/CMakeLists.txt +++ b/src/modules/decklink/CMakeLists.txt @@ -13,6 +13,7 @@ if(WIN32) elseif(APPLE) target_sources(mltdecklink PRIVATE darwin/DeckLinkAPIDispatch.cpp) target_include_directories(mltdecklink PRIVATE darwin) + target_link_libraries(mltdecklink PRIVATE "-framework CoreFoundation") else() target_sources(mltdecklink PRIVATE linux/DeckLinkAPIDispatch.cpp) target_include_directories(mltdecklink PRIVATE linux) diff --git a/src/modules/movit/CMakeLists.txt b/src/modules/movit/CMakeLists.txt index eb05c64d4..ead3120a5 100644 --- a/src/modules/movit/CMakeLists.txt +++ b/src/modules/movit/CMakeLists.txt @@ -1,5 +1,4 @@ add_library(mltmovit MODULE - consumer_xgl.c factory.c filter_glsl_manager.cpp filter_movit_blur.cpp @@ -32,6 +31,7 @@ endif() target_link_libraries(mltmovit PRIVATE m Threads::Threads mlt mlt++ OpenGL::GL PkgConfig::movit) if(UNIX AND NOT APPLE) + target_sources(mltmovit PRIVATE consumer_xgl.c) target_link_libraries(mltmovit PRIVATE X11::X11) endif() diff --git a/src/modules/plusgpl/CMakeLists.txt b/src/modules/plusgpl/CMakeLists.txt index 0069dfebc..d5f63e044 100644 --- a/src/modules/plusgpl/CMakeLists.txt +++ b/src/modules/plusgpl/CMakeLists.txt @@ -16,7 +16,7 @@ target_link_libraries(mltplusgpl PRIVATE mlt m Threads::Threads) if(WIN32) target_link_libraries(mltplusgpl PRIVATE ws2_32) -elseif(UNIX) +elseif(UNIX AND NOT APPLE) target_link_libraries(mltplusgpl PRIVATE rt) endif() diff --git a/src/modules/rtaudio/CMakeLists.txt b/src/modules/rtaudio/CMakeLists.txt index 3194c9bc9..bd0d77a30 100644 --- a/src/modules/rtaudio/CMakeLists.txt +++ b/src/modules/rtaudio/CMakeLists.txt @@ -10,7 +10,7 @@ else() target_sources(mltrtaudio PRIVATE RtAudio.cpp) target_include_directories(mltrtaudio PRIVATE .) if(APPLE) - target_link_libraries(mltrtaudio PRIVATE CoreAudio CoreFoundation) + target_link_libraries(mltrtaudio PRIVATE "-framework CoreAudio" "-framework CoreFoundation") target_compile_definitions(mltrtaudio PRIVATE __MACOSX_CORE__) elseif(WIN32) target_link_libraries(mltrtaudio PRIVATE ole32 dsound winmm ksuser) From a3c2bd8c178a9fc77f0d32ed8765bb810d2890f9 Mon Sep 17 00:00:00 2001 From: eszlari Date: Mon, 5 Apr 2021 18:47:49 +0200 Subject: [PATCH 116/122] cmake: melt: create relative symlink (#694) --- CMakeLists.txt | 4 ++-- src/melt/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 09d678e46..16c26ab35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -435,8 +435,8 @@ install(DIRECTORY presets profiles DESTINATION ${MLT_INSTALL_DATA_DIR}) if(UNIX AND NOT APPLE) install(FILES docs/melt.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 RENAME melt-${MLT_VERSION_MAJOR}.1) - install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \ - ${CMAKE_INSTALL_FULL_MANDIR}/man1/melt-${MLT_VERSION_MAJOR}.1 ${CMAKE_INSTALL_FULL_MANDIR}/man1/melt.1)" + install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink melt-${MLT_VERSION_MAJOR}.1 melt.1 \ + WORKING_DIRECTORY ${CMAKE_INSTALL_FULL_MANDIR}/man1)" ) endif() diff --git a/src/melt/CMakeLists.txt b/src/melt/CMakeLists.txt index 439c38f8e..921edd06e 100644 --- a/src/melt/CMakeLists.txt +++ b/src/melt/CMakeLists.txt @@ -22,7 +22,7 @@ if(WIN32 OR APPLE) install(TARGETS melt RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) else() install(PROGRAMS "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/melt" DESTINATION ${CMAKE_INSTALL_BINDIR} RENAME melt-${MLT_VERSION_MAJOR}) - install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink \ - ${CMAKE_INSTALL_FULL_BINDIR}/melt-${MLT_VERSION_MAJOR} ${CMAKE_INSTALL_FULL_BINDIR}/melt)" + install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink melt-${MLT_VERSION_MAJOR} melt \ + WORKING_DIRECTORY ${CMAKE_INSTALL_FULL_BINDIR})" ) endif() From 81bb4b38ffc2470be78c7ebf2035f091f88ac19e Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 6 Apr 2021 20:54:54 +0200 Subject: [PATCH 117/122] cmake: use same soname as gmake --- src/framework/CMakeLists.txt | 4 ++-- src/mlt++/CMakeLists.txt | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/framework/CMakeLists.txt b/src/framework/CMakeLists.txt index 3c1602e48..91e32d45d 100644 --- a/src/framework/CMakeLists.txt +++ b/src/framework/CMakeLists.txt @@ -78,8 +78,8 @@ target_include_directories(mlt PUBLIC ) set_target_properties(mlt PROPERTIES - VERSION 1.${MLT_VERSION_MINOR}.${MLT_VERSION_PATCH} - SOVERSION 1 + VERSION ${MLT_VERSION} + SOVERSION ${MLT_VERSION_MAJOR} OUTPUT_NAME mlt-${MLT_VERSION_MAJOR} PUBLIC_HEADER "${MLT_PUPLIC_HEADERS}" ) diff --git a/src/mlt++/CMakeLists.txt b/src/mlt++/CMakeLists.txt index ec0f15c44..c5e5b6c0c 100644 --- a/src/mlt++/CMakeLists.txt +++ b/src/mlt++/CMakeLists.txt @@ -70,8 +70,8 @@ target_include_directories(mlt++ PUBLIC ) set_target_properties(mlt++ PROPERTIES - VERSION 1.${MLT_VERSION_MINOR}.${MLT_VERSION_PATCH} - SOVERSION 1 + VERSION ${MLT_VERSION} + SOVERSION ${MLT_VERSION_MAJOR} OUTPUT_NAME mlt++-${MLT_VERSION_MAJOR} PUBLIC_HEADER "${MLTPP_PUPLIC_HEADERS}" ) From 5561a743dd98ad70f6a535d081a52f50b86ecf1f Mon Sep 17 00:00:00 2001 From: Peter Eszlari Date: Tue, 6 Apr 2021 20:56:52 +0200 Subject: [PATCH 118/122] cmake: fix movit data dir --- src/modules/movit/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/movit/CMakeLists.txt b/src/modules/movit/CMakeLists.txt index ead3120a5..cd4e84351 100644 --- a/src/modules/movit/CMakeLists.txt +++ b/src/modules/movit/CMakeLists.txt @@ -58,5 +58,5 @@ install(FILES transition_movit_luma.yml transition_movit_mix.yml transition_movit_overlay.yml - DESTINATION ${MLT_INSTALL_DATA_DIR}/opengl + DESTINATION ${MLT_INSTALL_DATA_DIR}/movit ) From c7d4c55d265d8d4b1ea102486cfccb8a4faef5b2 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Thu, 8 Apr 2021 22:23:20 -0500 Subject: [PATCH 119/122] Add pitch compensation to timeremap link This adds a new "stretch" parameter to rbpitch which is used by timeremap to perform the pitch compensation and resampling in one step rather than requiring a separate resampling step after pitch compensation. --- src/framework/mlt_link.h | 2 + src/modules/core/link_timeremap.c | 303 +++++++++++++--------- src/modules/rubberband/filter_rbpitch.cpp | 20 +- src/modules/rubberband/filter_rbpitch.yml | 9 + 4 files changed, 216 insertions(+), 118 deletions(-) diff --git a/src/framework/mlt_link.h b/src/framework/mlt_link.h index faaa72a33..802f63853 100644 --- a/src/framework/mlt_link.h +++ b/src/framework/mlt_link.h @@ -61,6 +61,8 @@ struct mlt_link_s /** \privatesection */ mlt_producer next; + /** the object of a subclass */ + void *child; }; #define MLT_LINK_PRODUCER( link ) ( &( link )->parent ) diff --git a/src/modules/core/link_timeremap.c b/src/modules/core/link_timeremap.c index 24d1882c9..a5c0fa257 100644 --- a/src/modules/core/link_timeremap.c +++ b/src/modules/core/link_timeremap.c @@ -27,6 +27,14 @@ #include #include +// Private Types +typedef struct +{ + mlt_frame prev_frame; + mlt_filter resample_filter; + mlt_filter pitch_filter; +} private_data; + static void link_configure( mlt_link self, mlt_profile chain_profile ) { // Timeremap must always work with the same profile as the chain so that @@ -36,7 +44,10 @@ static void link_configure( mlt_link self, mlt_profile chain_profile ) static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* format, int* frequency, int* channels, int* samples ) { + int requested_frequency = *frequency; + int requested_samples = *samples; mlt_link self = (mlt_link)mlt_frame_pop_audio( frame ); + private_data* pdata = (private_data*)self->child; mlt_properties unique_properties = mlt_frame_get_unique_properties( frame, MLT_LINK_SERVICE(self) ); if ( !unique_properties ) { @@ -72,120 +83,161 @@ static int link_get_audio( mlt_frame frame, void** audio, mlt_audio_format* form mlt_frame_set_audio( frame, *audio, *format, size, mlt_pool_release ); return 0; } - else + + // Calculate the samples to get from the input frames + int link_sample_count = mlt_audio_calculate_frame_samples( link_fps, *frequency, mlt_frame_get_position( frame ) ); + int sample_count = lrint( (double)link_sample_count * source_speed ); + mlt_position in_frame_pos = floor( source_time * source_fps ); + int64_t first_out_sample = llrint(source_time * (double)*frequency); + + // Attempt to maintain sample continuity with the previous frame + static const int64_t SAMPLE_CONTINUITY_ERROR_MARGIN = 4; + int64_t continuity_sample = mlt_properties_get_int64( MLT_LINK_PROPERTIES( self ), "_continuity_sample" ); + int64_t continuity_delta = continuity_sample - first_out_sample; + if ( source_duration > 0.0 && continuity_delta != 0 ) { - // Calculate the samples to get from the input frames - int link_sample_count = mlt_audio_calculate_frame_samples( link_fps, *frequency, mlt_frame_get_position( frame ) ); - int sample_count = lrint( (double)link_sample_count * source_speed ); - mlt_position in_frame_pos = floor( source_time * source_fps ); - int64_t first_out_sample = llrint(source_time * (double)*frequency); - - // Attempt to maintain sample continuity with the previous frame - static const int64_t SAMPLE_CONTINUITY_ERROR_MARGIN = 4; - int64_t continuity_sample = mlt_properties_get_int64( MLT_LINK_PROPERTIES( self ), "_continuity_sample" ); - int64_t continuity_delta = continuity_sample - first_out_sample; - if ( source_duration > 0.0 && continuity_delta != 0 ) + // Forward: Continue from where the previous frame left off if within the margin of error + if ( continuity_delta > -SAMPLE_CONTINUITY_ERROR_MARGIN && continuity_delta < SAMPLE_CONTINUITY_ERROR_MARGIN ) { - // Forward: Continue from where the previous frame left off if within the margin of error - if ( continuity_delta > -SAMPLE_CONTINUITY_ERROR_MARGIN && continuity_delta < SAMPLE_CONTINUITY_ERROR_MARGIN ) - { - sample_count = sample_count - continuity_delta; - first_out_sample = continuity_sample; - mlt_log_debug( MLT_LINK_SERVICE(self), "Maintain Forward Continuity: %d\n", (int)continuity_delta ); - } + sample_count = sample_count - continuity_delta; + first_out_sample = continuity_sample; + mlt_log_debug( MLT_LINK_SERVICE(self), "Maintain Forward Continuity: %d\n", (int)continuity_delta ); } - else if ( source_duration < 0.0 && continuity_delta != sample_count ) + } + else if ( source_duration < 0.0 && continuity_delta != sample_count ) + { + // Reverse: End where the previous frame left off if within the margin of error + continuity_delta -= sample_count; + if ( continuity_delta > -SAMPLE_CONTINUITY_ERROR_MARGIN && continuity_delta < SAMPLE_CONTINUITY_ERROR_MARGIN ) { - // Reverse: End where the previous frame left off if within the margin of error - continuity_delta -= sample_count; - if ( continuity_delta > -SAMPLE_CONTINUITY_ERROR_MARGIN && continuity_delta < SAMPLE_CONTINUITY_ERROR_MARGIN ) - { - sample_count = sample_count + continuity_delta; - mlt_log_debug( MLT_LINK_SERVICE(self), "Maintain Reverse Continuity: %d\n", (int)continuity_delta ); - } + sample_count = sample_count + continuity_delta; + mlt_log_debug( MLT_LINK_SERVICE(self), "Maintain Reverse Continuity: %d\n", (int)continuity_delta ); } + } + + int64_t first_in_sample = mlt_audio_calculate_samples_to_position( source_fps, *frequency, in_frame_pos ); + int samples_to_skip = first_out_sample - first_in_sample; + if ( samples_to_skip < 0 ) + { + mlt_log_error( MLT_LINK_SERVICE(self), "Audio too late: %d\t%d\n", (int)first_out_sample, (int)first_in_sample ); + samples_to_skip = 0; + } + + // Allocate the out buffer + struct mlt_audio_s out; + mlt_audio_set_values( &out, NULL, *frequency, *format, sample_count, *channels ); + mlt_audio_alloc_data( &out ); + + // Copy audio from the input frames to the output buffer + int samples_copied = 0; + int samples_needed = sample_count; - int64_t first_in_sample = mlt_audio_calculate_samples_to_position( source_fps, *frequency, in_frame_pos ); - int samples_to_skip = first_out_sample - first_in_sample; - if ( samples_to_skip < 0 ) + while ( samples_needed > 0 ) + { + char key[19]; + sprintf( key, "%d", in_frame_pos ); + mlt_frame src_frame = (mlt_frame)mlt_properties_get_data( unique_properties, key, NULL ); + if ( !src_frame ) { - mlt_log_error( MLT_LINK_SERVICE(self), "Audio too late: %d\t%d\n", (int)first_out_sample, (int)first_in_sample ); - samples_to_skip = 0; + mlt_log_error( MLT_LINK_SERVICE(self), "Frame not found: %d\n", in_frame_pos ); + break; } - // Allocate the out buffer - struct mlt_audio_s out; - mlt_audio_set_values( &out, NULL, *frequency, *format, sample_count, *channels ); - mlt_audio_alloc_data( &out ); + int in_samples = mlt_audio_calculate_frame_samples( source_fps, *frequency, in_frame_pos ); + struct mlt_audio_s in; + mlt_audio_set_values( &in, NULL, *frequency, *format, in_samples, *channels ); - // Copy audio from the input frames to the output buffer - int samples_copied = 0; - int samples_needed = sample_count; + int error = mlt_frame_get_audio( src_frame, &in.data, &in.format, &in.frequency, &in.channels, &in.samples ); + if ( error ) + { + mlt_log_error( MLT_LINK_SERVICE(self), "No audio: %d\n", in_frame_pos ); + break; + } - while ( samples_needed > 0 ) + int samples_to_copy = in.samples - samples_to_skip; + if ( samples_to_copy > samples_needed ) { - char key[19]; - sprintf( key, "%d", in_frame_pos ); - mlt_frame src_frame = (mlt_frame)mlt_properties_get_data( unique_properties, key, NULL ); - if ( !src_frame ) - { - mlt_log_error( MLT_LINK_SERVICE(self), "Frame not found: %d\n", in_frame_pos ); - break; - } + samples_to_copy = samples_needed; + } + mlt_log_debug( MLT_LINK_SERVICE(self), "Copy: %d\t%d\t%d\t%d\n", samples_to_skip, samples_to_skip + samples_to_copy -1, samples_to_copy, in.samples ); - int in_samples = mlt_audio_calculate_frame_samples( source_fps, *frequency, in_frame_pos ); - struct mlt_audio_s in; - mlt_audio_set_values( &in, NULL, *frequency, *format, in_samples, *channels ); + if ( samples_to_copy > 0 ) + { + mlt_audio_copy( &out, &in, samples_to_copy, samples_to_skip, samples_copied ); + samples_copied += samples_to_copy; + samples_needed -= samples_to_copy; + } - int error = mlt_frame_get_audio( src_frame, &in.data, &in.format, &in.frequency, &in.channels, &in.samples ); - if ( error ) - { - mlt_log_error( MLT_LINK_SERVICE(self), "No audio: %d\n", in_frame_pos ); - break; - } + samples_to_skip = 0; + in_frame_pos++; + } - int samples_to_copy = in.samples - samples_to_skip; - if ( samples_to_copy > samples_needed ) - { - samples_to_copy = samples_needed; - } - mlt_log_debug( MLT_LINK_SERVICE(self), "Copy: %d\t%d\t%d\t%d\n", samples_to_skip, samples_to_skip + samples_to_copy -1, samples_to_copy, in.samples ); + if ( samples_copied != sample_count ) + { + mlt_log_error( MLT_LINK_SERVICE(self), "Sample under run: %d\t%d\n", samples_copied, sample_count ); + mlt_audio_shrink( &out , samples_copied ); + } - if ( samples_to_copy > 0 ) - { - mlt_audio_copy( &out, &in, samples_to_copy, samples_to_skip, samples_copied ); - samples_copied += samples_to_copy; - samples_needed -= samples_to_copy; - } + if ( source_duration < 0.0 ) + { + // Going backwards + mlt_audio_reverse( &out ); + mlt_properties_set_int64( MLT_LINK_PROPERTIES( self ), "_continuity_sample", first_out_sample ); + } + else + { + mlt_properties_set_int64( MLT_LINK_PROPERTIES( self ), "_continuity_sample", first_out_sample + sample_count ); + } - samples_to_skip = 0; - in_frame_pos++; + int in_frequency = *frequency; + out.frequency = lrint( (double)out.frequency * (double)sample_count / (double)link_sample_count ); + mlt_frame_set_audio( frame, out.data, out.format, 0, out.release_data ); + mlt_audio_get_values( &out, audio, frequency, format, samples, channels ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "audio_frequency", *frequency ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "audio_channels", *channels ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "audio_samples", *samples ); + mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "audio_format", *format ); + + // Apply pitch compensation if requested + int pitch_compensate = mlt_properties_get_int( MLT_LINK_PROPERTIES( self ), "pitch" ); + if ( pitch_compensate ) + { + if ( !pdata->pitch_filter ) + { + pdata->pitch_filter = mlt_factory_filter( mlt_service_profile( MLT_LINK_SERVICE( self ) ), "rbpitch", NULL ); } - - if ( samples_copied != sample_count ) + if ( pdata->pitch_filter ) { - mlt_log_error( MLT_LINK_SERVICE(self), "Sample under run: %d\t%d\n", samples_copied, sample_count ); - mlt_audio_shrink( &out , samples_copied ); + mlt_properties_set_int( MLT_FILTER_PROPERTIES(pdata->pitch_filter), "stretch", 1 ); + // Set the pitchscale to compensate for the difference between the input sampling frequency and the requested sampling frequency. + double pitchscale = (double)in_frequency / (double)requested_frequency; + mlt_properties_set_double( MLT_FILTER_PROPERTIES(pdata->pitch_filter), "pitchscale", pitchscale ); + mlt_filter_process( pdata->pitch_filter, frame ); } - - if ( source_duration < 0.0 ) + } + // Apply a resampler if rbpitch is not stretching to provide + if ( !pitch_compensate || !pdata->pitch_filter ) + { + if ( !pdata->resample_filter ) { - // Going backwards - mlt_audio_reverse( &out ); - mlt_properties_set_int64( MLT_LINK_PROPERTIES( self ), "_continuity_sample", first_out_sample ); + pdata->resample_filter = mlt_factory_filter( mlt_service_profile( MLT_LINK_SERVICE(self) ), "resample", NULL ); + if ( !pdata->resample_filter ) + { + pdata->resample_filter = mlt_factory_filter( mlt_service_profile( MLT_LINK_SERVICE(self) ), "swresample", NULL ); + } } - else + if ( pdata->resample_filter ) { - mlt_properties_set_int64( MLT_LINK_PROPERTIES( self ), "_continuity_sample", first_out_sample + sample_count ); + mlt_filter_process( pdata->resample_filter, frame ); } - - out.frequency = lrint( (double)out.frequency * (double)sample_count / (double)link_sample_count ); - mlt_frame_set_audio( frame, out.data, out.format, 0, out.release_data ); - mlt_audio_get_values( &out, audio, frequency, format, samples, channels ); - return 0; } - return 1; + // Final call to get_audio() to apply the pitch or resample filter + *frequency = requested_frequency; + *samples = requested_samples; + int error = mlt_frame_get_audio( frame, audio, format, frequency, channels, samples ); + + return error; } static int link_get_image_blend( mlt_frame frame, uint8_t** image, mlt_image_format* format, int* width, int* height, int writable ) @@ -300,6 +352,7 @@ static int link_get_image_nearest( mlt_frame frame, uint8_t** image, mlt_image_f static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) { mlt_properties properties = MLT_LINK_PROPERTIES( self ); + private_data* pdata = (private_data*)self->child; mlt_position position = mlt_producer_position( MLT_LINK_PRODUCER( self ) ); mlt_position length = mlt_producer_get_length( MLT_LINK_PRODUCER( self ) ); double source_time = 0.0; @@ -347,8 +400,7 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) // Get frames from the next link and pass them along with the new frame int in_frame_count = 0; mlt_frame src_frame = NULL; - mlt_frame prev_frame = mlt_properties_get_data( properties, "_prev_frame", NULL ); - mlt_position prev_frame_position = prev_frame ? mlt_frame_get_position( prev_frame ) : -1; + mlt_position prev_frame_position = pdata->prev_frame ? mlt_frame_get_position( pdata->prev_frame ) : -1; mlt_position in_frame_pos = floor( source_time * source_fps ); double frame_time = (double)in_frame_pos / source_fps; double source_end_time = source_time + fabs(source_duration); @@ -362,7 +414,7 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) if( in_frame_pos == prev_frame_position ) { // Reuse the previous frame to avoid seeking. - src_frame = prev_frame; + src_frame = pdata->prev_frame; mlt_properties_inc_ref( MLT_FRAME_PROPERTIES(src_frame) ); } else @@ -397,11 +449,12 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) (*frame)->convert_audio = src_frame->convert_audio; mlt_properties_pass_list( MLT_FRAME_PROPERTIES(*frame), MLT_FRAME_PROPERTIES(src_frame), "audio_frequency" ); - if ( src_frame != prev_frame ) + if ( src_frame != pdata->prev_frame ) { // Save the last source frame because it might be requested for the next frame. + mlt_frame_close( pdata->prev_frame ); mlt_properties_inc_ref( MLT_FRAME_PROPERTIES(src_frame) ); - mlt_properties_set_data( properties, "_prev_frame", src_frame, 0, (mlt_destructor)mlt_frame_close, NULL ); + pdata->prev_frame = src_frame; } // Setup callbacks @@ -419,25 +472,6 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) mlt_frame_push_audio( *frame, (void*)self ); mlt_frame_push_audio( *frame, link_get_audio ); - // Apply a resampler - mlt_filter resampler = (mlt_filter)mlt_properties_get_data( properties, "_resampler", NULL ); - if ( !resampler ) - { - resampler = mlt_factory_filter( mlt_service_profile( MLT_LINK_SERVICE(self) ), "resample", NULL ); - if ( !resampler ) - { - resampler = mlt_factory_filter( mlt_service_profile( MLT_LINK_SERVICE(self) ), "swresample", NULL ); - } - if( resampler ) - { - mlt_properties_set_data( properties, "_resampler", resampler, 0, (mlt_destructor)mlt_filter_close, NULL ); - } - } - if ( resampler ) - { - mlt_filter_process( resampler, *frame ); - } - mlt_producer_prepare_next( MLT_LINK_PRODUCER( self ) ); mlt_properties_set_double( properties, "speed", source_speed ); @@ -446,20 +480,57 @@ static int link_get_frame( mlt_link self, mlt_frame_ptr frame, int index ) static void link_close( mlt_link self ) { - self->close = NULL; - mlt_link_close( self ); - free( self ); + if ( self ) + { + private_data* pdata = (private_data*)self->child; + if ( pdata ) + { + if ( pdata->prev_frame ) + { + mlt_frame_close( pdata->prev_frame ); + } + if ( pdata->resample_filter ) + { + mlt_filter_close( pdata->resample_filter ); + } + if ( pdata->pitch_filter ) + { + mlt_filter_close( pdata->pitch_filter ); + } + free( pdata ); + } + self->close = NULL; + mlt_link_close( self ); + free( self ); + } } mlt_link link_timeremap_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) { mlt_link self = mlt_link_init(); - if ( self != NULL ) + private_data* pdata = (private_data*)calloc( 1, sizeof(private_data) ); + + if ( self && pdata ) { + self->child = pdata; + // Callback registration self->configure = link_configure; self->get_frame = link_get_frame; self->close = link_close; } + else + { + if ( pdata ) + { + free( pdata ); + } + + if ( self ) + { + mlt_link_close( self ); + self = NULL; + } + } return self; } diff --git a/src/modules/rubberband/filter_rbpitch.cpp b/src/modules/rubberband/filter_rbpitch.cpp index edac25203..525fb94a7 100644 --- a/src/modules/rubberband/filter_rbpitch.cpp +++ b/src/modules/rubberband/filter_rbpitch.cpp @@ -50,7 +50,6 @@ static int rbpitch_get_audio( mlt_frame frame, void **buffer, mlt_audio_format * return mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); } - int requested_samples = *samples; mlt_properties unique_properties = mlt_frame_get_unique_properties( frame, MLT_FILTER_SERVICE(filter) ); if ( !unique_properties ) { @@ -59,6 +58,8 @@ static int rbpitch_get_audio( mlt_frame frame, void **buffer, mlt_audio_format * } // Get the producer's audio + int requested_frequency = *frequency; + int requested_samples = *samples; *format = mlt_audio_float; int error = mlt_frame_get_audio( frame, buffer, format, frequency, channels, samples ); if ( error ) return error; @@ -79,7 +80,15 @@ static int rbpitch_get_audio( mlt_frame frame, void **buffer, mlt_audio_format * // the future. double pitchscale = mlt_properties_get_double( unique_properties, "pitchscale" ); pitchscale = CLAMP( pitchscale, 0.05, 50.0 ); - int rubberband_frequency = CLAMP( *frequency, 10000, 300000 ); + double timeratio = 1.0; + int stretch = mlt_properties_get_int( unique_properties, "stretch" ); + int rubberband_frequency = *frequency; + if( stretch ) + { + rubberband_frequency = requested_frequency; + timeratio = (double)requested_samples / (double)*samples; + } + rubberband_frequency = CLAMP( rubberband_frequency, 10000, 300000 ); // Protect the RubberBandStretcher instance. mlt_service_lock( MLT_FILTER_SERVICE(filter) ); @@ -113,6 +122,7 @@ static int rbpitch_get_audio( mlt_frame frame, void **buffer, mlt_audio_format * s->setPitchOption(RubberBandStretcher::OptionPitchHighConsistency); s->setTransientsOption(RubberBandStretcher::OptionTransientsSmooth); } + s->setTimeRatio( timeratio ); // Configure input and output buffers and counters. int consumed_samples = 0; @@ -121,6 +131,11 @@ static int rbpitch_get_audio( mlt_frame frame, void **buffer, mlt_audio_format * struct mlt_audio_s in; struct mlt_audio_s out; mlt_audio_set_values( &in, *buffer, *frequency, *format, *samples, *channels ); + if( stretch ) + { + *frequency = requested_frequency; + *samples = requested_samples; + } mlt_audio_set_values( &out, NULL, *frequency, *format, *samples, *channels ); mlt_audio_alloc_data( &out ); @@ -218,6 +233,7 @@ static mlt_frame filter_process( mlt_filter filter, mlt_frame frame ) // Save the pitchscale on the frame to be used in rbpitch_get_audio mlt_properties unique_properties = mlt_frame_unique_properties( frame, MLT_FILTER_SERVICE(filter) ); mlt_properties_set_double( unique_properties, "pitchscale", pitchscale ); + mlt_properties_set_int( unique_properties, "stretch", mlt_properties_get_int( filter_properties, "stretch" ) ); mlt_frame_push_audio( frame, (void*)filter ); mlt_frame_push_audio( frame, (void*)rbpitch_get_audio ); diff --git a/src/modules/rubberband/filter_rbpitch.yml b/src/modules/rubberband/filter_rbpitch.yml index 85de27ebf..563251477 100644 --- a/src/modules/rubberband/filter_rbpitch.yml +++ b/src/modules/rubberband/filter_rbpitch.yml @@ -46,6 +46,15 @@ parameters: minimum: 0.1 maximum: 10 + - identifier: stretch + title: Stretch + type: boolean + description: > + Stretch the audio to fill the requested samples. This option will have no + effect if the requested sample size is the same as the received sample + size. + readonly: yes + - identifier: latency title: Latency type: float From 3c2fee94f983e75d538ce264340996b55f61bd2c Mon Sep 17 00:00:00 2001 From: Vincent Pinon Date: Sun, 11 Apr 2021 21:01:39 +0200 Subject: [PATCH 120/122] Fix building frei0r module in KDE Craft --- src/modules/frei0r/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/frei0r/CMakeLists.txt b/src/modules/frei0r/CMakeLists.txt index 4af3914c5..4e86cbd47 100644 --- a/src/modules/frei0r/CMakeLists.txt +++ b/src/modules/frei0r/CMakeLists.txt @@ -8,6 +8,7 @@ add_library(mltfrei0r MODULE ) target_compile_options(mltfrei0r PRIVATE ${MLT_COMPILE_OPTIONS}) +target_include_directories(mltfrei0r PRIVATE ${FREI0R_INCLUDE_DIRS}) if(APPLE AND RELOCATABLE) target_compile_definitions(mltfrei0r PRIVATE RELOCATABLE) endif() From 93cf0e549a52d64b35a2ef106cf371f1aa425d42 Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Sun, 11 Apr 2021 18:38:28 -0500 Subject: [PATCH 121/122] Add cmake & ninja output to .gitignore --- .gitignore | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index ad0c9466b..88189f1ba 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,13 @@ src/tests/*/* !src/tests/*/*.cpp !src/tests/*/*.pro build +*cmake_install.cmake +.ninja_* +build.ninja +rules.ninja +CMakeCache.txt +*CMakeFiles/ +Mlt7Config*.cmake +install_manifest.txt +out/ +src/modules/qt/mltqt_autogen/ From db5cc1b78fdda34d148b92015274e41a4e94bbfe Mon Sep 17 00:00:00 2001 From: Brian Matherly Date: Mon, 12 Apr 2021 21:28:13 -0500 Subject: [PATCH 122/122] Do not add normalize filters to chains A chain encapsulates a producer. The encapsulated producer should have normalize filters attached to it. If a link in a chain can not provide the requested frame, it should manually apply a filter to normalize. --- src/modules/core/producer_loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/core/producer_loader.c b/src/modules/core/producer_loader.c index 1f81cb84f..fc793764a 100644 --- a/src/modules/core/producer_loader.c +++ b/src/modules/core/producer_loader.c @@ -230,7 +230,7 @@ mlt_producer producer_loader_init( mlt_profile profile, mlt_service_type type, c mlt_properties_get( properties, "loader_normalised" ) == NULL ) attach_normalisers( profile, producer ); - if ( producer ) + if ( producer && mlt_service_identify( MLT_PRODUCER_SERVICE( producer ) ) != mlt_service_chain_type ) { // Always let the image and audio be converted int created = 0;