X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;ds=sidebyside;f=src%2Fmodules%2Fswfdec%2Fproducer_swfdec.c;h=83640fbf4ff8b812a352b4b3ddb1fa8937aeff34;hb=a615b9e1275a17404b5fe3a4f00c475c19f7ce5c;hp=97d175b2dd973a166f52028502f70628b85c0b7b;hpb=d834717dd593e1322dc44378017fd4bdc2b12a9a;p=mlt diff --git a/src/modules/swfdec/producer_swfdec.c b/src/modules/swfdec/producer_swfdec.c index 97d175b2..83640fbf 100644 --- a/src/modules/swfdec/producer_swfdec.c +++ b/src/modules/swfdec/producer_swfdec.c @@ -24,6 +24,7 @@ #include #include #include +#include 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" ); }