X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmiracle%2Fmiracle_unit.c;h=83f0f024c7b93124e32ac9350fcdba5e5683e7a7;hb=5c299d1ae6f3535df35b3f30bae0476a1ca50aa6;hp=aa81efc0703bcde7883a8c8725f8d4c226d2b392;hpb=89963b31bc7e8fcad7c45103c313e802e186267d;p=melted diff --git a/src/miracle/miracle_unit.c b/src/miracle/miracle_unit.c index aa81efc..83f0f02 100644 --- a/src/miracle/miracle_unit.c +++ b/src/miracle/miracle_unit.c @@ -33,6 +33,7 @@ #include #include #include +#include #include @@ -83,6 +84,21 @@ miracle_unit miracle_unit_init( int index, char *constructor ) return this; } +static char *strip_root( miracle_unit unit, char *file ) +{ + mlt_properties properties = unit->properties; + char *root = mlt_properties_get( properties, "root" ); + if ( file != NULL && root != NULL ) + { + int length = strlen( root ); + if ( root[ length - 1 ] == '/' ) + length --; + if ( !strncmp( file, root, length ) ) + file += length; + } + return file; +} + /** Communicate the current status to all threads waiting on the notifier. */ @@ -126,10 +142,15 @@ void miracle_unit_set_notifier( miracle_unit this, valerie_notifier notifier, ch miracle_unit_status_communicate( this ); } +static mlt_producer create_producer( char *file ) +{ + return mlt_factory_producer( "fezzik", file ); +} + /** Create or locate a producer for the file specified. */ -static mlt_producer create_producer( miracle_unit unit, char *file ) +static mlt_producer locate_producer( miracle_unit unit, char *file ) { // Get the unit properties mlt_properties properties = unit->producers; @@ -139,36 +160,12 @@ static mlt_producer create_producer( miracle_unit unit, char *file ) if ( result == NULL ) { - // 1st Line preferences - if ( strstr( file, ".mpg" ) ) - result = mlt_factory_producer( "mcmpeg", file ); - else if ( strstr( file, ".mpeg" ) ) - result = mlt_factory_producer( "mcmpeg", file ); - else if ( strstr( file, ".dv" ) ) - result = mlt_factory_producer( "mcdv", file ); - else if ( strstr( file, ".dif" ) ) - result = mlt_factory_producer( "mcdv", file ); - else if ( strstr( file, ".jpg" ) ) - result = mlt_factory_producer( "pixbuf", file ); - else if ( strstr( file, ".JPG" ) ) - result = mlt_factory_producer( "pixbuf", file ); - else if ( strstr( file, ".jpeg" ) ) - result = mlt_factory_producer( "pixbuf", file ); - else if ( strstr( file, ".png" ) ) - result = mlt_factory_producer( "pixbuf", file ); - - // 2nd Line fallbacks - if ( result == NULL && strstr( file, ".dv" ) ) - result = mlt_factory_producer( "libdv", file ); - else if ( result == NULL && strstr( file, ".dif" ) ) - result = mlt_factory_producer( "libdv", file ); - - // 3rd line fallbacks - if ( result == NULL ) - result = mlt_factory_producer( "ffmpeg", file ); + // Create the producer + result = create_producer( file ); // Now store the result - mlt_properties_set_data( properties, file, result, 0, ( mlt_destructor )mlt_producer_close, NULL ); + if ( result != NULL ) + mlt_properties_set_data( properties, file, result, 0, ( mlt_destructor )mlt_producer_close, NULL ); } return result; @@ -204,6 +201,35 @@ static void clear_unit( miracle_unit unit ) update_generation( unit ); } +/** Wipe all but the playing clip from the unit. +*/ + +static void clean_unit( miracle_unit unit ) +{ + mlt_properties properties = unit->properties; + mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); + mlt_playlist_clip_info info; + int current = mlt_playlist_current_clip( playlist ); + mlt_producer producer = mlt_playlist_producer( playlist ); + mlt_position position = mlt_producer_frame( producer ); + double speed = mlt_producer_get_speed( producer ); + mlt_playlist_get_clip_info( playlist, &info, current ); + + if ( info.resource != NULL ) + { + void *instance = mlt_properties_get_data( unit->producers, info.resource, NULL ); + position -= info.start; + mlt_properties_set_data( unit->producers, info.resource, instance, 0, NULL, NULL ); + clear_unit( unit ); + mlt_playlist_append_io( playlist, instance, info.frame_in, info.frame_out ); + mlt_properties_set_data( unit->producers, info.resource, instance, 0, ( mlt_destructor )mlt_producer_close, NULL ); + mlt_producer_seek( producer, position ); + mlt_producer_set_speed( producer, speed ); + } + + update_generation( unit ); +} + /** Generate a report on all loaded clips. */ @@ -213,7 +239,6 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response ) mlt_properties properties = unit->properties; int generation = mlt_properties_get_int( properties, "generation" ); mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); - mlt_producer producer = mlt_playlist_producer( playlist ); valerie_response_printf( response, 1024, "%d\n", generation ); @@ -221,14 +246,16 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response ) { mlt_playlist_clip_info info; mlt_playlist_get_clip_info( playlist , &info, i ); - valerie_response_printf( response, 10240, "%d \"%s\" %lld %lld %lld %lld %.2f\n", - i, info.resource, + valerie_response_printf( response, 10240, "%d \"%s\" %d %d %d %d %.2f\n", + i, + strip_root( unit, info.resource ), info.frame_in, info.frame_out, - mlt_producer_frame_position( producer, info.playtime ), - mlt_producer_frame_position( producer, info.length ), + info.frame_count, + info.length, info.fps ); } + valerie_response_printf( response, 1024, "\n" ); } /** Load a clip into the unit clearing existing play list. @@ -240,19 +267,18 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response ) \param out The ending frame (-1 for maximum) */ -valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, int64_t in, int64_t out, int flush ) +valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, int32_t in, int32_t out, int flush ) { - // Have to clear the unit first - clear_unit( unit ); - // Now try to create an producer - mlt_producer instance = create_producer( unit, clip ); + mlt_producer instance = create_producer( clip ); if ( instance != NULL ) { + clear_unit( unit ); mlt_properties properties = unit->properties; + mlt_properties_set_data( unit->producers, clip, instance, 0, ( mlt_destructor )mlt_producer_close, NULL ); mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); - mlt_playlist_append_io( playlist, instance, mlt_producer_time( instance, in ), mlt_producer_time( instance, out ) ); + mlt_playlist_append_io( playlist, instance, in, out ); miracle_log( LOG_DEBUG, "loaded clip %s", clip ); miracle_unit_status_communicate( unit ); return valerie_ok; @@ -261,15 +287,16 @@ valerie_error_code miracle_unit_load( miracle_unit unit, char *clip, int64_t in, return valerie_invalid_file; } -valerie_error_code miracle_unit_insert( miracle_unit unit, char *clip, int index, int64_t in, int64_t out ) +valerie_error_code miracle_unit_insert( miracle_unit unit, char *clip, int index, int32_t in, int32_t out ) { - mlt_producer instance = create_producer( unit, clip ); + mlt_producer instance = locate_producer( unit, clip ); if ( instance != NULL ) { mlt_properties properties = unit->properties; mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); - mlt_playlist_insert( playlist, instance, index, mlt_producer_time( instance, in ), mlt_producer_time( instance, out ) ); + fprintf( stderr, "inserting clip %s before %d\n", clip, index ); + mlt_playlist_insert( playlist, instance, index, in, out ); miracle_log( LOG_DEBUG, "inserted clip %s at %d", clip, index ); update_generation( unit ); miracle_unit_status_communicate( unit ); @@ -292,8 +319,9 @@ valerie_error_code miracle_unit_remove( miracle_unit unit, int index ) valerie_error_code miracle_unit_clean( miracle_unit unit ) { - clear_unit( unit ); + clean_unit( unit ); miracle_log( LOG_DEBUG, "Cleaned playlist" ); + miracle_unit_status_communicate( unit ); return valerie_ok; } @@ -317,15 +345,15 @@ valerie_error_code miracle_unit_move( miracle_unit unit, int src, int dest ) \param out The ending frame (-1 for maximum) */ -valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, int64_t in, int64_t out ) +valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, int32_t in, int32_t out ) { - mlt_producer instance = create_producer( unit, clip ); + mlt_producer instance = locate_producer( unit, clip ); if ( instance != NULL ) { mlt_properties properties = unit->properties; mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); - mlt_playlist_append_io( playlist, instance, mlt_producer_time( instance, in ), mlt_producer_time( instance, out ) ); + mlt_playlist_append_io( playlist, instance, in, out ); miracle_log( LOG_DEBUG, "appended clip %s", clip ); update_generation( unit ); miracle_unit_status_communicate( unit ); @@ -335,9 +363,7 @@ valerie_error_code miracle_unit_append( miracle_unit unit, char *clip, int64_t i return valerie_invalid_file; } -/** Start playing the clip. - - Start a dv-pump and commence dv1394 transmission. +/** Start playing the unit. \todo error handling \param unit A miracle_unit handle. @@ -350,7 +376,9 @@ void miracle_unit_play( miracle_unit_t *unit, int speed ) mlt_properties properties = unit->properties; mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); mlt_producer producer = mlt_playlist_producer( playlist ); + mlt_consumer consumer = mlt_properties_get_data( unit->properties, "consumer", NULL ); mlt_producer_set_speed( producer, ( double )speed / 1000 ); + mlt_consumer_start( consumer ); miracle_unit_status_communicate( unit ); } @@ -363,6 +391,12 @@ void miracle_unit_play( miracle_unit_t *unit, int speed ) void miracle_unit_terminate( miracle_unit unit ) { + mlt_consumer consumer = mlt_properties_get_data( unit->properties, "consumer", NULL ); + mlt_playlist playlist = mlt_properties_get_data( unit->properties, "playlist", NULL ); + mlt_producer producer = mlt_playlist_producer( playlist ); + mlt_producer_set_speed( producer, 0 ); + mlt_consumer_stop( consumer ); + miracle_unit_status_communicate( unit ); } /** Query the status of unit playback. @@ -373,7 +407,8 @@ void miracle_unit_terminate( miracle_unit unit ) int miracle_unit_has_terminated( miracle_unit unit ) { - return 0; + mlt_consumer consumer = mlt_properties_get_data( unit->properties, "consumer", NULL ); + return mlt_consumer_is_stopped( consumer ); } /** Transfer the currently loaded clip to another unit @@ -381,6 +416,28 @@ int miracle_unit_has_terminated( miracle_unit unit ) int miracle_unit_transfer( miracle_unit dest_unit, miracle_unit src_unit ) { + int i; + mlt_properties dest_properties = dest_unit->properties; + mlt_playlist dest_playlist = mlt_properties_get_data( dest_properties, "playlist", NULL ); + mlt_properties src_properties = src_unit->properties; + mlt_playlist src_playlist = mlt_properties_get_data( src_properties, "playlist", NULL ); + + for ( i = 0; i < mlt_playlist_count( src_playlist ); i ++ ) + { + mlt_playlist_clip_info info; + mlt_playlist_get_clip_info( src_playlist, &info, i ); + mlt_producer producer = locate_producer( dest_unit, info.resource ); + if ( producer != NULL ) + { + mlt_playlist_append_io( dest_playlist, producer, info.frame_in, info.frame_out ); + if ( i == 0 ) + { + miracle_unit_change_position( dest_unit, mlt_playlist_count( dest_playlist ) - 1, 0 ); + clean_unit( dest_unit ); + } + } + } + return 0; } @@ -414,25 +471,27 @@ int miracle_unit_get_status( miracle_unit unit, valerie_status status ) if ( info.resource != NULL && strcmp( info.resource, "" ) ) { - strncpy( status->clip, info.resource, sizeof( status->clip ) ); + strncpy( status->clip, strip_root( unit, info.resource ), sizeof( status->clip ) ); status->speed = (int)( mlt_producer_get_speed( producer ) * 1000.0 ); status->fps = mlt_producer_get_fps( producer ); status->in = info.frame_in; status->out = info.frame_out; - status->position = mlt_producer_frame_position( producer, mlt_producer_position( clip ) ); - status->length = mlt_producer_frame_position( producer, mlt_producer_get_length( clip ) ); - strncpy( status->tail_clip, info.resource, sizeof( status->tail_clip ) ); + status->position = mlt_producer_position( clip ); + status->length = mlt_producer_get_length( clip ); + strncpy( status->tail_clip, strip_root( unit, info.resource ), sizeof( status->tail_clip ) ); status->tail_in = info.frame_in; status->tail_out = info.frame_out; - status->tail_position = mlt_producer_frame_position( producer, mlt_producer_position( clip ) ); - status->tail_length = mlt_producer_frame_position( producer, mlt_producer_get_length( clip ) ); + status->tail_position = mlt_producer_position( clip ); + status->tail_length = mlt_producer_get_length( clip ); status->clip_index = mlt_playlist_current_clip( playlist ); status->seek_flag = 1; } status->generation = mlt_properties_get_int( properties, "generation" ); - if ( !strcmp( status->clip, "" ) ) + if ( miracle_unit_has_terminated( unit ) ) + status->status = unit_stopped; + else if ( !strcmp( status->clip, "" ) ) status->status = unit_not_loaded; else if ( status->speed == 0 ) status->status = unit_paused; @@ -452,7 +511,7 @@ int miracle_unit_get_status( miracle_unit unit, valerie_status status ) /** Change position in the playlist. */ -void miracle_unit_change_position( miracle_unit unit, int clip, int64_t position ) +void miracle_unit_change_position( miracle_unit unit, int clip, int32_t position ) { mlt_properties properties = unit->properties; mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); @@ -467,13 +526,13 @@ void miracle_unit_change_position( miracle_unit unit, int clip, int64_t position else if ( clip >= mlt_playlist_count( playlist ) ) { clip = mlt_playlist_count( playlist ) - 1; - position = 999999999999; + position = LONG_MAX; } if ( mlt_playlist_get_clip_info( playlist, &info, clip ) == 0 ) { - int64_t frame_start = mlt_producer_frame_position( info.producer, info.start ); - int64_t frame_offset = position; + int32_t frame_start = info.start; + int32_t frame_offset = position; if ( frame_offset < 0 ) frame_offset = info.frame_out; @@ -482,7 +541,7 @@ void miracle_unit_change_position( miracle_unit unit, int clip, int64_t position if ( frame_offset >= info.frame_out ) frame_offset = info.frame_out; - mlt_producer_seek_frame( producer, frame_start + frame_offset - info.frame_in ); + mlt_producer_seek( producer, frame_start + frame_offset - info.frame_in ); } miracle_unit_status_communicate( unit ); @@ -502,7 +561,7 @@ int miracle_unit_get_current_clip( miracle_unit unit ) /** Set a clip's in point */ -int miracle_unit_set_clip_in( miracle_unit unit, int index, int64_t position ) +int miracle_unit_set_clip_in( miracle_unit unit, int index, int32_t position ) { mlt_properties properties = unit->properties; mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); @@ -511,8 +570,8 @@ int miracle_unit_set_clip_in( miracle_unit unit, int index, int64_t position ) if ( error == 0 ) { - mlt_timecode in = mlt_producer_time( info.producer, position ); - error = mlt_playlist_resize_clip( playlist, index, in, info.out ); + miracle_unit_play( unit, 0 ); + error = mlt_playlist_resize_clip( playlist, index, position, info.frame_out ); update_generation( unit ); miracle_unit_change_position( unit, index, 0 ); } @@ -523,7 +582,7 @@ int miracle_unit_set_clip_in( miracle_unit unit, int index, int64_t position ) /** Set a clip's out point. */ -int miracle_unit_set_clip_out( miracle_unit unit, int index, int64_t position ) +int miracle_unit_set_clip_out( miracle_unit unit, int index, int32_t position ) { mlt_properties properties = unit->properties; mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); @@ -532,8 +591,8 @@ int miracle_unit_set_clip_out( miracle_unit unit, int index, int64_t position ) if ( error == 0 ) { - mlt_timecode out = mlt_producer_time( info.producer, position ); - error = mlt_playlist_resize_clip( playlist, index, info.in, out ); + miracle_unit_play( unit, 0 ); + error = mlt_playlist_resize_clip( playlist, index, info.frame_in, position ); update_generation( unit ); miracle_unit_status_communicate( unit ); miracle_unit_change_position( unit, index, -1 ); @@ -545,13 +604,13 @@ int miracle_unit_set_clip_out( miracle_unit unit, int index, int64_t position ) /** Step by specified position. */ -void miracle_unit_step( miracle_unit unit, int64_t offset ) +void miracle_unit_step( miracle_unit unit, int32_t offset ) { mlt_properties properties = unit->properties; mlt_playlist playlist = mlt_properties_get_data( properties, "playlist", NULL ); mlt_producer producer = mlt_playlist_producer( playlist ); - mlt_timecode position = mlt_producer_position( producer ); - mlt_producer_seek_frame( producer, mlt_producer_frame_position( producer, position ) + offset ); + mlt_position position = mlt_producer_frame( producer ); + mlt_producer_seek( producer, position + offset ); } /** Set the unit's clip mode regarding in and out points. @@ -595,8 +654,20 @@ void miracle_unit_step( miracle_unit unit, int64_t offset ) int miracle_unit_set( miracle_unit unit, char *name_value ) { - mlt_playlist playlist = mlt_properties_get_data( unit->properties, "playlist", NULL ); - mlt_properties properties = mlt_playlist_properties( playlist ); + mlt_properties properties = NULL; + + if ( strncmp( name_value, "consumer.", 9 ) ) + { + mlt_playlist playlist = mlt_properties_get_data( unit->properties, "playlist", NULL ); + properties = mlt_playlist_properties( playlist ); + } + else + { + mlt_consumer consumer = mlt_properties_get_data( unit->properties, "consumer", NULL ); + properties = mlt_consumer_properties( consumer ); + name_value += 9; + } + return mlt_properties_parse( properties, name_value ); }