// See if video is turned off
int video_off = mlt_properties_get_int( properties, "video_off" );
+ int preview_off = mlt_properties_get_int( properties, "preview_off" );
+ int preview_format = mlt_properties_get_int( properties, "preview_format" );
// Get the audio settings
mlt_audio_format afmt = mlt_audio_pcm;
int skip_next = 0;
mlt_service lock_object = NULL;
+ if ( preview_off && preview_format != 0 )
+ this->format = preview_format;
+
// Get the first frame
frame = mlt_consumer_get_frame( this );
mlt_properties_set_int( properties, "image_count", mlt_properties_get_int( properties, "image_count" ) - 1 );
mlt_position position = mlt_frame_get_position( this );
error = get_image( this, buffer, format, width, height, writable );
+ mlt_properties_set_int( properties, "width", *width );
+ mlt_properties_set_int( properties, "height", *height );
+ mlt_properties_set_int( properties, "format", *format );
mlt_frame_set_position( this, position );
}
else if ( mlt_properties_get_data( properties, "image", NULL ) != NULL )
{
- *format = mlt_image_yuv422;
+ *format = mlt_properties_get_int( properties, "format" );
*buffer = mlt_properties_get_data( properties, "image", NULL );
*width = mlt_properties_get_int( properties, "width" );
*height = mlt_properties_get_int( properties, "height" );
mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL );
mlt_properties_set_int( properties, "width", *width );
mlt_properties_set_int( properties, "height", *height );
+ mlt_properties_set_int( properties, "format", *format );
mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( test_frame ) );
}
else
*height = *height == 0 ? 576 : *height;
size = *width * *height;
+ mlt_properties_set_int( properties, "format", *format );
mlt_properties_set_int( properties, "width", *width );
mlt_properties_set_int( properties, "height", *height );
mlt_properties_set_int( properties, "aspect_ratio", 0 );
memset( *buffer, 255, size );
break;
case mlt_image_rgb24a:
+ case mlt_image_opengl:
size *= 4;
size += *width * 4;
*buffer = mlt_pool_alloc( size );
u = u > 240 ? 240 : u;\
v = v > 240 ? 240 : v
+#define YUV2RGB( y, u, v, r, g, b ) \
+ r = ((1192 * ( y - 16 ) + 1634 * ( v - 128 ) ) >> 10 ); \
+ g = ((1192 * ( y - 16 ) - 832 * ( v - 128 ) - 400 * ( u - 128 ) ) >> 10 ); \
+ b = ((1192 * ( y - 16 ) + 2066 * ( u - 128 ) ) >> 10 ); \
+ r = r < 0 ? 0 : r > 255 ? 255 : r; \
+ g = g < 0 ? 0 : g > 255 ? 255 : g; \
+ b = b < 0 ? 0 : b > 255 ? 255 : b;
+
#endif
mlt_properties_set_data( properties, "image", *buffer, *width * *height * 2, NULL, NULL );
mlt_properties_set_int( properties, "width", *width );
mlt_properties_set_int( properties, "height", *height );
+ mlt_properties_set_int( properties, "format", *format );
mlt_properties_set_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( frame ) );
mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( frame_properties, "progressive" ) );
mlt_properties_set_int( properties, "distort", mlt_properties_get_int( frame_properties, "distort" ) );
mlt_image_rgb24,
mlt_image_rgb24a,
mlt_image_yuv422,
- mlt_image_yuv420p
+ mlt_image_yuv420p,
+ mlt_image_opengl
}
mlt_image_format;
case mlt_image_yuv420p:
value = PIX_FMT_YUV420P;
break;
+ case mlt_image_opengl:
case mlt_image_none:
fprintf( stderr, "Invalid format...\n" );
break;
error = mlt_frame_get_image( this, image, format, width, height, 0 );
- if ( error == 0 && *format != output_format && *image != NULL )
+ if ( error == 0 && *format != output_format && *image != NULL && output_format != mlt_image_opengl )
{
int in_fmt = convert_mlt_to_av_cs( *format );
int out_fmt = convert_mlt_to_av_cs( output_format );
*format = output_format;
mlt_properties_set_data( properties, "image", output, size, mlt_pool_release, NULL );
mlt_properties_set_int( properties, "format", output_format );
+
+ // Special case for alpha rgb - merge the alpha mask when it exists
+ if ( *format == mlt_image_rgb24a )
+ {
+ // Fetch the alpha
+ register uint8_t *alpha = mlt_frame_get_alpha_mask( this );
+
+ if ( alpha != NULL )
+ {
+ register uint8_t *bits = *image;
+ register int len = *width * *height;
+ register int n = ( len + 7 ) / 8;
+
+ // TODO: Proper check for big endian systems
+ #ifndef __DARWIN__
+ bits += 3;
+ #endif
+
+ // Merge the alpha mask into the RGB image using Duff's Device
+ switch( len % 8 )
+ {
+ case 0: do { *bits = *alpha++; bits += 4;
+ case 7: *bits = *alpha++; bits += 4;
+ case 6: *bits = *alpha++; bits += 4;
+ case 5: *bits = *alpha++; bits += 4;
+ case 4: *bits = *alpha++; bits += 4;
+ case 3: *bits = *alpha++; bits += 4;
+ case 2: *bits = *alpha++; bits += 4;
+ case 1: *bits = *alpha++; bits += 4;
+ }
+ while( --n );
+ }
+ }
+ }
+ }
+ else if ( error == 0 && *format != output_format && *image != NULL && output_format == mlt_image_opengl )
+ {
+ if ( *format == mlt_image_yuv422 )
+ {
+ int size = *width * *height * 4;
+ uint8_t *output = mlt_pool_alloc( size );
+ int h = *height;
+ int w = *width;
+ uint8_t *o = output + size;
+ int ostride = w * 4;
+ uint8_t *p = *image;
+ uint8_t *alpha = mlt_frame_get_alpha_mask( this ) + *width * *height;
+ int r, g, b;
+
+ while( h -- )
+ {
+ w = *width;
+ o -= ostride;
+ alpha -= *width;
+ while( w >= 2 )
+ {
+ YUV2RGB( *p, *( p + 1 ), *( p + 3 ), r, g, b );
+ *o ++ = r;
+ *o ++ = g;
+ *o ++ = b;
+ *o ++ = *alpha ++;
+ YUV2RGB( *( p + 2 ), *( p + 1 ), *( p + 3 ), r, g, b );
+ *o ++ = r;
+ *o ++ = g;
+ *o ++ = b;
+ *o ++ = *alpha ++;
+ w -= 2;
+ p += 4;
+ }
+ o -= ostride;
+ alpha -= *width;
+ }
+
+ mlt_properties_set_data( properties, "image", output, size, mlt_pool_release, NULL );
+ mlt_properties_set_int( properties, "format", output_format );
+ *image = output;
+ *format = output_format;
+ }
}
+
return error;
}
then
cat << EOF >> ../producers.dat
+color libmltcore$LIBSUF
colour libmltcore$LIBSUF
noise libmltcore$LIBSUF
ppm libmltcore$LIBSUF
void *mlt_create_producer( char *id, void *arg )
{
+ if ( !strcmp( id, "color" ) )
+ return producer_colour_init( arg );
if ( !strcmp( id, "colour" ) )
return producer_colour_init( arg );
if ( !strcmp( id, "noise" ) )
mlt_properties_set_data( b_props, "image", dst, size, mlt_pool_release, NULL );
mlt_properties_set_int( b_props, "width", *width );
mlt_properties_set_int( b_props, "height", *height );
+ mlt_properties_set_int( b_props, "format", *format );
}
}
uint8_t *image = mlt_properties_get_data( a_props, "image", NULL );
int width = mlt_properties_get_int( a_props, "width" );
int height = mlt_properties_get_int( a_props, "height" );
+ int format = mlt_properties_get_int( a_props, "format" );
// Pointers for copy operation
uint8_t *p;
mlt_properties_set_data( b_props, "image", dest, w * h * 2, mlt_pool_release, NULL );
mlt_properties_set_int( b_props, "width", w );
mlt_properties_set_int( b_props, "height", h );
+ mlt_properties_set_int( b_props, "format", format );
if ( y < 0 )
{
{
if ( width != this->width || height != this->height )
{
- pixbuf = mlt_properties_get_data( producer_props, "pixbuf", NULL );
+ pixbuf = mlt_properties_get_data( producer_props, "_pixbuf", NULL );
mlt_pool_release( this->image );
mlt_pool_release( this->alpha );
this->image = NULL;
if ( pixbuf != NULL )
{
// Register this pixbuf for destruction and reuse
- mlt_properties_set_data( producer_props, "pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref, NULL );
+ mlt_events_block( producer_props, NULL );
+ mlt_properties_set_data( producer_props, "_pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref, NULL );
g_object_ref( pixbuf );
mlt_properties_set_data( MLT_FRAME_PROPERTIES( frame ), "pixbuf", pixbuf, 0, ( mlt_destructor )g_object_unref, NULL );
- mlt_properties_set_int( producer_props, "real_width", gdk_pixbuf_get_width( pixbuf ) );
- mlt_properties_set_int( producer_props, "real_height", gdk_pixbuf_get_height( pixbuf ) );
+ mlt_properties_set_int( producer_props, "_real_width", gdk_pixbuf_get_width( pixbuf ) );
+ mlt_properties_set_int( producer_props, "_real_height", gdk_pixbuf_get_height( pixbuf ) );
+ mlt_events_unblock( producer_props, NULL );
// Store the width/height of the pixbuf temporarily
this->width = gdk_pixbuf_get_width( pixbuf );
// Set width/height of frame
mlt_properties_set_int( properties, "width", this->width );
mlt_properties_set_int( properties, "height", this->height );
- mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "real_width" ) );
- mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "real_height" ) );
+ mlt_properties_set_int( properties, "real_width", mlt_properties_get_int( producer_props, "_real_width" ) );
+ mlt_properties_set_int( properties, "real_height", mlt_properties_get_int( producer_props, "_real_height" ) );
// pass the image data without destructor
mlt_properties_set_data( properties, "image", this->image, this->width * ( this->height + 1 ) * 2, NULL, NULL );
#include "consumer_sdl.h"
#include <framework/mlt_frame.h>
#include <framework/mlt_deque.h>
+#include <framework/mlt_factory.h>
+#include <framework/mlt_filter.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
SDL_Rect rect;
uint8_t *buffer;
int bpp;
+ int filtered;
};
/** Forward references to static functions.
if ( !this->running )
{
+ int video_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "video_off" );
+ int preview_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "preview_off" );
+ int display_off = video_off | preview_off;
+ int audio_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "audio_off" );
+ int sdl_started = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" );
+
consumer_stop( parent );
this->running = 1;
this->bpp = mlt_properties_get_int( this->properties, "bpp" );
- if ( mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" ) == 0 )
+ // Attach a colour space converter
+ if ( preview_off && !this->filtered )
+ {
+ mlt_filter filter = mlt_factory_filter( "avcolour_space", NULL );
+ mlt_properties_set_int( MLT_FILTER_PROPERTIES( filter ), "forced", mlt_image_yuv422 );
+ mlt_service_attach( MLT_CONSUMER_SERVICE( parent ), filter );
+ mlt_filter_close( filter );
+ this->filtered = 1;
+ }
+
+ if ( sdl_started == 0 && display_off == 0 )
{
if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 )
{
SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
SDL_EnableUNICODE( 1 );
}
- else
+ else if ( display_off == 0 )
{
this->sdl_screen = SDL_GetVideoSurface( );
}
- if ( !mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "audio_off" ) )
+ if ( audio_off == 0 )
SDL_InitSubSystem( SDL_INIT_AUDIO );
- if ( this->sdl_screen == NULL )
+ if ( this->sdl_screen == NULL && display_off == 0 )
this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
pthread_create( &this->thread, NULL, consumer_thread, this );
uint8_t *image;
int changed = 0;
- if ( this->running && mlt_properties_get_int( properties, "video_off" ) == 0 )
+ int video_off = mlt_properties_get_int( properties, "video_off" );
+ int preview_off = mlt_properties_get_int( properties, "preview_off" );
+ mlt_image_format preview_format = mlt_properties_get_int( properties, "preview_format" );
+ int display_off = video_off | preview_off;
+
+ if ( this->running && display_off == 0 )
{
// Get the image, width and height
- mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 );
+ mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "format", vfmt );
+ mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
// Handle events
if ( this->sdl_screen != NULL )
sdl_unlock_display();
}
+ else if ( this->running )
+ {
+ vfmt = preview_format == mlt_image_none ? mlt_image_rgb24a : preview_format;
+ if ( !video_off )
+ mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 );
+ mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "format", vfmt );
+ mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
+ }
return 0;
}
mlt_properties_set_data( still, "transport_producer", mlt_properties_get_data( properties, "transport_producer", NULL ), 0, NULL, NULL );
mlt_properties_set_data( play, "transport_callback", mlt_properties_get_data( properties, "transport_callback", NULL ), 0, NULL, NULL );
mlt_properties_set_data( still, "transport_callback", mlt_properties_get_data( properties, "transport_callback", NULL ), 0, NULL, NULL );
- mlt_properties_set_int( play, "resize", mlt_properties_get_int( properties, "resize" ) );
- mlt_properties_set_int( still, "resize", mlt_properties_get_int( properties, "resize" ) );
- mlt_properties_set( play, "rescale", mlt_properties_get( properties, "rescale" ) );
- mlt_properties_set( still, "rescale", mlt_properties_get( properties, "rescale" ) );
- mlt_properties_set_int( play, "width", mlt_properties_get_int( properties, "width" ) );
- mlt_properties_set_int( still, "width", mlt_properties_get_int( properties, "width" ) );
- mlt_properties_set_int( play, "height", mlt_properties_get_int( properties, "height" ) );
- mlt_properties_set_int( still, "height", mlt_properties_get_int( properties, "height" ) );
- mlt_properties_set_double( play, "aspect_ratio", mlt_properties_get_double( properties, "aspect_ratio" ) );
- mlt_properties_set_double( still, "aspect_ratio", mlt_properties_get_double( properties, "aspect_ratio" ) );
- mlt_properties_set_double( play, "display_ratio", mlt_properties_get_double( properties, "display_ratio" ) );
- mlt_properties_set_double( still, "display_ratio", mlt_properties_get_double( properties, "display_ratio" ) );
mlt_properties_set_int( play, "progressive", progressive );
mlt_properties_set_int( still, "progressive", progressive );
- mlt_properties_set( play, "deinterlace_method", mlt_properties_get( properties, "deinterlace_method" ) );
- mlt_properties_set( still, "deinterlace_method", mlt_properties_get( properties, "deinterlace_method" ) );
+
+ mlt_properties_pass_list( play, properties, "resize,rescale,width,height,aspect_ratio,display_ratio" );
+ mlt_properties_pass_list( still, properties, "resize,rescale,width,height,aspect_ratio,display_ratio" );
+ mlt_properties_pass_list( play, properties, "deinterlace_method" );
+ mlt_properties_pass_list( still, properties, "deinterlace_method" );
+ mlt_properties_pass_list( play, properties, "preview_off,preview_format" );
+ mlt_properties_pass_list( still, properties, "preview_off,preview_format" );
mlt_properties_pass( play, properties, "play." );
mlt_properties_pass( still, properties, "still." );
mlt_frame frame = NULL;
int last_position = -1;
+ // Determine if the application is dealing with the preview
+ int preview_off = mlt_properties_get_int( properties, "preview_off" );
+
this->refresh_count = 0;
// Loop until told not to
}
// Copy the rectangle info from the active consumer
- if ( this->running )
+ if ( this->running && preview_off == 0 )
{
mlt_properties active = MLT_CONSUMER_PROPERTIES( this->active );
mlt_service_lock( MLT_CONSUMER_SERVICE( consumer ) );
this->width = mlt_properties_get_int( this->properties, "width" );
this->height = mlt_properties_get_int( this->properties, "height" );
}
+ else
+ {
+ mlt_properties_set_int( this->properties, "width", this->width );
+ mlt_properties_set_int( this->properties, "height", this->height );
+ }
// Default window size
this->window_width = ( double )this->height * display_ratio;
if ( !this->running )
{
+ int preview_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "preview_off" );
+ int sdl_started = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" );
+
// Attach a colour space converter
if ( !this->filtered )
{
this->joined = 0;
// Allow the user to force resizing to window size
- if ( mlt_properties_get_int( this->properties, "resize" ) )
- {
- mlt_properties_set_int( this->properties, "width", this->width );
- mlt_properties_set_int( this->properties, "height", this->height );
- }
+ this->width = mlt_properties_get_int( this->properties, "width" );
+ this->height = mlt_properties_get_int( this->properties, "height" );
- if ( mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" ) == 0 )
+ if ( sdl_started == 0 && preview_off == 0 )
{
if ( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 )
{
SDL_EnableKeyRepeat( SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL );
SDL_EnableUNICODE( 1 );
}
- else
+ else if ( preview_off == 0 )
{
if ( SDL_GetVideoSurface( ) != NULL )
{
}
}
- if ( this->sdl_screen == NULL )
+ if ( this->sdl_screen == NULL && preview_off == 0 )
this->sdl_screen = SDL_SetVideoMode( this->window_width, this->window_height, 0, this->sdl_flags );
pthread_create( &this->thread, NULL, consumer_thread, this );
if ( this->joined == 0 )
{
+ int preview_off = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "preview_off" );
+ int sdl_started = mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" );
+
// Kill the thread and clean up
this->running = 0;
pthread_join( this->thread, NULL );
this->joined = 1;
- if ( mlt_properties_get_int( MLT_CONSUMER_PROPERTIES( parent ), "sdl_started" ) == 0 )
+ if ( sdl_started == 0 && preview_off == 0 )
SDL_Quit( );
this->sdl_screen = NULL;
this->last_producer == mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "_producer", NULL ) )
{
sdl_unlock_display( );
- if ( unlock != NULL )
- unlock( );
+ if ( unlock != NULL ) unlock( );
return 0;
}
this->last_producer = mlt_properties_get_data( MLT_FRAME_PROPERTIES( frame ), "_producer", NULL );
// Get the image, width and height
- mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 );
+ mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
if ( image != NULL )
{
// Get the consumer
mlt_consumer consumer = &this->parent;
+ mlt_properties properties = MLT_CONSUMER_PROPERTIES( consumer );
// internal intialization
mlt_frame frame = NULL;
+ mlt_image_format vfmt = mlt_image_rgb24a;
+ int height = this->height;
+ int width = this->width;
+ uint8_t *image = NULL;
+
+ // Allow the hosting app to provide the preview
+ int preview_off = mlt_properties_get_int( properties, "preview_off" );
+ mlt_image_format preview_format = mlt_properties_get_int( properties, "preview_format" );
+
+ // Check if a specific colour space has been requested
+ if ( preview_off && preview_format != mlt_image_none )
+ vfmt = preview_format;
// Loop until told not to
while( this->running )
// Ensure that we have a frame
if ( this->running && frame != NULL )
{
- consumer_play_video( this, frame );
+ if ( preview_off == 0 )
+ {
+ consumer_play_video( this, frame );
+ }
+ else
+ {
+ mlt_frame_get_image( frame, &image, &vfmt, &width, &height, 0 );
+ mlt_properties_set_int( MLT_FRAME_PROPERTIES( frame ), "format", vfmt );
+ mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
+ }
mlt_frame_close( frame );
}
else