Пример #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;
}
Пример #2
0
static mlt_consumer generate_consumer( mlt_consumer consumer, mlt_properties props, int index )
{
    mlt_profile profile = NULL;
    if ( mlt_properties_get( props, "mlt_profile" ) )
        profile = mlt_profile_init( mlt_properties_get( props, "mlt_profile" ) );
    if ( !profile )
        profile = mlt_profile_clone( mlt_service_profile( MLT_CONSUMER_SERVICE(consumer) ) );
    mlt_consumer nested = create_consumer( profile, mlt_properties_get( props, "mlt_service" ),
                                           mlt_properties_get( props, "target" ) );

    if ( nested )
    {
        mlt_properties properties = MLT_CONSUMER_PROPERTIES(consumer);
        mlt_properties nested_props = MLT_CONSUMER_PROPERTIES(nested);
        char key[30];

        snprintf( key, sizeof(key), "%d.consumer", index );
        mlt_properties_set_data( properties, key, nested, 0, (mlt_destructor) mlt_consumer_close, NULL );
        snprintf( key, sizeof(key), "%d.profile", index );
        mlt_properties_set_data( properties, key, profile, 0, (mlt_destructor) mlt_profile_close, NULL );

        mlt_properties_set_int( nested_props, "put_mode", 1 );
        mlt_properties_pass_list( nested_props, properties, "terminate_on_pause" );
        mlt_properties_set( props, "consumer", NULL );
        // set mlt_profile before other properties to facilitate presets
        mlt_properties_pass_list( nested_props, props, "mlt_profile" );
        mlt_properties_inherit( nested_props, props );

        attach_normalisers( profile, MLT_CONSUMER_SERVICE(nested) );

        // Relay the first available consumer-frame-show event
        mlt_event event = mlt_properties_get_data( properties, "frame-show-event", NULL );
        if ( !event )
        {
            event = mlt_events_listen( nested_props, properties, "consumer-frame-show", (mlt_listener) on_frame_show );
            mlt_properties_set_data( properties, "frame-show-event", event, 0, /*mlt_event_close*/ NULL, NULL );
        }
    }
    else
    {
        mlt_profile_close( profile );
    }
    return nested;
}
Пример #3
0
int main( int argc, char **argv )
{
    int i;
    mlt_consumer consumer = NULL;
    FILE *store = NULL;
    char *name = NULL;
    mlt_profile profile = NULL;
    int is_progress = 0;
    int is_silent = 0;
    mlt_profile backup_profile;

    // Handle abnormal exit situations.
    signal( SIGSEGV, abnormal_exit_handler );
    signal( SIGILL, abnormal_exit_handler );
    signal( SIGABRT, abnormal_exit_handler );

    // Construct the factory
    mlt_repository repo = mlt_factory_init( NULL );

#if defined(WIN32) && !defined(MELT_NOSDL)
    is_silent = 1;
#endif

    for ( i = 1; i < argc; i ++ )
    {
        // Check for serialisation switch
        if ( !strcmp( argv[ i ], "-serialise" ) )
        {
            name = argv[ ++ i ];
            if ( name != NULL && strstr( name, ".melt" ) )
                store = fopen( name, "w" );
            else
            {
                if ( name == NULL || name[0] == '-' )
                    store = stdout;
                name = NULL;
            }
        }
        // Look for the profile option
        else if ( !strcmp( argv[ i ], "-profile" ) )
        {
            const char *pname = argv[ ++ i ];
            if ( pname && pname[0] != '-' )
                profile = mlt_profile_init( pname );
        }
        else if ( !strcmp( argv[ i ], "-progress" ) )
        {
            is_progress = 1;
        }
        else if ( !strcmp( argv[ i ], "-progress2" ) )
        {
            is_progress = 2;
        }
        // Look for the query option
        else if ( !strcmp( argv[ i ], "-query" ) )
        {
            const char *pname = argv[ ++ i ];
            if ( pname && pname[0] != '-' )
            {
                if ( !strcmp( pname, "consumers" ) || !strcmp( pname, "consumer" ) )
                    query_services( repo, consumer_type );
                else if ( !strcmp( pname, "filters" ) || !strcmp( pname, "filter" ) )
                    query_services( repo, filter_type );
                else if ( !strcmp( pname, "producers" ) || !strcmp( pname, "producer" ) )
                    query_services( repo, producer_type );
                else if ( !strcmp( pname, "transitions" ) || !strcmp( pname, "transition" ) )
                    query_services( repo, transition_type );
                else if ( !strcmp( pname, "profiles" ) || !strcmp( pname, "profile" ) )
                    query_profiles();
                else if ( !strcmp( pname, "presets" ) || !strcmp( pname, "preset" ) )
                    query_presets();
                else if ( !strncmp( pname, "format", 6 ) )
                    query_formats();
                else if ( !strncmp( pname, "acodec", 6 ) || !strcmp( pname, "audio_codecs" ) )
                    query_acodecs();
                else if ( !strncmp( pname, "vcodec", 6 ) || !strcmp( pname, "video_codecs" ) )
                    query_vcodecs();

                else if ( !strncmp( pname, "consumer=", 9 ) )
                    query_metadata( repo, consumer_type, "consumer", strchr( pname, '=' ) + 1 );
                else if ( !strncmp( pname, "filter=", 7 ) )
                    query_metadata( repo, filter_type, "filter", strchr( pname, '=' ) + 1 );
                else if ( !strncmp( pname, "producer=", 9 ) )
                    query_metadata( repo, producer_type, "producer", strchr( pname, '=' ) + 1 );
                else if ( !strncmp( pname, "transition=", 11 ) )
                    query_metadata( repo, transition_type, "transition", strchr( pname, '=' ) + 1 );
                else if ( !strncmp( pname, "profile=", 8 ) )
                    query_profile( strchr( pname, '=' ) + 1 );
                else if ( !strncmp( pname, "preset=", 7 ) )
                    query_preset( strchr( pname, '=' ) + 1 );
                else
                    goto query_all;
            }
            else
            {
query_all:
                query_services( repo, consumer_type );
                query_services( repo, filter_type );
                query_services( repo, producer_type );
                query_services( repo, transition_type );
                fprintf( stdout, "# You can query the metadata for a specific service using:\n"
                         "# -query <type>=<identifer>\n"
                         "# where <type> is one of: consumer, filter, producer, or transition.\n" );
            }
            goto exit_factory;
        }
        else if ( !strcmp( argv[ i ], "-silent" ) )
        {
            is_silent = 1;
        }
        else if ( !strcmp( argv[ i ], "-verbose" ) )
        {
            mlt_log_set_level( MLT_LOG_VERBOSE );
        }
        else if ( !strcmp( argv[ i ], "-version" ) || !strcmp( argv[ i ], "--version" ) )
        {
            fprintf( stdout, "%s " VERSION "\n"
                     "Copyright (C) 2002-2013 Ushodaya Enterprises Limited\n"
                     "<http://www.mltframework.org/>\n"
                     "This is free software; see the source for copying conditions.  There is NO\n"
                     "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
                     basename( argv[0] ) );
            goto exit_factory;
        }
        else if ( !strcmp( argv[ i ], "-debug" ) )
        {
            mlt_log_set_level( MLT_LOG_DEBUG );
        }
    }
    if ( !is_silent && !isatty( STDIN_FILENO ) && !is_progress )
        is_progress = 1;

    // Create profile if not set explicitly
    if ( getenv( "MLT_PROFILE" ) )
        profile = mlt_profile_init( NULL );
    if ( profile == NULL )
        profile = mlt_profile_init( NULL );
    else
        profile->is_explicit = 1;

    // Look for the consumer option to load profile settings from consumer properties
    backup_profile = mlt_profile_clone( profile );
    load_consumer( &consumer, profile, argc, argv );

    // If the consumer changed the profile, then it is explicit.
    if ( backup_profile && !profile->is_explicit && (
                profile->width != backup_profile->width ||
                profile->height != backup_profile->height ||
                profile->sample_aspect_num != backup_profile->sample_aspect_num ||
                profile->sample_aspect_den != backup_profile->sample_aspect_den ||
                profile->frame_rate_den != backup_profile->frame_rate_den ||
                profile->frame_rate_num != backup_profile->frame_rate_num ||
                profile->colorspace != backup_profile->colorspace ) )
        profile->is_explicit = 1;
    mlt_profile_close( backup_profile );

    // Get melt producer
    if ( argc > 1 )
        melt = mlt_factory_producer( profile, "melt", &argv[ 1 ] );

    if ( melt )
    {
        // Generate an automatic profile if needed.
        if ( ! profile->is_explicit )
        {
            mlt_profile_from_producer( profile, melt );
            mlt_producer_close( melt );
            melt = mlt_factory_producer( profile, "melt", &argv[ 1 ] );
        }

        // Reload the consumer with the fully qualified profile.
        // The producer or auto-profile could have changed the profile.
        load_consumer( &consumer, profile, argc, argv );

        // See if producer has consumer already attached
        if ( !store && !consumer )
        {
            consumer = MLT_CONSUMER( mlt_service_consumer( MLT_PRODUCER_SERVICE( melt ) ) );
            if ( consumer )
            {
                mlt_properties_inc_ref( MLT_CONSUMER_PROPERTIES(consumer) ); // because we explicitly close it
                mlt_properties_set_data( MLT_CONSUMER_PROPERTIES(consumer),
                                         "transport_callback", transport_action, 0, NULL, NULL );
            }
        }

        // If we have no consumer, default to sdl
        if ( store == NULL && consumer == NULL )
            consumer = create_consumer( profile, NULL );
    }

    // Set transport properties on consumer and produder
    if ( consumer != NULL && melt != NULL )
    {
        mlt_properties_set_data( MLT_CONSUMER_PROPERTIES( consumer ), "transport_producer", melt, 0, NULL, NULL );
        mlt_properties_set_data( MLT_PRODUCER_PROPERTIES( melt ), "transport_consumer", consumer, 0, NULL, NULL );
        if ( is_progress )
            mlt_properties_set_int(  MLT_CONSUMER_PROPERTIES( consumer ), "progress", is_progress );
        if ( is_silent )
            mlt_properties_set_int(  MLT_CONSUMER_PROPERTIES( consumer ), "silent", is_silent );
    }

    if ( argc > 1 && melt != NULL && mlt_producer_get_length( melt ) > 0 )
    {
        // Parse the arguments
        for ( i = 1; i < argc; i ++ )
        {
            if ( !strcmp( argv[ i ], "-jack" ) )
            {
                setup_jack_transport( consumer, profile );
            }
            else if ( !strcmp( argv[ i ], "-serialise" ) )
            {
                if ( store != stdout )
                    i ++;
            }
            else
            {
                if ( store != NULL )
                    fprintf( store, "%s\n", argv[ i ] );

                i ++;

                while ( argv[ i ] != NULL && argv[ i ][ 0 ] != '-' )
                {
                    if ( store != NULL )
                        fprintf( store, "%s\n", argv[ i ] );
                    i += 1;
                }

                i --;
            }
        }

        if ( consumer != NULL && store == NULL )
        {
            // Get melt's properties
            mlt_properties melt_props = MLT_PRODUCER_PROPERTIES( melt );

            // Get the last group
            mlt_properties group = mlt_properties_get_data( melt_props, "group", 0 );

            // Apply group settings
            mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
            mlt_properties_inherit( properties, group );

            // Connect consumer to melt
            mlt_consumer_connect( consumer, MLT_PRODUCER_SERVICE( melt ) );

            // Start the consumer
            mlt_events_listen( properties, consumer, "consumer-fatal-error", ( mlt_listener )on_fatal_error );
            if ( mlt_consumer_start( consumer ) == 0 )
            {
                // Try to exit gracefully upon these signals
                signal( SIGINT, stop_handler );
                signal( SIGTERM, stop_handler );
#ifndef WIN32
                signal( SIGHUP, stop_handler );
                signal( SIGPIPE, stop_handler );
#endif

                // Transport functionality
                transport( melt, consumer );

                // Stop the consumer
                mlt_consumer_stop( consumer );
            }
        }
        else if ( store != NULL && store != stdout && name != NULL )
        {
            fprintf( stderr, "Project saved as %s.\n", name );
            fclose( store );
        }
    }
    else
    {
        show_usage( argv[0] );
    }

    // Disconnect producer from consumer to prevent ref cycles from closing services
    if ( consumer )
    {
        mlt_consumer_connect( consumer, NULL );
        mlt_events_fire( MLT_CONSUMER_PROPERTIES(consumer), "consumer-cleanup", NULL);
    }

    // Close the producer
    if ( melt != NULL )
        mlt_producer_close( melt );

    // Close the consumer
    if ( consumer != NULL )
        mlt_consumer_close( consumer );

    // Close the factory
    mlt_profile_close( profile );

exit_factory:

// Workaround qmelt on OS X from crashing at exit.
#if !defined(__MACH__) || !defined(QT_GUI_LIB)
    mlt_factory_close( );
#endif

    return 0;
}
Пример #4
0
void AudioScript::pre_judge() throw (Exception)
{
    const ScriptParam* inparam = get_param_info("in");
    const ScriptParam* outparam = get_param_info("out");
    const ScriptParam* resparam = get_param_info("resource");

    if ( !inparam || inparam->param_style != ScriptParams::PosParam ||
            !outparam || outparam->param_style != ScriptParams::PosParam) {
        throw_error_v(ErrorScriptArgInvalid, "in/out position param is required for %s script",
                      Vm::proc_type_names[VIDEO_RESOURCE_SCRIPT]);
    }

    if ( !resparam || resparam->param_style != ScriptParams::ScalarParam ) {
        throw_error_v(ErrorScriptArgInvalid, "resource scalar param is required for %s script",
                      Vm::proc_type_names[VIDEO_RESOURCE_SCRIPT]);
    }

    json_t* res_arg = get_arg_value("resource");
    json_t* in = get_arg_value("in");
    json_t* out = get_arg_value("out");

    if (!res_arg || !json_is_string(res_arg) || !strlen(json_string_value(res_arg))) {
        throw_error_v(ErrorScriptArgInvalid, "resource arg is required for %s script",
                      Vm::proc_type_names[VIDEO_RESOURCE_SCRIPT]);
    }

    if ( !in || !json_is_integer(in) ) {
        throw_error_v(ErrorScriptArgInvalid, "in arg is required for %s script",
                      Vm::proc_type_names[VIDEO_RESOURCE_SCRIPT]);
    }

    if ( !out || !json_is_integer(out) ) {
        throw_error_v(ErrorScriptArgInvalid, "out arg is required for %s script",
                      Vm::proc_type_names[VIDEO_RESOURCE_SCRIPT]);
    }

    string path(json_string_value(res_arg));


    mlt_profile profile = mlt_profile_init(NULL);
    mlt_producer prod = mlt_factory_producer(profile, "loader", path.c_str());

    if  ( prod == NULL ) {
        throw_error_v(ErrorScriptArgInvalid, "out arg is required for %s script",
                      Vm::proc_type_names[VIDEO_RESOURCE_SCRIPT]);
    }

    uuid = Vm::uuid();
    MltLoader::push_mlt_registry(mlt_producer_service(prod), uuid.c_str());

    int length = mlt_producer_get_length(prod);
    int inframe = json_integer_value(in), outframe = json_integer_value(out);

    json_decref(in);
    json_decref(out);

    switch (inparam->pos_type) {
    case ScriptParams::FramePos:
        if ( inframe == -1  || inframe >= length) {
            inframe = length - 1;
        }
        else if ( inframe < 0 ) {
            inframe = length + inframe;
            if (inframe < 0)inframe = 0;
        }
        break;
    case ScriptParams::TimePos: {
        int total_time = length * 40;
        if ( inframe == -1 ) {
            inframe = length - 1;
        }
        else if ( inframe >= 0  ) {
            if ( inframe > total_time) {
                inframe = length -1;
            }
            else {
                inframe = (double)inframe / 40 ;
            }
        }
        else {
            inframe = total_time + inframe;
            if ( inframe < 0 ) {
                inframe = length - 1;
            }
            else {
                inframe = (double)inframe/40;
            }
        }
    }
    break;
    }


    switch (outparam->pos_type) {
    case ScriptParams::FramePos:
        if ( outframe == -1  || outframe >= length) {
            outframe = length - 1;
        }
        else if ( outframe < 0 ) {
            outframe = length + outframe;
            if (outframe < 0)outframe = 0;
        }
        break;
    case ScriptParams::TimePos: {
        int total_time = length * 40;
        if ( outframe == -1 ) {
            outframe = length - 1;
        }
        else if ( outframe >= 0  ) {
            if ( outframe > total_time) {
                outframe = length -1;
            }
            else {
                outframe = (double)outframe / 40 ;
            }
        }
        else {
            outframe = total_time + outframe;
            if ( outframe < 0 ) {
                outframe = length - 1;
            }
            else {
                outframe = (double)outframe/40;
            }
        }
    }
    break;
    }

    if ( inframe > outframe ) {
        inframe ^= outframe ^= inframe ^= outframe;
    }

    if ( !type_spec_props.get() ) {
        type_spec_props.reset(new ScriptProps(*this, NULL));
    }

    type_spec_props->add_property("resource", res_arg);
    json_decref(res_arg);

    type_spec_props->add_property("uuid", JsonWrap(json_string(uuid.c_str()),1).h);

    set_frame_range(inframe,outframe);

    json_t* jv = json_integer(inframe);
    mlt_props->add_property("in", jv);
    json_decref(jv);

    jv = json_integer(outframe);
    mlt_props->add_property("out", jv);
    json_decref(jv);


    //mlt_producer_set_in_and_out(prod, inframe, outframe);
#ifdef DEBUG
    std::cout << mlt_producer_properties(prod);
#endif
    this->path  = path;
    //todo: check format info
    return;
}
Пример #5
0
static void mlt_consumer_property_changed( mlt_properties owner, mlt_consumer self, char *name )
{
	if ( !strcmp( name, "mlt_profile" ) )
	{
		// Get the properies
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );

		// Get the current profile
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );

		// Load the new profile
		mlt_profile new_profile = mlt_profile_init( mlt_properties_get( properties, name ) );

		if ( new_profile )
		{
			// Copy the profile
			if ( profile != NULL )
			{
				free( profile->description );
				memcpy( profile, new_profile, sizeof( struct mlt_profile_s ) );
				profile->description = strdup( new_profile->description );
			}
			else
			{
				profile = new_profile;
			}

			// Apply to properties
			apply_profile_properties( self, profile, properties );
			mlt_profile_close( new_profile );
		}
 	}
	else if ( !strcmp( name, "frame_rate_num" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
		{
			profile->frame_rate_num = mlt_properties_get_int( properties, "frame_rate_num" );
			mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) );
		}
	}
	else if ( !strcmp( name, "frame_rate_den" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
		{
			profile->frame_rate_den = mlt_properties_get_int( properties, "frame_rate_den" );
			mlt_properties_set_double( properties, "fps", mlt_profile_fps( profile ) );
		}
	}
	else if ( !strcmp( name, "width" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
			profile->width = mlt_properties_get_int( properties, "width" );
	}
	else if ( !strcmp( name, "height" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
			profile->height = mlt_properties_get_int( properties, "height" );
	}
	else if ( !strcmp( name, "progressive" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
			profile->progressive = mlt_properties_get_int( properties, "progressive" );
	}
	else if ( !strcmp( name, "sample_aspect_num" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
		{
			profile->sample_aspect_num = mlt_properties_get_int( properties, "sample_aspect_num" );
			mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile )  );
		}
	}
	else if ( !strcmp( name, "sample_aspect_den" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
		{
			profile->sample_aspect_den = mlt_properties_get_int( properties, "sample_aspect_den" );
			mlt_properties_set_double( properties, "aspect_ratio", mlt_profile_sar( profile )  );
		}
	}
	else if ( !strcmp( name, "display_aspect_num" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
		{
			profile->display_aspect_num = mlt_properties_get_int( properties, "display_aspect_num" );
			mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile )  );
		}
	}
	else if ( !strcmp( name, "display_aspect_den" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
		{
			profile->display_aspect_den = mlt_properties_get_int( properties, "display_aspect_den" );
			mlt_properties_set_double( properties, "display_ratio", mlt_profile_dar( profile )  );
		}
	}
	else if ( !strcmp( name, "colorspace" ) )
	{
		mlt_properties properties = MLT_CONSUMER_PROPERTIES( self );
		mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( self ) );
		if ( profile )
			profile->colorspace = mlt_properties_get_int( properties, "colorspace" );
	}
}
Пример #6
0
int inigo( int argc, char **argv )
{
	int i;
	mlt_consumer consumer = NULL;
	mlt_producer melt = NULL;
	FILE *store = NULL;
	char *name = NULL;
	mlt_profile profile = NULL;
	int is_progress = 0;
	int is_silent = 0;

	// Construct the factory
	mlt_repository repo = mlt_factory_init( NULL );

	for ( i = 1; i < argc; i ++ )
	{
//		fprintf(stderr, "argv[%d] = %s\n", i, argv[i]);
		
		// Check for serialisation switch
		if ( !strcmp( argv[ i ], "-serialise" ) )
		{
			name = argv[ ++ i ];
			if ( name != NULL && strstr( name, ".melt" ) )
				store = fopen( name, "w" );
			else
			{
				if ( name == NULL || name[0] == '-' )
					store = stdout;
				name = NULL;
			}
		}
		// Look for the profile option
		else if ( !strcmp( argv[ i ], "-profile" ) )
		{
			const char *pname = argv[ ++ i ];
			if ( pname && pname[0] != '-' )
				profile = mlt_profile_init( pname );
		}
		else if ( !strcmp( argv[ i ], "-progress" ) )
		{
			is_progress = 1;
		}
		// Look for the query option
		else if ( !strcmp( argv[ i ], "-query" ) )
		{
			const char *pname = argv[ ++ i ];
			if ( pname && pname[0] != '-' )
			{
				if ( !strcmp( pname, "consumers" ) || !strcmp( pname, "consumer" ) )
					query_services( repo, consumer_type );
				else if ( !strcmp( pname, "filters" ) || !strcmp( pname, "filter" ) )
					query_services( repo, filter_type );
				else if ( !strcmp( pname, "producers" ) || !strcmp( pname, "producer" ) )
					query_services( repo, producer_type );
				else if ( !strcmp( pname, "transitions" ) || !strcmp( pname, "transition" ) )
					query_services( repo, transition_type );
				
				else if ( !strncmp( pname, "consumer=", 9 ) )
					query_metadata( repo, consumer_type, "consumer", strchr( pname, '=' ) + 1 );
				else if ( !strncmp( pname, "filter=", 7 ) )
					query_metadata( repo, filter_type, "filter", strchr( pname, '=' ) + 1 );
				else if ( !strncmp( pname, "producer=", 9 ) )
					query_metadata( repo, producer_type, "producer", strchr( pname, '=' ) + 1 );
				else if ( !strncmp( pname, "transition=", 11 ) )
					query_metadata( repo, transition_type, "transition", strchr( pname, '=' ) + 1 );
				else
					goto query_all;
			}
			else
			{
query_all:
				query_services( repo, consumer_type );
				query_services( repo, filter_type );
				query_services( repo, producer_type );
				query_services( repo, transition_type );
				fprintf( stderr, "# You can query the metadata for a specific service using:\n"
					"# -query <type>=<identifer>\n"
					"# where <type> is one of: consumer, filter, producer, or transition.\n" );
			}
			goto exit_factory;
		}
		else if ( !strcmp( argv[ i ], "-silent" ) )
		{
			is_silent = 1;
		}
		else if ( !strcmp( argv[ i ], "-verbose" ) )
		{
			mlt_log_set_level( MLT_LOG_VERBOSE );
		}
		else if ( !strcmp( argv[ i ], "-version" ) || !strcmp( argv[ i ], "--version" ) )
		{
			fprintf( stderr, "MLT %s 0.5\n"
				"Copyright (C) 2002-2009 Ushodaya Enterprises Limited\n"
				"<http://www.mltframework.org/>\n"
				"This is free software; see the source for copying conditions.  There is NO\n"
				"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
				basename( argv[0] ) );
			goto exit_factory;
		}
		else if ( !strcmp( argv[ i ], "-debug" ) )
		{
			mlt_log_set_level( MLT_LOG_DEBUG );
		}
	}

	// Create profile if not set explicitly
	if ( profile == NULL )
		profile = mlt_profile_init( NULL );

	// Look for the consumer option
	for ( i = 1; i < argc; i ++ )
	{
		if ( !strcmp( argv[ i ], "-consumer" ) )
		{
			consumer = create_consumer( profile, argv[ ++ i ] );
			if ( consumer )
			{
				mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
				while ( argv[ i + 1 ] != NULL && strstr( argv[ i + 1 ], "=" ) )
					mlt_properties_parse( properties, argv[ ++ i ] );
			}
		}
	}

	// If we have no consumer, default to sdl
	if ( store == NULL && consumer == NULL )
		consumer = create_consumer( profile, NULL );

	// Get melt producer
	if ( argc > 1 )
		melt = mlt_factory_producer( profile, "melt", &argv[ 1 ] );

	// Set transport properties on consumer and produder
	if ( consumer != NULL && melt != NULL )
	{
		mlt_properties_set_data( MLT_CONSUMER_PROPERTIES( consumer ), "transport_producer", melt, 0, NULL, NULL );
		mlt_properties_set_data( MLT_PRODUCER_PROPERTIES( melt ), "transport_consumer", consumer, 0, NULL, NULL );
		if ( is_progress )
			mlt_properties_set_int(  MLT_CONSUMER_PROPERTIES( consumer ), "progress", is_progress );
		if ( is_silent )
			mlt_properties_set_int(  MLT_CONSUMER_PROPERTIES( consumer ), "silent", is_silent );
	}

	if ( argc > 1 && melt != NULL && mlt_producer_get_length( melt ) > 0 )
	{
		// Parse the arguments
		for ( i = 1; i < argc; i ++ )
		{
			if ( !strcmp( argv[ i ], "-serialise" ) )
			{
				if ( store != stdout )
					i ++;
			}
			else
			{
				if ( store != NULL )
					fprintf( store, "%s\n", argv[ i ] );

				i ++;

				while ( argv[ i ] != NULL && argv[ i ][ 0 ] != '-' )
				{
					if ( store != NULL )
						fprintf( store, "%s\n", argv[ i ] );
					i += 1;
				}

				i --;
			}
		}

		if ( consumer != NULL && store == NULL )
		{
			// Get melt's properties
			mlt_properties melt_props = MLT_PRODUCER_PROPERTIES( melt );
	
			// Get the last group
			mlt_properties group = mlt_properties_get_data( melt_props, "group", 0 );
	
			// Apply group settings
			mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
			mlt_properties_inherit( properties, group );

			// Connect consumer to melt
			mlt_consumer_connect( consumer, MLT_PRODUCER_SERVICE( melt ) );

			// Start the consumer
			mlt_consumer_start( consumer );

			// Transport functionality
			transport( melt, consumer );

			// Stop the consumer
			mlt_consumer_stop( consumer );
		}
		else if ( store != NULL && store != stdout && name != NULL )
		{
			fprintf( stderr, "Project saved as %s.\n", name );
			fclose( store );
		}
	}
	else
	{
		fprintf( stderr,
"Usage: %s [options] [producer [name=value]* ]+\n"
"Options:\n"
"  -attach filter[:arg] [name=value]*       Attach a filter to the output\n"
"  -attach-cut filter[:arg] [name=value]*   Attach a filter to a cut\n"
"  -attach-track filter[:arg] [name=value]* Attach a filter to a track\n"
"  -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"
"  -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"
"  -group [name=value]*                     Apply properties repeatedly\n"
"  -help                                    Show this message\n"
"  -join clips                              Join multiple clips into one cut\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"
"  -profile name                            Set the processing settings\n"
"  -progress                                Display progress along with position\n"
"  -remove                                  Remove the most recent cut\n"
"  -repeat times                            Repeat the last cut\n"
"  -query                                   List all of the registered services\n"
"  -query \"consumers\" | \"consumer\"=id       List consumers or show info about one\n"
"  -query \"filters\" | \"filter\"=id           List filters or show info about one\n"
"  -query \"producers\" | \"producer\"=id       List producers or show info about one\n"
"  -query \"transitions\" | \"transition\"=id   List transitions, show info about one\n"
"  -serialise [filename]                    Write the commands to a text file\n"
"  -silent                                  Do not display position/transport\n"
"  -split relative-frame                    Split the last cut into two cuts\n"
"  -swap                                    Rearrange the last two cuts\n"
"  -track                                   Add a track\n"
"  -transition id[:arg] [name=value]*       Add a transition\n"
"  -verbose                                 Set the logging level to verbose\n"
"  -version                                 Show the version and copyright\n"
"  -video-track | -hide-audio               Add a video-only track\n"
"For more help: <http://www.mltframework.org/>\n",
		basename( argv[0] ) );
	}

	// Close the producer
	if ( melt != NULL )
		mlt_producer_close( melt );

	// Close the consumer
	if ( consumer != NULL )
		mlt_consumer_close( consumer );

	// Close the factory
	mlt_profile_close( profile );

exit_factory:
		
	mlt_factory_close( );

	return 0;
}
Пример #7
0
static int get_frame( mlt_producer self, mlt_frame_ptr frame, int index )
{
	mlt_properties properties = MLT_PRODUCER_PROPERTIES(self);
	context cx = mlt_properties_get_data( properties, "context", NULL );

	if ( !cx )
	{
		// Allocate and initialize our context
		cx = mlt_pool_alloc( sizeof( struct context_s ) );
		memset( cx, 0, sizeof( *cx ) );
		mlt_properties_set_data( properties, "context", cx, 0, mlt_pool_release, NULL );
		cx->self = self;
		char *profile_name = mlt_properties_get( properties, "profile" );
		if ( !profile_name )
			profile_name = mlt_properties_get( properties, "mlt_profile" );
		mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( self ) );

		if ( profile_name )
		{
			cx->profile = mlt_profile_init( profile_name );
			cx->profile->is_explicit = 1;
		}
		else
		{
			cx->profile = mlt_profile_clone( profile );
			cx->profile->is_explicit = 0;
		}

		// Encapsulate a real producer for the resource
		cx->producer = mlt_factory_producer( cx->profile, NULL,
			mlt_properties_get( properties, "resource" ) );
		if ( ( profile_name && !strcmp( profile_name, "auto" ) ) ||
			mlt_properties_get_int( properties, "autoprofile" ) )
		{
			mlt_profile_from_producer( cx->profile, cx->producer );
			mlt_producer_close( cx->producer );
			cx->producer = mlt_factory_producer( cx->profile, NULL,	mlt_properties_get( properties, "resource" ) );
		}

		// Since we control the seeking, prevent it from seeking on its own
		mlt_producer_set_speed( cx->producer, 0 );
		cx->audio_position = -1;

		// We will encapsulate a consumer
		cx->consumer = mlt_consumer_new( cx->profile );
		// Do not use _pass_list on real_time so that it defaults to 0 in the absence of
		// an explicit real_time property.
		mlt_properties_set_int( MLT_CONSUMER_PROPERTIES( cx->consumer ), "real_time",
			mlt_properties_get_int( properties, "real_time" ) );
		mlt_properties_pass_list( MLT_CONSUMER_PROPERTIES( cx->consumer ), properties,
			"buffer, prefill, deinterlace_method, rescale" );
	
		// Connect it all together
		mlt_consumer_connect( cx->consumer, MLT_PRODUCER_SERVICE( cx->producer ) );
		mlt_consumer_start( cx->consumer );
	}

	// Generate a frame
	*frame = mlt_frame_init( MLT_PRODUCER_SERVICE( self ) );
	if ( *frame )
	{
		// Seek the producer to the correct place
		// Calculate our positions
		double actual_position = (double) mlt_producer_frame( self );
		if ( mlt_producer_get_speed( self ) != 0 )
			actual_position *= mlt_producer_get_speed( self );
		mlt_position need_first = floor( actual_position );
		mlt_producer_seek( cx->producer,
			lrint( need_first * mlt_profile_fps( cx->profile ) / mlt_producer_get_fps( self ) ) );

		// Get the nested frame
		mlt_frame nested_frame = mlt_consumer_rt_frame( cx->consumer );

		// Stack the producer and our methods on the nested frame
		mlt_frame_push_service( *frame, nested_frame );
		mlt_frame_push_service( *frame, cx );
		mlt_frame_push_get_image( *frame, get_image );
		mlt_frame_push_audio( *frame, nested_frame );
		mlt_frame_push_audio( *frame, cx );
		mlt_frame_push_audio( *frame, get_audio );
		
		// Give the returned frame temporal identity
		mlt_frame_set_position( *frame, mlt_producer_position( self ) );
		
		// Store the nested frame on the produced frame for destruction
		mlt_properties frame_props = MLT_FRAME_PROPERTIES( *frame );
		mlt_properties_set_data( frame_props, "_producer_consumer.frame", nested_frame, 0, (mlt_destructor) mlt_frame_close, NULL );

		// Inform the normalizers about our video properties
		mlt_properties_set_double( frame_props, "aspect_ratio", mlt_profile_sar( cx->profile ) );
		mlt_properties_set_int( frame_props, "width", cx->profile->width );
		mlt_properties_set_int( frame_props, "height", cx->profile->height );
		mlt_properties_set_int( frame_props, "meta.media.width", cx->profile->width );
		mlt_properties_set_int( frame_props, "meta.media.height", cx->profile->height );
		mlt_properties_set_int( frame_props, "progressive", cx->profile->progressive );
	}

	// Calculate the next timecode
	mlt_producer_prepare_next( self );

	return 0;
}