mlt_properties_set_int( play, "put_mode", 1 );
mlt_properties_set_int( still, "put_mode", 1 );
+ mlt_properties_set_int( play, "terminate_on_pause", 1 );
// Start the still producer just to initialise the gui
mlt_consumer_start( this->still );
// Identify the arg
consumer_sdl this = arg;
- // Get the consumer
+ // Get the consumer and producer
mlt_consumer consumer = &this->parent;
+ mlt_producer producer = MLT_PRODUCER( mlt_service_get_producer( MLT_CONSUMER_SERVICE( consumer ) ) );
// Get the properties
mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
int first = 1;
mlt_frame frame = NULL;
int last_position = -1;
+ int eof_threshold = 10 + mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( this->play ), "buffer" );
// Determine if the application is dealing with the preview
int preview_off = mlt_properties_get_int( properties, "preview_off" );
last_position = -1;
}
- // If we're not the first frame and both consumers are stopped, then stop ourselves
- if ( !first && mlt_consumer_is_stopped( this->play ) && mlt_consumer_is_stopped( this->still ) )
- {
- this->running = 0;
- mlt_frame_close( frame );
- }
- // Allow a little grace time before switching consumers on speed changes
- else if ( this->ignore_change -- > 0 && this->active != NULL && !mlt_consumer_is_stopped( this->active ) )
- {
- mlt_consumer_put_frame( this->active, frame );
- }
// If we aren't playing normally, then use the still
- else if ( speed != 1 )
+ if ( speed != 1 )
{
- if ( !mlt_consumer_is_stopped( this->play ) )
+ mlt_position duration = mlt_producer_get_playtime( producer );
+
+ // Do not interrupt the normal consumer near the end
+ if ( !mlt_consumer_is_stopped( this->play ) && ( duration - this->last_position ) > eof_threshold )
mlt_consumer_stop( this->play );
+
+ // Switch to the still consumer
if ( mlt_consumer_is_stopped( this->still ) )
{
- mlt_producer producer = mlt_service_get_producer( MLT_CONSUMER_SERVICE( consumer ) );
+ // If near the end, wait for the normal consumer to play out its buffers
+ if ( ! mlt_consumer_is_stopped( this->play ) && speed == 0.0 )
+ {
+ // This frame with speed=0 will tell normal consumer to terminate
+ mlt_consumer_put_frame( this->play, frame );
+ while ( ! mlt_consumer_is_stopped( this->play ) )
+ {
+ struct timespec tm = { 0, 10000000L }; // 10 ms
+ nanosleep( &tm, NULL );
+ }
+
+ // We want to be positioned at the end
+ if ( duration - this->last_position < 10 )
+ this->last_position = duration - 1;
+ }
+ else
+ {
+ // We will need a new frame at the correct position
+ mlt_frame_close( frame );
+ }
+
+ // Get a new frame at the sought position
if ( producer )
mlt_producer_seek( producer, this->last_position );
+ frame = mlt_consumer_get_frame( consumer );
+
+ // Start the still consumer
this->last_speed = speed;
this->active = this->still;
- this->ignore_change = 0;
+ this->ignore_change = 25;
mlt_consumer_start( this->still );
- mlt_frame_close( frame );
}
- else
- {
+ // Use the still consumer
+ if ( frame )
mlt_consumer_put_frame( this->still, frame );
- }
+ }
+ // Allow a little grace time before switching consumers on speed changes
+ else if ( this->ignore_change -- > 0 && this->active != NULL && !mlt_consumer_is_stopped( this->active ) )
+ {
+ mlt_consumer_put_frame( this->active, frame );
}
// Otherwise use the normal player
else
{
this->last_speed = speed;
this->active = this->play;
- this->ignore_change = 25;
+ this->ignore_change = 0;
mlt_consumer_start( this->play );
}
mlt_consumer_put_frame( this->play, frame );