Esempio n. 1
0
int mlt_consumer_init( mlt_consumer self, void *child, mlt_profile profile )
{
	int error = 0;
	memset( self, 0, sizeof( struct mlt_consumer_s ) );
	self->child = child;
	error = mlt_service_init( &self->parent, self );
	if ( error == 0 )
	{
		// Get the properties from the service
		mlt_properties properties = MLT_SERVICE_PROPERTIES( &self->parent );

		// Apply profile to properties
		if ( profile == NULL )
		{
			// Normally the application creates the profile and controls its lifetime
			// This is the fallback exception handling
			profile = mlt_profile_init( NULL );
			mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
			mlt_properties_set_data( properties, "_profile", profile, 0, (mlt_destructor)mlt_profile_close, NULL );
		}
		apply_profile_properties( self, profile, properties );

		// Default rescaler for all consumers
		mlt_properties_set( properties, "rescale", "bilinear" );

		// Default read ahead buffer size
		mlt_properties_set_int( properties, "buffer", 25 );
		mlt_properties_set_int( properties, "drop_max", 5 );

		// Default audio frequency and channels
		mlt_properties_set_int( properties, "frequency", 48000 );
		mlt_properties_set_int( properties, "channels", 2 );

		// Default of all consumers is real time
		mlt_properties_set_int( properties, "real_time", 1 );

		// Default to environment test card
		mlt_properties_set( properties, "test_card", mlt_environment( "MLT_TEST_CARD" ) );

		// Hmm - default all consumers to yuv422 :-/
		self->format = mlt_image_yuv422;
		mlt_properties_set( properties, "mlt_image_format", mlt_image_format_name( self->format ) );
		mlt_properties_set( properties, "mlt_audio_format", mlt_audio_format_name( 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-stopped", NULL );
		mlt_events_listen( properties, self, "consumer-frame-show", ( mlt_listener )on_consumer_frame_show );

		// Register a property-changed listener to handle the profile property -
		// subsequent properties can override the profile
		self->event_listener = mlt_events_listen( properties, self, "property-changed", ( mlt_listener )mlt_consumer_property_changed );

		// Create the push mutex and condition
		pthread_mutex_init( &self->put_mutex, NULL );
		pthread_cond_init( &self->put_cond, NULL );

	}
	return error;
}
Esempio n. 2
0
int mlt_service_init( mlt_service self, void *child )
{
	int error = 0;

	// Initialise everything to NULL
	memset( self, 0, sizeof( struct mlt_service_s ) );

	// Assign the child
	self->child = child;

	// Generate local space
	self->local = calloc( 1, sizeof( mlt_service_base ) );

	// Associate the methods
	self->get_frame = service_get_frame;

	// Initialise the properties
	error = mlt_properties_init( &self->parent, self );
	if ( error == 0 )
	{
		self->parent.close = ( mlt_destructor )mlt_service_close;
		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 );
		pthread_mutex_init( &( ( mlt_service_base * )self->local )->mutex, NULL );
	}

	return error;
}
Esempio n. 3
0
int mlt_producer_init( mlt_producer self, void *child )
{
	// Check that we haven't received NULL
	int error = self == NULL;

	// Continue if no error
	if ( error == 0 )
	{
#ifdef _MLT_PRODUCER_CHECKS_
		producers_created ++;
#endif

		// Initialise the producer
		memset( self, 0, sizeof( struct mlt_producer_s ) );

		// Associate with the child
		self->child = child;

		// Initialise the service
		if ( mlt_service_init( &self->parent, self ) == 0 )
		{
			// The parent is the service
			mlt_service parent = &self->parent;

			// Define the parent close
			parent->close = ( mlt_destructor )mlt_producer_close;
			parent->close_object = self;

			// For convenience, we'll assume the close_object is self
			self->close_object = self;

			// Get the properties of the parent
			mlt_properties properties = MLT_SERVICE_PROPERTIES( parent );

			// Set the default properties
			mlt_properties_set( properties, "mlt_type", "mlt_producer" );
			mlt_properties_set_position( properties, "_position", 0.0 );
			mlt_properties_set_double( properties, "_frame", 0 );
			mlt_properties_set_double( properties, "_speed", 1.0 );
			mlt_properties_set_position( properties, "in", 0 );
			char *e = getenv( "MLT_DEFAULT_PRODUCER_LENGTH" );
			int p = e ? atoi( e ) : 15000;
			mlt_properties_set_position( properties, "out", p - 1 );
			mlt_properties_set_position( properties, "length", p );
			mlt_properties_set( properties, "eof", "pause" );
			mlt_properties_set( properties, "resource", "<producer>" );

			// Override service get_frame
			parent->get_frame = producer_get_frame;

			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 );
		}
	}

	return error;
}
Esempio n. 4
0
GlslManager::GlslManager()
	: Mlt::Filter( mlt_filter_new() )
	, pbo(0)
	, initEvent(0)
	, closeEvent(0)
{
	mlt_filter filter = get_filter();
	if ( filter ) {
		// Set the mlt_filter child in case we choose to override virtual functions.
		filter->child = this;
		mlt_properties_set_data(mlt_global_properties(), "glslManager", this, 0,
			(mlt_destructor) deleteManager, NULL);

		mlt_events_register( get_properties(), "init glsl", NULL );
		mlt_events_register( get_properties(), "close glsl", NULL );
		initEvent = listen("init glsl", this, (mlt_listener) GlslManager::onInit);
		closeEvent = listen("close glsl", this, (mlt_listener) GlslManager::onClose);
	}
}
Esempio n. 5
0
mlt_consumer consumer_sdl_preview_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
	consumer_sdl self = calloc( 1, sizeof( struct consumer_sdl_s ) );
	if ( self != NULL && mlt_consumer_init( &self->parent, self, profile ) == 0 )
	{
		// Get the parent consumer object
		mlt_consumer parent = &self->parent;

		// Get the properties
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( parent );

		// Get the width and height
		int width = mlt_properties_get_int( properties, "width" );
		int height = mlt_properties_get_int( properties, "height" );

		// Process actual param
		if ( arg == NULL || sscanf( arg, "%dx%d", &width, &height ) == 2 )
		{
			mlt_properties_set_int( properties, "width", width );
			mlt_properties_set_int( properties, "height", height );
		}

		// Create child consumers
		self->play = mlt_factory_consumer( profile, "sdl", arg );
		self->still = mlt_factory_consumer( profile, "sdl_still", arg );
		mlt_properties_set( properties, "rescale", "nearest" );
		mlt_properties_set( properties, "deinterlace_method", "onefield" );
		mlt_properties_set_int( properties, "prefill", 1 );
		mlt_properties_set_int( properties, "top_field_first", -1 );

		parent->close = consumer_close;
		parent->start = consumer_start;
		parent->stop = consumer_stop;
		parent->is_stopped = consumer_is_stopped;
		parent->purge = consumer_purge;
		self->joined = 1;
		mlt_events_listen( MLT_CONSUMER_PROPERTIES( self->play ), self, "consumer-frame-show", ( mlt_listener )consumer_frame_show_cb );
		mlt_events_listen( MLT_CONSUMER_PROPERTIES( self->still ), self, "consumer-frame-show", ( mlt_listener )consumer_frame_show_cb );
		mlt_events_listen( MLT_CONSUMER_PROPERTIES( self->play ), self, "consumer-sdl-event", ( mlt_listener )consumer_sdl_event_cb );
		mlt_events_listen( MLT_CONSUMER_PROPERTIES( self->still ), self, "consumer-sdl-event", ( mlt_listener )consumer_sdl_event_cb );
		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 );
		return parent;
	}
	free( self );
	return NULL;
}
Esempio n. 6
0
/** 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;
}
Esempio n. 7
0
mlt_consumer consumer_sdl2_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg )
{
	// Create the consumer object
	consumer_sdl self = calloc( 1, sizeof( struct consumer_sdl_s ) );

	// If no malloc'd and consumer init ok
	if ( self != NULL && mlt_consumer_init( &self->parent, self, profile ) == 0 )
	{
		// Create the queue
		self->queue = mlt_deque_init( );

		// Get the parent consumer object
		mlt_consumer parent = &self->parent;

		// We have stuff to clean up, so override the close method
		parent->close = consumer_close;

		// get a handle on properties
		mlt_service service = MLT_CONSUMER_SERVICE( parent );
		self->properties = MLT_SERVICE_PROPERTIES( service );

		// Set the default volume
		mlt_properties_set_double( self->properties, "volume", 1.0 );

		// This is the initialisation of the consumer
		pthread_mutex_init( &self->audio_mutex, NULL );
		pthread_cond_init( &self->audio_cond, NULL);
		pthread_mutex_init( &self->video_mutex, NULL );
		pthread_cond_init( &self->video_cond, NULL);
		
		// Default scaler (for now we'll use nearest)
		mlt_properties_set( self->properties, "rescale", "nearest" );
		mlt_properties_set( self->properties, "deinterlace_method", "onefield" );
		mlt_properties_set_int( self->properties, "top_field_first", -1 );

		// Default buffer for low latency
		mlt_properties_set_int( self->properties, "buffer", 1 );

		// Default audio buffer
		mlt_properties_set_int( self->properties, "audio_buffer", 2048 );
#if defined(_WIN32) && SDL_MAJOR_VERSION == 2
		mlt_properties_set( self->properties, "audio_driver", "DirectSound" );
#endif

		// Ensure we don't join on a non-running object
		self->joined = 1;
		
		// process actual param
		if ( arg && sscanf( arg, "%dx%d", &self->width, &self->height ) )
		{
			mlt_properties_set_int( self->properties, "resolution", 1 );
		}
		else
		{
			self->width = mlt_properties_get_int( self->properties, "width" );
			self->height = mlt_properties_get_int( self->properties, "height" );
		}
	
		// Allow thread to be started/stopped
		parent->start = consumer_start;
		parent->stop = consumer_stop;
		parent->is_stopped = consumer_is_stopped;
		parent->purge = consumer_purge;

		// Register specific events
		mlt_events_register( self->properties, "consumer-sdl-event", ( mlt_transmitter )consumer_sdl_event );

		// Return the consumer produced
		return parent;
	}

	// malloc or consumer init failed
	free( self );

	// Indicate failure
	return NULL;
}
Esempio n. 8
0
mlt_producer producer_pango_init( const char *filename )
{
	producer_pango this = calloc( 1, sizeof( struct producer_pango_s ) );
	if ( this != NULL && mlt_producer_init( &this->parent, this ) == 0 )
	{
		mlt_producer producer = &this->parent;

		pthread_mutex_lock( &pango_mutex );
		if ( fontmap == NULL )
			fontmap = (PangoFT2FontMap*) pango_ft2_font_map_new();
		g_type_init();
		pthread_mutex_unlock( &pango_mutex );

		producer->get_frame = producer_get_frame;
		producer->close = ( mlt_destructor )producer_close;

		// Get the properties interface
		mlt_properties properties = MLT_PRODUCER_PROPERTIES( &this->parent );

		mlt_events_register( properties, "fontmap-reload", NULL );
		mlt_events_listen( properties, producer, "fontmap-reload", (mlt_listener) on_fontmap_reload );

		// Set the default properties
		mlt_properties_set( properties, "fgcolour", "0xffffffff" );
		mlt_properties_set( properties, "bgcolour", "0x00000000" );
		mlt_properties_set( properties, "olcolour", "0x00000000" );
		mlt_properties_set_int( properties, "align", pango_align_left );
		mlt_properties_set_int( properties, "pad", 0 );
		mlt_properties_set_int( properties, "outline", 0 );
		mlt_properties_set( properties, "text", "" );
		mlt_properties_set( properties, "font", NULL );
		mlt_properties_set( properties, "family", "Sans" );
		mlt_properties_set_int( properties, "size", 48 );
		mlt_properties_set( properties, "style", "normal" );
		mlt_properties_set( properties, "encoding", "UTF-8" );
		mlt_properties_set_int( properties, "weight", PANGO_WEIGHT_NORMAL );
		mlt_properties_set_int( properties, "stretch", PANGO_STRETCH_NORMAL + 1 );
		mlt_properties_set_int( properties, "rotate", 0 );
		mlt_properties_set_int( properties, "seekable", 1 );

		if ( filename == NULL || ( filename && ( !strcmp( filename, "" )
			|| strstr( filename, "<producer>" )
			// workaround for old kdenlive countdown generator
			|| strstr( filename, "&lt;producer&gt;" ) ) ) )
		{
			mlt_properties_set( properties, "markup", "" );
		}
		else if ( filename[ 0 ] == '+' || strstr( filename, "/+" ) )
		{
			char *copy = strdup( filename + 1 );
			char *markup = copy;
			if ( strstr( markup, "/+" ) )
				markup = strstr( markup, "/+" ) + 2;
			if ( strrchr( markup, '.' ) )
				( *strrchr( markup, '.' ) ) = '\0';
			while ( strchr( markup, '~' ) )
				( *strchr( markup, '~' ) ) = '\n';
			mlt_properties_set( properties, "resource", filename );
			mlt_properties_set( properties, "markup", markup );
			free( copy );
		}
		else if ( strstr( filename, ".mpl" ) ) 
		{
			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_properties_set( 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 );

			// Make sure we have at least one entry
			if ( mlt_properties_get( contents, "0" ) == NULL )
				mlt_properties_set( contents, "0", "" );

			for ( i = 0; i < mlt_properties_count( contents ); i ++ )
			{
				char *name = mlt_properties_get_name( contents, i );
				char *value = mlt_properties_get_value( contents, i );
				while ( value != NULL && strchr( value, '~' ) )
					( *strchr( value, '~' ) ) = '\n';
				item.frame = atoi( name );
				mlt_geometry_insert( key_frames, &item );
				out_point = MAX( out_point, item.frame );
			}
			mlt_geometry_interpolate( key_frames );
			mlt_properties_set_position( properties, "length", out_point + 1 );
			mlt_properties_set_position( properties, "out", out_point );
		}
		else
		{
			// Convert file name string encoding.
			mlt_properties_set( properties, "resource", filename );
			mlt_properties_from_utf8( properties, "resource", "_resource" );
			filename = mlt_properties_get( properties, "_resource" );

			FILE *f = fopen( filename, "r" );
			if ( f != NULL )
			{
				char line[81];
				char *markup = NULL;
				size_t size = 0;
				line[80] = '\0';
				
				while ( fgets( line, 80, f ) )
				{
					size += strlen( line ) + 1;
					if ( markup )
					{
						markup = realloc( markup, size );
						if ( markup )
							strcat( markup, line );
					}
					else
					{
						markup = strdup( line );
					}
				}
				fclose( f );

				if ( markup && markup[ strlen( markup ) - 1 ] == '\n' )
					markup[ strlen( markup ) - 1 ] = '\0';

				if ( markup )
					mlt_properties_set( properties, "markup", markup );
				else
					mlt_properties_set( properties, "markup", "" );
				free( markup );
			}
			else
			{
				producer->close = NULL;
				mlt_producer_close( producer );
				producer = NULL;
				free( this );
			}
		}

		return producer;
	}
	free( this );
	return NULL;
}
Esempio n. 9
0
mlt_repository mlt_factory_init( const char *directory )
{
	// Load the system locales
	setlocale( LC_ALL, "" );

	if ( ! global_properties )
		global_properties = mlt_properties_new( );

	// Allow property refresh on a subsequent initialisation
	if ( global_properties )
	{
		mlt_properties_set_or_default( global_properties, "MLT_NORMALISATION", getenv( "MLT_NORMALISATION" ), "PAL" );
		mlt_properties_set_or_default( global_properties, "MLT_PRODUCER", getenv( "MLT_PRODUCER" ), "loader" );
		mlt_properties_set_or_default( global_properties, "MLT_CONSUMER", getenv( "MLT_CONSUMER" ), "sdl" );
		mlt_properties_set( global_properties, "MLT_TEST_CARD", getenv( "MLT_TEST_CARD" ) );
		mlt_properties_set_or_default( global_properties, "MLT_PROFILE", getenv( "MLT_PROFILE" ), "dv_pal" );
		mlt_properties_set_or_default( global_properties, "MLT_DATA", getenv( "MLT_DATA" ), PREFIX_DATA );

#if defined(WIN32)
		char path[1024];
		DWORD size = sizeof( path );
		GetModuleFileName( NULL, path, size );
#elif defined(__DARWIN__)  && defined(RELOCATABLE)
		char path[1024];
		uint32_t size = sizeof( path );
		_NSGetExecutablePath( path, &size );
#endif
#if defined(WIN32) || (defined(__DARWIN__) && defined(RELOCATABLE))
		char *path2 = strdup( path );
		char *appdir = dirname( path2 );
		mlt_properties_set( global_properties, "MLT_APPDIR", appdir );
		free( path2 );
#endif
	}

	// Only initialise once
	if ( mlt_directory == NULL )
	{
#if !defined(WIN32) && !(defined(__DARWIN__) && defined(RELOCATABLE))
		// Allow user overrides
		if ( directory == NULL || !strcmp( directory, "" ) )
			directory = getenv( "MLT_REPOSITORY" );
#endif
		// If no directory is specified, default to install directory
		if ( directory == NULL )
			directory = PREFIX_LIB;

		// Store the prefix for later retrieval
#if defined(WIN32) || (defined(__DARWIN__) && defined(RELOCATABLE))
		char *exedir = mlt_environment( "MLT_APPDIR" );
		size_t size = strlen( exedir );
		if ( global_properties && !getenv( "MLT_DATA" ) )
		{
			mlt_directory = calloc( 1, size + strlen( PREFIX_DATA ) + 1 );
			strcpy( mlt_directory, exedir );
			strcat( mlt_directory, PREFIX_DATA );
			mlt_properties_set( global_properties, "MLT_DATA", mlt_directory );
			free( mlt_directory );
		}
		mlt_directory = calloc( 1, size + strlen( directory ) + 1 );
		strcpy( mlt_directory, exedir );
		strcat( mlt_directory, directory );
#else
		mlt_directory = strdup( directory );
#endif
		
		// Initialise the pool
		mlt_pool_init( );

		// 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 );

		// Create the repository of services
		repository = mlt_repository_init( mlt_directory );

		// Force a clean up when app closes
		atexit( mlt_factory_close );
	}

	if ( global_properties )
	{
		char *path = getenv( "MLT_PRESETS_PATH" );
		if ( path )
		{
			mlt_properties_set( global_properties, "MLT_PRESETS_PATH", path );
		}
		else
		{
			path = malloc( strlen( mlt_environment( "MLT_DATA" ) ) + strlen( PRESETS_DIR ) + 1 );
			strcpy( path, mlt_environment( "MLT_DATA" ) );
			strcat( path, PRESETS_DIR );
			mlt_properties_set( global_properties, "MLT_PRESETS_PATH", path );
			free( path );
		}
	}

	return repository;
}