]> git.sesse.net Git - mlt/blobdiff - src/modules/swfdec/producer_swfdec.c
Refactor movit.convert, movit.mix, and movit.overlay.
[mlt] / src / modules / swfdec / producer_swfdec.c
index 97d175b2dd973a166f52028502f70628b85c0b7b..83640fbf4ff8b812a352b4b3ddb1fa8937aeff34 100644 (file)
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <math.h>
+#include <limits.h>
 
 typedef struct
 {
@@ -39,8 +40,12 @@ typedef struct
 
 void swfdec_open( producer_swfdec swfdec, mlt_profile profile )
 {
+       mlt_properties properties = MLT_PRODUCER_PROPERTIES( &swfdec->parent );
+
        // Setup the swfdec player
        swfdec->player = swfdec_player_new( NULL );
+       if ( mlt_properties_get( properties, "variables") )
+               swfdec_player_set_variables( swfdec->player, mlt_properties_get( properties, "variables" ) );
        swfdec_player_set_url( swfdec->player, swfdec->url );
        swfdec_player_set_maximum_runtime( swfdec->player, 10000 );
 
@@ -88,10 +93,31 @@ void swfdec_close( producer_swfdec swfdec )
        swfdec->surface = NULL;
 }
 
+// Cairo uses 32 bit native endian ARGB
+static void bgra_to_rgba( uint8_t *src, uint8_t* dst, int width, int height )
+{
+       int n = width * height + 1;
+
+       while ( --n )
+       {
+               *dst++ = src[2];
+               *dst++ = src[1];
+               *dst++ = src[0];
+               *dst++ = src[3];
+               src += 4;
+       }       
+}
+
 static int get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable )
 {
        producer_swfdec swfdec = mlt_frame_pop_service( frame );
-       mlt_properties properties = MLT_FRAME_PROPERTIES( frame );
+       mlt_service service = MLT_PRODUCER_SERVICE( &swfdec->parent );
+       mlt_profile profile = mlt_service_profile( service );
+
+       mlt_service_lock( service );
+       
+       if ( !swfdec->player )
+               swfdec_open( swfdec, profile );
 
        // Set width and height
        *width = swfdec->width;
@@ -99,11 +125,10 @@ static int get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *forma
        *format = mlt_image_rgb24a;
 
        *buffer = mlt_pool_alloc( *width * ( *height + 1 ) * 4 );
-       mlt_properties_set_data( properties, "image", *buffer, *width * ( *height + 1 ) * 4, (mlt_destructor) mlt_pool_release, NULL );
+       mlt_frame_set_image( frame, *buffer, *width * ( *height + 1 ) * 4, mlt_pool_release );
 
        // Seek
-       mlt_position pos = mlt_properties_get_position( properties, "swfdec.position" );
-       mlt_profile profile = mlt_service_profile( MLT_PRODUCER_SERVICE( &swfdec->parent ) );
+       mlt_position pos = mlt_frame_original_position( frame );
        if ( pos > swfdec->last_position )
        {
                gulong msec = 1000UL * ( pos - swfdec->last_position ) * profile->frame_rate_den / profile->frame_rate_num;
@@ -113,7 +138,7 @@ static int get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *forma
        else if ( pos < swfdec->last_position )
        {
                swfdec_close( swfdec );
-               swfdec_open( swfdec, mlt_service_profile( MLT_PRODUCER_SERVICE( &swfdec->parent ) ) );
+               swfdec_open( swfdec, mlt_service_profile( service ) );
                gulong msec = 1000UL * pos * profile->frame_rate_den / profile->frame_rate_num;
                while ( msec > 0 )
                        msec -= swfdec_player_advance( swfdec->player, msec );
@@ -130,23 +155,11 @@ static int get_image( mlt_frame frame, uint8_t **buffer, mlt_image_format *forma
 
        // Get image from surface
        uint8_t *image = cairo_image_surface_get_data( swfdec->surface );
-       uint8_t *d = *buffer;
-       int stride = cairo_format_stride_for_width( CAIRO_FORMAT_ARGB32, swfdec->width );
-       int y;
-       for ( y = 0; y < swfdec->height; y++ )
-       {
-               int x = swfdec->width + 1;
-               uint32_t *s = ( uint32_t* )( image + stride * y );
-               while ( --x )
-               {
-                       // Cairo uses 32 bit native endian
-                       *d++ = *s >> 16;  // R
-                       *d++ = *s >> 8;   // G
-                       *d++ = *s & 0xFF; // B
-                       *d++ = *s >> 24;  // A
-                       s++;
-               }
-       }
+       
+       mlt_service_unlock( service );
+       
+       // Convert to RGBA
+       bgra_to_rgba( image, *buffer, swfdec->width, swfdec->height );
 
        return 0;
 }
@@ -166,11 +179,8 @@ static int get_frame( mlt_producer producer, mlt_frame_ptr frame, int index )
        mlt_properties_set_int( properties, "test_image", 0 );
        mlt_properties_set_int( properties, "width", swfdec->width );
        mlt_properties_set_int( properties, "height", swfdec->height );
-       mlt_properties_set_int( properties, "real_width", swfdec->width );
-       mlt_properties_set_int( properties, "real_height", swfdec->height );
        mlt_properties_set_int( properties, "progressive", 1 );
        mlt_properties_set_double( properties, "aspect_ratio", 1.0 );
-       mlt_properties_set_position( properties, "swfdec.position", mlt_producer_frame( producer ) );
 
        // Push the get_image method on to the stack
        mlt_frame_push_service( *frame, swfdec );
@@ -215,17 +225,32 @@ mlt_producer producer_swfdec_init( mlt_profile profile, mlt_service_type type, c
                swfdec->url = swfdec_url_new_from_input( filename );
                if ( swfdec->url )
                {
-                       swfdec_open( swfdec, profile );
-
                        // Set the return value
                        producer = &swfdec->parent;
 
                        // Set the resource property (required for all producers)
-                       mlt_properties_set( MLT_PRODUCER_PROPERTIES( producer ), "resource", filename );
+                       mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
+                       mlt_properties_set( properties, "resource", filename );
 
                        // Set the callbacks
                        producer->close = (mlt_destructor) producer_close;
                        producer->get_frame = get_frame;
+
+                       // Set the meta media attributes
+                       swfdec->width = profile->width;
+                       swfdec->height = profile->height;
+                       mlt_properties_set_int( properties, "meta.media.nb_streams", 1 );
+                       mlt_properties_set( properties, "meta.media.0.stream.type", "video" );
+                       mlt_properties_set( properties, "meta.media.0.codec.name", "swf" );
+                       mlt_properties_set( properties, "meta.media.0.codec.long_name", "Adobe Flash" );
+                       mlt_properties_set( properties, "meta.media.0.codec.pix_fmt", "bgra" );
+                       mlt_properties_set_int( properties, "meta.media.width", profile->width );
+                       mlt_properties_set_int( properties, "meta.media.height", profile->height );
+                       mlt_properties_set_double( properties, "meta.media.sample_aspect_num", 1.0 );
+                       mlt_properties_set_double( properties, "meta.media.sample_aspect_den", 1.0 );
+                       mlt_properties_set_int( properties, "meta.media.frame_rate_num", profile->frame_rate_num );
+                       mlt_properties_set_int( properties, "meta.media.frame_rate_den", profile->frame_rate_den );
+                       mlt_properties_set_int( properties, "meta.media.progressive", 1 );
                }
                else
                {
@@ -242,8 +267,16 @@ mlt_producer producer_swfdec_init( mlt_profile profile, mlt_service_type type, c
        return producer;
 }
 
+static mlt_properties metadata( mlt_service_type type, const char *id, void *data )
+{
+       char file[ PATH_MAX ];
+       snprintf( file, PATH_MAX, "%s/swfdec/%s", mlt_environment( "MLT_DATA" ), (char*) data );
+       return mlt_properties_parse_yaml( file );
+}
+
 MLT_REPOSITORY
 {
        swfdec_init();
        MLT_REGISTER( producer_type, "swfdec", producer_swfdec_init );
+       MLT_REGISTER_METADATA( producer_type, "swfdec", metadata, "producer_swfdec.yml" );
 }