// Get the service assoicated to the consumer
mlt_service service = mlt_consumer_service( this );
+ // Get the consumer properties
+ mlt_properties properties = mlt_consumer_properties( this );
+
// Get the frame
- if ( mlt_service_producer( service ) == NULL )
+ if ( mlt_service_producer( service ) == NULL && mlt_properties_get_int( properties, "put_mode" ) )
{
pthread_mutex_lock( &this->put_mutex );
if ( this->put == NULL )
if ( frame != NULL || mlt_service_get_frame( service, &frame, 0 ) == 0 )
{
- // Get the consumer properties
- mlt_properties properties = mlt_consumer_properties( this );
-
// Get the frame properties
mlt_properties frame_properties = mlt_frame_properties( frame );
if ( mlt_properties_get( properties, "post" ) )
system( mlt_properties_get( properties, "post" ) );
+ if ( this->put != NULL )
+ {
+ mlt_frame_close( this->put );
+ this->put = NULL;
+ }
+
return 0;
}
mlt_properties properties = mlt_producer_properties( producer );
int silent = mlt_properties_get_int( mlt_consumer_properties( consumer ), "silent" );
- term_init( );
if ( mlt_properties_get_int( properties, "done" ) == 0 && !mlt_consumer_is_stopped( consumer ) )
{
if ( !silent )
{
+ term_init( );
+
fprintf( stderr, "+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+\n" );
fprintf( stderr, "|1=-10| |2= -5| |3= -2| |4= -1| |5= 0| |6= 1| |7= 2| |8= 5| |9= 10|\n" );
fprintf( stderr, "+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+\n" );
mlt_properties_set_int( this->properties, "rect_y", this->rect.y );
mlt_properties_set_int( this->properties, "rect_w", this->rect.w );
mlt_properties_set_int( this->properties, "rect_h", this->rect.h );
-
+
// Force an overlay recreation
if ( this->sdl_overlay != NULL )
SDL_FreeYUVOverlay( this->sdl_overlay );
// open SDL window with video overlay, if possible
sdl_lock_display();
this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
- SDL_SetClipRect( this->sdl_screen, &this->rect );
sdl_unlock_display();
-
+ if ( consumer_get_dimensions( &this->window_width, &this->window_height ) )
+ this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
+ SDL_Flip( this->sdl_screen );
+ mlt_properties_set_int( properties, "changed", 0 );
+
if ( this->sdl_screen != NULL )
{
SDL_SetClipRect( this->sdl_screen, &this->rect );
sdl_lock_display();
this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
SDL_SetClipRect( this->sdl_screen, &this->rect );
- SDL_Flip( this->sdl_screen );
sdl_unlock_display();
mlt_properties_set_int( properties, "changed", 0 );
}
{
if ( SDL_GetVideoSurface( ) != NULL )
consumer_get_dimensions( &this->window_width, &this->window_height );
+ mlt_properties_set_int( mlt_consumer_properties( consumer ), "changed", 1 );
}
SDL_InitSubSystem( SDL_INIT_AUDIO );
struct consumer_sdl_s
{
struct mlt_consumer_s parent;
+ mlt_consumer active;
+ int ignore_change;
mlt_consumer play;
mlt_consumer still;
pthread_t thread;
static void consumer_close( mlt_consumer parent );
static void *consumer_thread( void * );
static void consumer_frame_show_cb( mlt_consumer sdl, mlt_consumer this, mlt_frame frame );
+static void consumer_sdl_event_cb( mlt_consumer sdl, mlt_consumer this, SDL_Event *event );
mlt_consumer consumer_sdl_preview_init( char *arg )
{
mlt_events_fire( mlt_consumer_properties( parent ), "consumer-frame-show", frame, NULL );
}
+static void consumer_sdl_event_cb( mlt_consumer sdl, mlt_consumer parent, SDL_Event *event )
+{
+ mlt_events_fire( mlt_consumer_properties( parent ), "consumer-sdl-event", event, NULL );
+}
+
static int consumer_start( mlt_consumer parent )
{
consumer_sdl this = parent->child;
mlt_properties_pass( play, mlt_consumer_properties( consumer ), "play." );
mlt_properties_pass( still, mlt_consumer_properties( consumer ), "still." );
+ mlt_properties_set_data( play, "app_lock", mlt_properties_get_data( properties, "app_lock", NULL ), 0, NULL, NULL );
+ mlt_properties_set_data( still, "app_lock", mlt_properties_get_data( properties, "app_lock", NULL ), 0, NULL, NULL );
+ mlt_properties_set_data( play, "app_unlock", mlt_properties_get_data( properties, "app_unlock", NULL ), 0, NULL, NULL );
+ mlt_properties_set_data( still, "app_unlock", mlt_properties_get_data( properties, "app_unlock", NULL ), 0, NULL, NULL );
+
+ mlt_properties_set_int( play, "put_mode", 1 );
+ mlt_properties_set_int( still, "put_mode", 1 );
+
// Loop until told not to
while( this->running )
{
// Get the speed of the frame
double speed = mlt_properties_get_double( mlt_frame_properties( frame ), "_speed" );
+ // Determine which speed to use
+ double use_speed = first ? speed : this->last_speed;
+
+ // Get changed requests to the preview
+ int changed = mlt_properties_get_int( properties, "changed" );
+ mlt_properties_set_int( properties, "changed", 0 );
+
// Make sure the recipient knows that this frame isn't really rendered
mlt_properties_set_int( mlt_frame_properties( frame ), "rendered", 0 );
this->running = 0;
mlt_frame_close( frame );
}
- else if ( this->last_speed != 1 )
+ else if ( this->ignore_change -- > 0 && this->active != NULL && !mlt_consumer_is_stopped( this->active ) )
+ {
+ mlt_consumer_put_frame( this->active, frame );
+ if ( this->active == this->still )
+ mlt_properties_set_int( still, "changed", changed );
+ }
+ else if ( use_speed != 1 )
{
if ( !mlt_consumer_is_stopped( this->play ) )
+ {
mlt_consumer_stop( this->play );
+ }
if ( mlt_consumer_is_stopped( this->still ) )
{
- this->last_speed = speed;
+ this->last_speed = use_speed;
+ this->active = this->still;
+ this->ignore_change = 5;
mlt_consumer_start( this->still );
}
+ mlt_properties_set_int( still, "changed", changed );
mlt_consumer_put_frame( this->still, frame );
}
else
{
if ( !mlt_consumer_is_stopped( this->still ) )
+ {
mlt_consumer_stop( this->still );
+ }
if ( mlt_consumer_is_stopped( this->play ) )
{
- this->last_speed = speed;
+ this->last_speed = use_speed;
+ this->active = this->play;
+ this->ignore_change = 25;
mlt_consumer_start( this->play );
}
mlt_consumer_put_frame( this->play, frame );
pthread_join( this->thread, NULL );
this->joined = 1;
-
- mlt_frame_close( parent->put );
- parent->put = NULL;
}
return 0;
uint8_t *image;
int changed = 0;
+ void ( *lock )( void ) = mlt_properties_get_data( properties, "app_lock", NULL );
+ void ( *unlock )( void ) = mlt_properties_get_data( properties, "app_unlock", NULL );
+
+ if ( lock != NULL ) lock( );
+
+ sdl_lock_display();
// Handle events
if ( this->sdl_screen != NULL )
changed = 1;
}
- if ( this->sdl_screen == NULL || changed )
+ if ( this->sdl_screen == NULL || changed || mlt_properties_get_int( properties, "changed" ) == 2 )
{
+ // open SDL window
+ this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 16, this->sdl_flags );
+ consumer_get_dimensions( &this->window_width, &this->window_height );
+ changed = 1;
+ mlt_properties_set_int( properties, "changed", 0 );
+
// Determine frame's display aspect ratio
float frame_aspect = mlt_frame_get_aspect_ratio( frame ) * this->width / this->height;
mlt_properties_set_int( this->properties, "rect_y", this->rect.y );
mlt_properties_set_int( this->properties, "rect_w", this->rect.w );
mlt_properties_set_int( this->properties, "rect_h", this->rect.h );
-
- // open SDL window
- sdl_lock_display();
- this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 16, this->sdl_flags );
- consumer_get_dimensions( &this->window_width, &this->window_height );
- sdl_unlock_display();
- changed = 1;
}
-
- if ( mlt_properties_get_int( properties, "changed" ) )
+ else
{
- sdl_lock_display();
- this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 16, this->sdl_flags );
- SDL_SetClipRect( this->sdl_screen, &this->rect );
- SDL_Flip( this->sdl_screen );
- consumer_get_dimensions( &this->window_width, &this->window_height );
- sdl_unlock_display();
+ changed = mlt_properties_get_int( properties, "changed" );
mlt_properties_set_int( properties, "changed", 0 );
- changed = 1;
}
-
+
if ( changed == 0 &&
this->last_position == mlt_frame_get_position( frame ) &&
this->last_producer == mlt_properties_get_data( mlt_frame_properties( frame ), "_producer", NULL ) )
+ {
+ sdl_unlock_display( );
+ if ( unlock != NULL )
+ unlock( );
return 0;
+ }
// Update last frame shown info
this->last_position = mlt_frame_get_position( frame );
if ( this->sdl_screen != NULL )
{
- sdl_lock_display();
-
// Calculate the scan length
int scanlength = this->sdl_screen->pitch / 2;
SDL_Rect rect = this->rect;
// Generate the affine transform scaling values
- float scale_width = ( float )width / ( float )rect.w;
- float scale_height = ( float )height / ( float )rect.h;
+ int scale_width = ( width << 16 ) / rect.w;
+ int scale_height = ( height << 16 ) / rect.h;
// Constants defined for clarity and optimisation
int stride = width * 3;
uint16_t *start = ( uint16_t * )this->sdl_screen->pixels + rect.y * scanlength + rect.x;
- int y;
+ int x, y, row_index;
+ uint16_t *p;
+ uint8_t *q, *row;
// Iterate through the screen using a very basic scaling algorithm
- for ( y = 0; y < rect.h; y ++ )
+ for ( y = 0; y < rect.h && this->last_position != -1; y ++ )
{
// Obtain the pointer to the current screen row
- uint16_t *p = start;
+ p = start;
// Calculate the row_index
- int row_index = ( int )( scale_height * y );
+ row_index = ( scale_height * y ) >> 16;
// Calculate the pointer for the y offset (positioned on B instead of R)
- uint8_t *row = image + stride * row_index;
-
- int x;
+ row = image + stride * row_index;
// Iterate through the screen width
for ( x = 0; x < rect.w; x ++ )
{
// Obtain the pixel pointer
- uint8_t *q = row + ( ( int )( scale_width * x ) * 3 );
+ q = row + ( ( ( scale_width * x ) >> 16 ) * 3 );
// Map the BGR colour from the frame to the SDL format
*p ++ = SDL_MapRGB( this->sdl_screen->format, *q, *( q + 1 ), *( q + 2 ) );
// Flip it into sight
SDL_Flip( this->sdl_screen );
-
- sdl_unlock_display();
}
+ sdl_unlock_display();
+
+ if ( unlock != NULL ) unlock( );
+
return 0;
}
}
else
{
- this->sdl_screen = SDL_GetVideoSurface( );
- mlt_properties_set_int( mlt_consumer_properties( consumer ), "changed", 1 );
+ mlt_properties_set_int( mlt_consumer_properties( consumer ), "changed", 2 );
}
// Loop until told not to
// Specify the SDL Version
SDL_VERSION( &wm.version );
- // Lock the display
- sdl_lock_display();
-
// Get the wm structure
if ( SDL_GetWMInfo( &wm ) == 1 )
{
}
}
- // Unlock the display
- sdl_lock_display();
-
return changed;
}