* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "config.h"
#include "mlt_consumer.h"
#include "mlt_factory.h"
#include "mlt_producer.h"
#include <stdlib.h>
#include <sys/time.h>
+#undef DEINTERLACE_ON_NOT_NORMAL_SPEED
+
static void mlt_consumer_frame_render( mlt_listener listener, mlt_properties owner, mlt_service this, void **args );
static void mlt_consumer_frame_show( mlt_listener listener, mlt_properties owner, mlt_service this, void **args );
static void mlt_consumer_property_changed( mlt_service owner, mlt_consumer this, char *name );
mlt_properties_set_data( properties, "test_card_producer", NULL, 0, NULL, NULL );
}
+ // Set the frame duration in microseconds for the frame-dropping heuristic
+ int frame_duration = 1000000 / mlt_properties_get_int( properties, "frame_rate_num" ) *
+ mlt_properties_get_int( properties, "frame_rate_den" );
+ mlt_properties_set_int( properties, "frame_duration", frame_duration );
+
// Check and run an ante command
if ( mlt_properties_get( properties, "ante" ) )
system( mlt_properties_get( properties, "ante" ) );
// All non normal playback frames should be shown
if ( mlt_properties_get_int( MLT_FRAME_PROPERTIES( frame ), "_speed" ) != 1 )
{
+#ifdef DEINTERLACE_ON_NOT_NORMAL_SPEED
mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "consumer_deinterlace", 1 );
+#endif
skipped = 0;
time_frame = 0;
time_process = 0;
}
// Get the image
- if ( !skip_next )
+ if ( !skip_next || this->real_time == -1 )
{
// Get the image, mark as rendered and time it
if ( !video_off )
time_process += time_difference( &ante );
// Determine if the next frame should be skipped
- if ( mlt_deque_count( this->queue ) <= 5 && ( ( time_wait + time_frame + time_process ) / count ) > 40000 )
- skip_next = 1;
+ if ( mlt_deque_count( this->queue ) <= 5 )
+ {
+ int frame_duration = mlt_properties_get_int( properties, "frame_duration" );
+ if ( ( ( time_wait + time_frame + time_process ) / count ) > frame_duration )
+ skip_next = 1;
+ }
// Unlock if there's a lock object
if ( lock_object ) mlt_service_unlock( lock_object );
pthread_cond_init( &this->cond, NULL );
// Create the read ahead
- pthread_create( &this->ahead_thread, NULL, consumer_read_ahead_thread, this );
+ if ( mlt_properties_get( MLT_CONSUMER_PROPERTIES( this ), "priority" ) )
+ {
+ struct sched_param priority;
+ priority.sched_priority = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( this ), "priority" );
+ pthread_attr_t thread_attributes;
+ pthread_attr_init( &thread_attributes );
+ pthread_attr_setschedpolicy( &thread_attributes, SCHED_OTHER );
+ pthread_attr_setschedparam( &thread_attributes, &priority );
+ pthread_attr_setinheritsched( &thread_attributes, PTHREAD_EXPLICIT_SCHED );
+ pthread_attr_setscope( &thread_attributes, PTHREAD_SCOPE_SYSTEM );
+ if ( pthread_create( &this->ahead_thread, &thread_attributes, consumer_read_ahead_thread, this ) < 0 )
+ pthread_create( &this->ahead_thread, NULL, consumer_read_ahead_thread, this );
+ pthread_attr_destroy( &thread_attributes );
+ }
+ else
+ {
+ pthread_create( &this->ahead_thread, NULL, consumer_read_ahead_thread, this );
+ }
}
static void consumer_read_ahead_stop( mlt_consumer this )