]> git.sesse.net Git - mlt/commitdiff
more int64 frame addressing in playlist
authorlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sat, 10 Jan 2004 17:36:56 +0000 (17:36 +0000)
committerlilo_booter <lilo_booter@d19143bc-622f-0410-bfdd-b5b2a6649095>
Sat, 10 Jan 2004 17:36:56 +0000 (17:36 +0000)
git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@47 d19143bc-622f-0410-bfdd-b5b2a6649095

mlt/src/framework/mlt_playlist.c
mlt/src/framework/mlt_playlist.h
mlt/src/framework/mlt_producer.c
mlt/src/framework/mlt_producer.h
mlt/src/miracle/miracle_unit.c
src/framework/mlt_playlist.c
src/framework/mlt_playlist.h
src/framework/mlt_producer.c
src/framework/mlt_producer.h
src/miracle/miracle_unit.c

index c28705bf1d54598c59e8696c9b6fc78647024317..32179aa35d7a8f5bc07a6f7f208ef1cdf67511c2 100644 (file)
@@ -33,7 +33,9 @@
 typedef struct
 {
        mlt_producer producer;
-       mlt_timecode in;
+       int64_t frame_in;
+       int64_t frame_out;
+       int64_t frame_count;
        mlt_timecode playtime;
 }
 playlist_entry;
@@ -150,8 +152,11 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
 /** Append to the virtual playlist.
 */
 
-static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_timecode in, mlt_timecode playtime )
+static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, int64_t in, int64_t out )
 {
+       double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "fps" );
+       double playtime = ( double )( out - in + 1 ) / fps;
+
        // Check that we have room
        if ( this->count >= this->size )
        {
@@ -164,9 +169,13 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer
 
        this->list[ this->count ] = calloc( sizeof( playlist_entry ), 1 );
        this->list[ this->count ]->producer = producer;
-       this->list[ this->count ]->in = in;
+       this->list[ this->count ]->frame_in = in;
+       this->list[ this->count ]->frame_out = out;
+       this->list[ this->count ]->frame_count = out - in + 1;
        this->list[ this->count ]->playtime = playtime;
 
+       mlt_producer_set_speed( producer, 0 );
+
        this->count ++;
 
        return mlt_playlist_virtual_refresh( this );
@@ -178,32 +187,53 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer
 static mlt_producer mlt_playlist_virtual_seek( mlt_playlist this )
 {
        // Default producer to blank
-       mlt_producer producer = &this->blank;
+       mlt_producer producer = NULL;
 
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode position = mlt_producer_position( &this->parent );
+       mlt_timecode pos = mlt_producer_position( &this->parent );
+       int64_t position = mlt_producer_frame_position( &this->parent, pos );
+       int64_t total = 0;
 
        // Loop through the virtual playlist
        int i = 0;
 
        for ( i = 0; i < this->count; i ++ )
        {
-               if ( position < this->list[ i ]->playtime )
+               // Increment the total
+               total += this->list[ i ]->frame_count;
+
+               if ( position < this->list[ i ]->frame_count )
                {
                        // Found it, now break
                        producer = this->list[ i ]->producer;
-                       position += this->list[ i ]->in;
+                       position += this->list[ i ]->frame_in;
                        break;
                }
                else
                {
                        // Decrement position by length of this entry
-                       position -= this->list[ i ]->playtime;
+                       position -= this->list[ i ]->frame_count;
                }
        }
 
        // Seek in real producer to relative position
-       mlt_producer_seek( producer, position );
+       if ( producer != NULL )
+       {
+               mlt_producer_seek_frame( producer, position );
+       }
+       else if ( total > 0 )
+       {
+               playlist_entry *entry = this->list[ this->count - 1 ];
+               mlt_producer this_producer = mlt_playlist_producer( this );
+               mlt_producer_seek_frame( this_producer, total - 1 );
+               producer = entry->producer;
+               mlt_producer_seek_frame( producer, entry->frame_out );
+       }
+       else
+       {
+               mlt_producer_seek( mlt_playlist_producer( this ), 0 );
+               producer = &this->blank;
+       }
 
        return producer;
 }
@@ -214,24 +244,24 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
        mlt_producer producer = &this->blank;
 
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode position = mlt_producer_position( &this->parent );
+       mlt_timecode pos = mlt_producer_position( &this->parent );
+       int64_t position = mlt_producer_frame_position( &this->parent, pos );
 
        // Loop through the virtual playlist
        int i = 0;
 
        for ( i = 0; i < this->count; i ++ )
        {
-               if ( position < this->list[ i ]->playtime )
+               if ( position < this->list[ i ]->frame_count )
                {
                        // Found it, now break
                        producer = this->list[ i ]->producer;
-                       position += this->list[ i ]->in;
                        break;
                }
                else
                {
                        // Decrement position by length of this entry
-                       position -= this->list[ i ]->playtime;
+                       position -= this->list[ i ]->frame_count;
                }
        }
 
@@ -239,7 +269,8 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
        if ( i < this->count )
        {
                // Update the playtime for the changed clip (hmmm)
-               this->list[ i ]->playtime = position - this->list[ i ]->in;
+               this->list[ i ]->frame_count = position + 1;
+               this->list[ i ]->frame_out = position - this->list[ i ]->frame_in;
 
                // Refresh the playlist
                mlt_playlist_virtual_refresh( this );
@@ -251,14 +282,15 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
 int mlt_playlist_current_clip( mlt_playlist this )
 {
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode position = mlt_producer_position( &this->parent );
+       mlt_timecode pos = mlt_producer_position( &this->parent );
+       int64_t position = mlt_producer_frame_position( &this->parent, pos );
 
        // Loop through the virtual playlist
        int i = 0;
 
        for ( i = 0; i < this->count; i ++ )
        {
-               if ( position < this->list[ i ]->playtime )
+               if ( position < this->list[ i ]->frame_count )
                {
                        // Found it, now break
                        break;
@@ -266,7 +298,7 @@ int mlt_playlist_current_clip( mlt_playlist this )
                else
                {
                        // Decrement position by length of this entry
-                       position -= this->list[ i ]->playtime;
+                       position -= this->list[ i ]->frame_count;
                }
        }
 
@@ -287,7 +319,7 @@ mlt_producer mlt_playlist_current( mlt_playlist this )
 
 mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index )
 {
-       mlt_timecode position = 0;
+       int64_t position = 0;
        int absolute_clip = index;
        int i = 0;
 
@@ -315,9 +347,9 @@ mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index
 
        // Now determine the timecode
        for ( i = 0; i < absolute_clip; i ++ )
-               position += this->list[ i ]->playtime;
+               position += this->list[ i ]->frame_count;
 
-       return position;
+       return mlt_producer_time( &this->parent, position );
 }
 
 int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index )
@@ -331,8 +363,10 @@ int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info,
                info->producer = producer;
                info->start = mlt_playlist_clip( this, mlt_whence_relative_start, index );
                info->resource = mlt_properties_get( properties, "resource" );
-               info->in = this->list[ index ]->in;
-               info->out = this->list[ index ]->in + this->list[ index ]->playtime;
+               info->frame_in = this->list[ index ]->frame_in;
+               info->in = mlt_producer_time( producer, info->frame_in );
+               info->frame_out = this->list[ index ]->frame_out;
+               info->out = mlt_producer_time( producer, info->frame_out );
                info->playtime = this->list[ index ]->playtime;
                info->length = mlt_producer_get_length( producer );
                info->fps = mlt_producer_get_fps( producer );
@@ -364,7 +398,8 @@ int mlt_playlist_clear( mlt_playlist this )
 int mlt_playlist_append( mlt_playlist this, mlt_producer producer )
 {
        // Append to virtual list
-       return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) );
+       int64_t out = mlt_producer_frame_position( producer, mlt_producer_get_out( producer ) );
+       return mlt_playlist_virtual_append( this, producer, 0, out );
 }
 
 /** Append a producer to the playlist with in/out points.
@@ -374,9 +409,15 @@ int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in,
 {
        // Append to virtual list
        if ( in != -1 && out != -1 )
-               return mlt_playlist_virtual_append( this, producer, in, out - in );
+       {
+               int64_t fin = mlt_producer_frame_position( producer, in );
+               int64_t fout = mlt_producer_frame_position( producer, out );
+               return mlt_playlist_virtual_append( this, producer, fin, fout );
+       }
        else
-               return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) );
+       {
+               return mlt_playlist_append( this, producer );
+       }
 }
 
 /** Append a blank to the playlist of a given length.
@@ -385,7 +426,8 @@ int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in,
 int mlt_playlist_blank( mlt_playlist this, mlt_timecode length )
 {
        // Append to the virtual list
-       return mlt_playlist_virtual_append( this, &this->blank, 0, length );
+       int64_t fout = mlt_producer_frame_position( &this->blank, length );
+       return mlt_playlist_virtual_append( this, &this->blank, 0, fout );
 }
 
 /** Insert a producer into the playlist.
@@ -426,7 +468,12 @@ int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_timecode in, mlt_
                        out = t;
                }
 
-               entry->in = in;
+               int64_t fin = mlt_producer_frame_position( producer, in );
+               int64_t fout = mlt_producer_frame_position( producer, out );
+
+               entry->frame_in = fin;
+               entry->frame_out = fout;
+               entry->frame_count = fout - fin + 1;
                entry->playtime = out - in;
                mlt_playlist_virtual_refresh( this );
        }
index 48b4a55a35f8f98b2012108b8ce19044ebfbaf8b..8cdcccef8b38a3cd9be648340a3a33a626e50243 100644 (file)
@@ -32,7 +32,9 @@ typedef struct
        mlt_timecode start;
        char *resource;
        mlt_timecode in;
+       int64_t frame_in;
        mlt_timecode out;
+       int64_t frame_out;
        mlt_timecode playtime;
        mlt_timecode length;
        float fps;
index 277db6912ff0bbb6f82b9ef3e4a7d0ac06b0d9ee..278d9026957b9455183024663a65c405bbfc11b3 100644 (file)
@@ -133,13 +133,13 @@ int mlt_producer_seek( mlt_producer this, mlt_timecode timecode )
 /** Seek to a specified absolute frame.
 */
 
-int mlt_producer_seek_frame( mlt_producer this, uint64_t frame )
+int mlt_producer_seek_frame( mlt_producer this, int64_t frame )
 {
        // Calculate the time code
        double timecode = ( frame / mlt_producer_get_fps( this ) ) - mlt_producer_get_in( this );
 
        // If timecode is invalid, then seek on time
-       if ( timecode < 0 )
+       if ( frame < 0 || timecode < 0 )
        {
                // Seek to the in point
                mlt_producer_seek( this, 0 );
index 888c3bc55e86c10f3e54ec8929a0429a2bc6edaf..52976524f8fb5e5d840f9c6c7d9ac8a027ff8a69 100644 (file)
@@ -49,7 +49,7 @@ extern mlt_properties mlt_producer_properties( mlt_producer this );
 extern mlt_timecode mlt_producer_time( mlt_producer this, int64_t frame );
 extern int64_t mlt_producer_frame_position( mlt_producer this, mlt_timecode position );
 extern int mlt_producer_seek( mlt_producer this, mlt_timecode timecode );
-extern int mlt_producer_seek_frame( mlt_producer this, uint64_t frame );
+extern int mlt_producer_seek_frame( mlt_producer this, int64_t frame );
 extern mlt_timecode mlt_producer_position( mlt_producer this );
 extern uint64_t mlt_producer_frame( mlt_producer this );
 extern int mlt_producer_set_speed( mlt_producer this, double speed );
index bc90d69b9a85bd27187605e701783afcdd379c3e..ba8bf09839b6f94afa982450f48358815d879dee 100644 (file)
@@ -223,8 +223,8 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response )
                mlt_playlist_get_clip_info( playlist , &info, i );
                valerie_response_printf( response, 10240, "%d \"%s\" %lld %lld %lld %lld %.2f\n", 
                                                                 i, info.resource, 
-                                                                mlt_producer_frame_position( producer, info.in )
-                                                                mlt_producer_frame_position( producer, info.out ),
+                                                                info.frame_in
+                                                                info.frame_out,
                                                                 mlt_producer_frame_position( producer, info.playtime ), 
                                                                 mlt_producer_frame_position( producer, info.length ), 
                                                                 info.fps );
@@ -417,13 +417,13 @@ int miracle_unit_get_status( miracle_unit unit, valerie_status status )
                        strncpy( status->clip, info.resource, sizeof( status->clip ) );
                        status->speed = (int)( mlt_producer_get_speed( producer ) * 1000.0 );
                        status->fps = mlt_producer_get_fps( producer );
-                       status->in = mlt_producer_frame_position( producer, info.in );
-                       status->out = mlt_producer_frame_position( producer, info.out );
+                       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->tail_in = mlt_producer_frame_position( producer, info.in );
-                       status->tail_out = mlt_producer_frame_position( producer, info.out );
+                       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->clip_index = mlt_playlist_current_clip( playlist );
@@ -460,30 +460,29 @@ void miracle_unit_change_position( miracle_unit unit, int clip, int64_t position
        mlt_playlist_clip_info info;
 
        if ( clip < 0 )
+       {
                clip = 0;
+               position = 0;
+       }
        else if ( clip >= mlt_playlist_count( playlist ) )
-               clip = mlt_playlist_count( playlist );
+       {
+               clip = mlt_playlist_count( playlist ) - 1;
+               position = 999999999999;
+       }
 
        if ( mlt_playlist_get_clip_info( playlist, &info, clip ) == 0 )
        {
-               mlt_timecode relative = mlt_producer_time( info.producer, position );
-               mlt_timecode absolute = relative - info.in;
                int64_t frame_start = mlt_producer_frame_position( info.producer, info.start );
-               int64_t frame_offset = 0;
-
-               if ( absolute < 0 )
-                       frame_offset = 0;
-               else if ( absolute >= info.out )
-                       frame_offset = mlt_producer_frame_position( info.producer, info.out ) - 1;
-               else
-                       frame_offset = mlt_producer_frame_position( info.producer, absolute );
-
-               mlt_producer_seek_frame( producer, frame_start + frame_offset );
-       }
-       else
-       {
-               mlt_timecode out = mlt_producer_get_out( producer );
-               mlt_producer_seek( producer, mlt_producer_frame_position( producer, out ) - 1 );
+               int64_t frame_offset = position;
+
+               if ( frame_offset < 0 )
+                       frame_offset = info.frame_out;
+               if ( frame_offset < info.frame_in )
+                       frame_offset = info.frame_in;
+               if ( frame_offset >= info.frame_out )
+                       frame_offset = info.frame_out;
+               
+               mlt_producer_seek_frame( producer, frame_start + frame_offset - info.frame_in );
        }
 
        miracle_unit_status_communicate( unit );
@@ -537,7 +536,7 @@ int miracle_unit_set_clip_out( miracle_unit unit, int index, int64_t position )
                error = mlt_playlist_resize_clip( playlist, index, info.in, out );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
-               miracle_unit_change_position( unit, index, 0 );
+               miracle_unit_change_position( unit, index, -1 );
        }
 
        return error;
@@ -552,7 +551,7 @@ void miracle_unit_step( miracle_unit unit, int64_t offset )
        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( producer, position + mlt_producer_time( producer, offset ) );
+       mlt_producer_seek_frame( producer, mlt_producer_frame_position( producer, position ) + offset );
 }
 
 /** Set the unit's clip mode regarding in and out points.
index c28705bf1d54598c59e8696c9b6fc78647024317..32179aa35d7a8f5bc07a6f7f208ef1cdf67511c2 100644 (file)
@@ -33,7 +33,9 @@
 typedef struct
 {
        mlt_producer producer;
-       mlt_timecode in;
+       int64_t frame_in;
+       int64_t frame_out;
+       int64_t frame_count;
        mlt_timecode playtime;
 }
 playlist_entry;
@@ -150,8 +152,11 @@ static int mlt_playlist_virtual_refresh( mlt_playlist this )
 /** Append to the virtual playlist.
 */
 
-static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, mlt_timecode in, mlt_timecode playtime )
+static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer, int64_t in, int64_t out )
 {
+       double fps = mlt_properties_get_double( mlt_playlist_properties( this ), "fps" );
+       double playtime = ( double )( out - in + 1 ) / fps;
+
        // Check that we have room
        if ( this->count >= this->size )
        {
@@ -164,9 +169,13 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer
 
        this->list[ this->count ] = calloc( sizeof( playlist_entry ), 1 );
        this->list[ this->count ]->producer = producer;
-       this->list[ this->count ]->in = in;
+       this->list[ this->count ]->frame_in = in;
+       this->list[ this->count ]->frame_out = out;
+       this->list[ this->count ]->frame_count = out - in + 1;
        this->list[ this->count ]->playtime = playtime;
 
+       mlt_producer_set_speed( producer, 0 );
+
        this->count ++;
 
        return mlt_playlist_virtual_refresh( this );
@@ -178,32 +187,53 @@ static int mlt_playlist_virtual_append( mlt_playlist this, mlt_producer producer
 static mlt_producer mlt_playlist_virtual_seek( mlt_playlist this )
 {
        // Default producer to blank
-       mlt_producer producer = &this->blank;
+       mlt_producer producer = NULL;
 
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode position = mlt_producer_position( &this->parent );
+       mlt_timecode pos = mlt_producer_position( &this->parent );
+       int64_t position = mlt_producer_frame_position( &this->parent, pos );
+       int64_t total = 0;
 
        // Loop through the virtual playlist
        int i = 0;
 
        for ( i = 0; i < this->count; i ++ )
        {
-               if ( position < this->list[ i ]->playtime )
+               // Increment the total
+               total += this->list[ i ]->frame_count;
+
+               if ( position < this->list[ i ]->frame_count )
                {
                        // Found it, now break
                        producer = this->list[ i ]->producer;
-                       position += this->list[ i ]->in;
+                       position += this->list[ i ]->frame_in;
                        break;
                }
                else
                {
                        // Decrement position by length of this entry
-                       position -= this->list[ i ]->playtime;
+                       position -= this->list[ i ]->frame_count;
                }
        }
 
        // Seek in real producer to relative position
-       mlt_producer_seek( producer, position );
+       if ( producer != NULL )
+       {
+               mlt_producer_seek_frame( producer, position );
+       }
+       else if ( total > 0 )
+       {
+               playlist_entry *entry = this->list[ this->count - 1 ];
+               mlt_producer this_producer = mlt_playlist_producer( this );
+               mlt_producer_seek_frame( this_producer, total - 1 );
+               producer = entry->producer;
+               mlt_producer_seek_frame( producer, entry->frame_out );
+       }
+       else
+       {
+               mlt_producer_seek( mlt_playlist_producer( this ), 0 );
+               producer = &this->blank;
+       }
 
        return producer;
 }
@@ -214,24 +244,24 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
        mlt_producer producer = &this->blank;
 
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode position = mlt_producer_position( &this->parent );
+       mlt_timecode pos = mlt_producer_position( &this->parent );
+       int64_t position = mlt_producer_frame_position( &this->parent, pos );
 
        // Loop through the virtual playlist
        int i = 0;
 
        for ( i = 0; i < this->count; i ++ )
        {
-               if ( position < this->list[ i ]->playtime )
+               if ( position < this->list[ i ]->frame_count )
                {
                        // Found it, now break
                        producer = this->list[ i ]->producer;
-                       position += this->list[ i ]->in;
                        break;
                }
                else
                {
                        // Decrement position by length of this entry
-                       position -= this->list[ i ]->playtime;
+                       position -= this->list[ i ]->frame_count;
                }
        }
 
@@ -239,7 +269,8 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
        if ( i < this->count )
        {
                // Update the playtime for the changed clip (hmmm)
-               this->list[ i ]->playtime = position - this->list[ i ]->in;
+               this->list[ i ]->frame_count = position + 1;
+               this->list[ i ]->frame_out = position - this->list[ i ]->frame_in;
 
                // Refresh the playlist
                mlt_playlist_virtual_refresh( this );
@@ -251,14 +282,15 @@ static mlt_producer mlt_playlist_virtual_set_out( mlt_playlist this )
 int mlt_playlist_current_clip( mlt_playlist this )
 {
        // Map playlist position to real producer in virtual playlist
-       mlt_timecode position = mlt_producer_position( &this->parent );
+       mlt_timecode pos = mlt_producer_position( &this->parent );
+       int64_t position = mlt_producer_frame_position( &this->parent, pos );
 
        // Loop through the virtual playlist
        int i = 0;
 
        for ( i = 0; i < this->count; i ++ )
        {
-               if ( position < this->list[ i ]->playtime )
+               if ( position < this->list[ i ]->frame_count )
                {
                        // Found it, now break
                        break;
@@ -266,7 +298,7 @@ int mlt_playlist_current_clip( mlt_playlist this )
                else
                {
                        // Decrement position by length of this entry
-                       position -= this->list[ i ]->playtime;
+                       position -= this->list[ i ]->frame_count;
                }
        }
 
@@ -287,7 +319,7 @@ mlt_producer mlt_playlist_current( mlt_playlist this )
 
 mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index )
 {
-       mlt_timecode position = 0;
+       int64_t position = 0;
        int absolute_clip = index;
        int i = 0;
 
@@ -315,9 +347,9 @@ mlt_timecode mlt_playlist_clip( mlt_playlist this, mlt_whence whence, int index
 
        // Now determine the timecode
        for ( i = 0; i < absolute_clip; i ++ )
-               position += this->list[ i ]->playtime;
+               position += this->list[ i ]->frame_count;
 
-       return position;
+       return mlt_producer_time( &this->parent, position );
 }
 
 int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info, int index )
@@ -331,8 +363,10 @@ int mlt_playlist_get_clip_info( mlt_playlist this, mlt_playlist_clip_info *info,
                info->producer = producer;
                info->start = mlt_playlist_clip( this, mlt_whence_relative_start, index );
                info->resource = mlt_properties_get( properties, "resource" );
-               info->in = this->list[ index ]->in;
-               info->out = this->list[ index ]->in + this->list[ index ]->playtime;
+               info->frame_in = this->list[ index ]->frame_in;
+               info->in = mlt_producer_time( producer, info->frame_in );
+               info->frame_out = this->list[ index ]->frame_out;
+               info->out = mlt_producer_time( producer, info->frame_out );
                info->playtime = this->list[ index ]->playtime;
                info->length = mlt_producer_get_length( producer );
                info->fps = mlt_producer_get_fps( producer );
@@ -364,7 +398,8 @@ int mlt_playlist_clear( mlt_playlist this )
 int mlt_playlist_append( mlt_playlist this, mlt_producer producer )
 {
        // Append to virtual list
-       return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) );
+       int64_t out = mlt_producer_frame_position( producer, mlt_producer_get_out( producer ) );
+       return mlt_playlist_virtual_append( this, producer, 0, out );
 }
 
 /** Append a producer to the playlist with in/out points.
@@ -374,9 +409,15 @@ int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in,
 {
        // Append to virtual list
        if ( in != -1 && out != -1 )
-               return mlt_playlist_virtual_append( this, producer, in, out - in );
+       {
+               int64_t fin = mlt_producer_frame_position( producer, in );
+               int64_t fout = mlt_producer_frame_position( producer, out );
+               return mlt_playlist_virtual_append( this, producer, fin, fout );
+       }
        else
-               return mlt_playlist_virtual_append( this, producer, 0, mlt_producer_get_playtime( producer ) );
+       {
+               return mlt_playlist_append( this, producer );
+       }
 }
 
 /** Append a blank to the playlist of a given length.
@@ -385,7 +426,8 @@ int mlt_playlist_append_io( mlt_playlist this, mlt_producer producer, double in,
 int mlt_playlist_blank( mlt_playlist this, mlt_timecode length )
 {
        // Append to the virtual list
-       return mlt_playlist_virtual_append( this, &this->blank, 0, length );
+       int64_t fout = mlt_producer_frame_position( &this->blank, length );
+       return mlt_playlist_virtual_append( this, &this->blank, 0, fout );
 }
 
 /** Insert a producer into the playlist.
@@ -426,7 +468,12 @@ int mlt_playlist_resize_clip( mlt_playlist this, int clip, mlt_timecode in, mlt_
                        out = t;
                }
 
-               entry->in = in;
+               int64_t fin = mlt_producer_frame_position( producer, in );
+               int64_t fout = mlt_producer_frame_position( producer, out );
+
+               entry->frame_in = fin;
+               entry->frame_out = fout;
+               entry->frame_count = fout - fin + 1;
                entry->playtime = out - in;
                mlt_playlist_virtual_refresh( this );
        }
index 48b4a55a35f8f98b2012108b8ce19044ebfbaf8b..8cdcccef8b38a3cd9be648340a3a33a626e50243 100644 (file)
@@ -32,7 +32,9 @@ typedef struct
        mlt_timecode start;
        char *resource;
        mlt_timecode in;
+       int64_t frame_in;
        mlt_timecode out;
+       int64_t frame_out;
        mlt_timecode playtime;
        mlt_timecode length;
        float fps;
index 277db6912ff0bbb6f82b9ef3e4a7d0ac06b0d9ee..278d9026957b9455183024663a65c405bbfc11b3 100644 (file)
@@ -133,13 +133,13 @@ int mlt_producer_seek( mlt_producer this, mlt_timecode timecode )
 /** Seek to a specified absolute frame.
 */
 
-int mlt_producer_seek_frame( mlt_producer this, uint64_t frame )
+int mlt_producer_seek_frame( mlt_producer this, int64_t frame )
 {
        // Calculate the time code
        double timecode = ( frame / mlt_producer_get_fps( this ) ) - mlt_producer_get_in( this );
 
        // If timecode is invalid, then seek on time
-       if ( timecode < 0 )
+       if ( frame < 0 || timecode < 0 )
        {
                // Seek to the in point
                mlt_producer_seek( this, 0 );
index 888c3bc55e86c10f3e54ec8929a0429a2bc6edaf..52976524f8fb5e5d840f9c6c7d9ac8a027ff8a69 100644 (file)
@@ -49,7 +49,7 @@ extern mlt_properties mlt_producer_properties( mlt_producer this );
 extern mlt_timecode mlt_producer_time( mlt_producer this, int64_t frame );
 extern int64_t mlt_producer_frame_position( mlt_producer this, mlt_timecode position );
 extern int mlt_producer_seek( mlt_producer this, mlt_timecode timecode );
-extern int mlt_producer_seek_frame( mlt_producer this, uint64_t frame );
+extern int mlt_producer_seek_frame( mlt_producer this, int64_t frame );
 extern mlt_timecode mlt_producer_position( mlt_producer this );
 extern uint64_t mlt_producer_frame( mlt_producer this );
 extern int mlt_producer_set_speed( mlt_producer this, double speed );
index bc90d69b9a85bd27187605e701783afcdd379c3e..ba8bf09839b6f94afa982450f48358815d879dee 100644 (file)
@@ -223,8 +223,8 @@ void miracle_unit_report_list( miracle_unit unit, valerie_response response )
                mlt_playlist_get_clip_info( playlist , &info, i );
                valerie_response_printf( response, 10240, "%d \"%s\" %lld %lld %lld %lld %.2f\n", 
                                                                 i, info.resource, 
-                                                                mlt_producer_frame_position( producer, info.in )
-                                                                mlt_producer_frame_position( producer, info.out ),
+                                                                info.frame_in
+                                                                info.frame_out,
                                                                 mlt_producer_frame_position( producer, info.playtime ), 
                                                                 mlt_producer_frame_position( producer, info.length ), 
                                                                 info.fps );
@@ -417,13 +417,13 @@ int miracle_unit_get_status( miracle_unit unit, valerie_status status )
                        strncpy( status->clip, info.resource, sizeof( status->clip ) );
                        status->speed = (int)( mlt_producer_get_speed( producer ) * 1000.0 );
                        status->fps = mlt_producer_get_fps( producer );
-                       status->in = mlt_producer_frame_position( producer, info.in );
-                       status->out = mlt_producer_frame_position( producer, info.out );
+                       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->tail_in = mlt_producer_frame_position( producer, info.in );
-                       status->tail_out = mlt_producer_frame_position( producer, info.out );
+                       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->clip_index = mlt_playlist_current_clip( playlist );
@@ -460,30 +460,29 @@ void miracle_unit_change_position( miracle_unit unit, int clip, int64_t position
        mlt_playlist_clip_info info;
 
        if ( clip < 0 )
+       {
                clip = 0;
+               position = 0;
+       }
        else if ( clip >= mlt_playlist_count( playlist ) )
-               clip = mlt_playlist_count( playlist );
+       {
+               clip = mlt_playlist_count( playlist ) - 1;
+               position = 999999999999;
+       }
 
        if ( mlt_playlist_get_clip_info( playlist, &info, clip ) == 0 )
        {
-               mlt_timecode relative = mlt_producer_time( info.producer, position );
-               mlt_timecode absolute = relative - info.in;
                int64_t frame_start = mlt_producer_frame_position( info.producer, info.start );
-               int64_t frame_offset = 0;
-
-               if ( absolute < 0 )
-                       frame_offset = 0;
-               else if ( absolute >= info.out )
-                       frame_offset = mlt_producer_frame_position( info.producer, info.out ) - 1;
-               else
-                       frame_offset = mlt_producer_frame_position( info.producer, absolute );
-
-               mlt_producer_seek_frame( producer, frame_start + frame_offset );
-       }
-       else
-       {
-               mlt_timecode out = mlt_producer_get_out( producer );
-               mlt_producer_seek( producer, mlt_producer_frame_position( producer, out ) - 1 );
+               int64_t frame_offset = position;
+
+               if ( frame_offset < 0 )
+                       frame_offset = info.frame_out;
+               if ( frame_offset < info.frame_in )
+                       frame_offset = info.frame_in;
+               if ( frame_offset >= info.frame_out )
+                       frame_offset = info.frame_out;
+               
+               mlt_producer_seek_frame( producer, frame_start + frame_offset - info.frame_in );
        }
 
        miracle_unit_status_communicate( unit );
@@ -537,7 +536,7 @@ int miracle_unit_set_clip_out( miracle_unit unit, int index, int64_t position )
                error = mlt_playlist_resize_clip( playlist, index, info.in, out );
                update_generation( unit );
                miracle_unit_status_communicate( unit );
-               miracle_unit_change_position( unit, index, 0 );
+               miracle_unit_change_position( unit, index, -1 );
        }
 
        return error;
@@ -552,7 +551,7 @@ void miracle_unit_step( miracle_unit unit, int64_t offset )
        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( producer, position + mlt_producer_time( producer, offset ) );
+       mlt_producer_seek_frame( producer, mlt_producer_frame_position( producer, position ) + offset );
 }
 
 /** Set the unit's clip mode regarding in and out points.