From: lilo_booter Date: Wed, 13 Oct 2004 07:14:21 +0000 (+0000) Subject: Some fixes for alpha masks X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=4a39b72c5ac8fd2dd6db81a95eab08adde0491b9;p=mlt Some fixes for alpha masks git-svn-id: https://mlt.svn.sourceforge.net/svnroot/mlt/trunk/mlt@473 d19143bc-622f-0410-bfdd-b5b2a6649095 --- diff --git a/docs/services.txt b/docs/services.txt index 00b3e083..a92de216 100644 --- a/docs/services.txt +++ b/docs/services.txt @@ -1417,6 +1417,7 @@ Consumers ratio to square pixels. int progressive - indicates whether to use progressive or field- based rendering, default 0 (off). + int audio_buffer - size of the sdl audio buffer (default: 1024) Read Only Properties diff --git a/src/framework/mlt_consumer.c b/src/framework/mlt_consumer.c index 0f2a97f9..4422b111 100644 --- a/src/framework/mlt_consumer.c +++ b/src/framework/mlt_consumer.c @@ -220,8 +220,8 @@ mlt_frame mlt_consumer_get_frame( mlt_consumer this ) // Aspect ratio and other jiggery pokery mlt_properties_set_double( frame_properties, "consumer_aspect_ratio", mlt_properties_get_double( properties, "aspect_ratio" ) ); - mlt_properties_set_int( frame_properties, "consumer_progressive", mlt_properties_get_int( properties, "progressive" ) ); - mlt_properties_set_int( frame_properties, "consumer_deinterlace", mlt_properties_get_int( properties, "deinterlace" ) ); + if ( mlt_properties_get_int( properties, "progressive" ) || mlt_properties_get_int( properties, "deinterlace" ) ) + mlt_properties_set_int( properties, "consumer_deinterlace", 1 ); } // Return the frame diff --git a/src/framework/mlt_frame.c b/src/framework/mlt_frame.c index be21562d..9198807d 100644 --- a/src/framework/mlt_frame.c +++ b/src/framework/mlt_frame.c @@ -303,9 +303,9 @@ int mlt_frame_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *for uint8_t *mlt_frame_get_alpha_mask( mlt_frame this ) { - if ( this->get_alpha_mask != NULL ) + if ( this != NULL && this->get_alpha_mask != NULL ) return this->get_alpha_mask( this ); - return NULL; + return this == NULL ? NULL : mlt_properties_get_data( &this->parent, "alpha", NULL ); } int mlt_frame_get_audio( mlt_frame this, int16_t **buffer, mlt_audio_format *format, int *frequency, int *channels, int *samples ) @@ -531,6 +531,86 @@ int mlt_convert_yuv420p_to_yuv422( uint8_t *yuv420p, int width, int height, int return ret; } +uint8_t *mlt_resize_alpha( uint8_t *input, int owidth, int oheight, int iwidth, int iheight ) +{ + uint8_t *output = NULL; + + if ( input != NULL && ( iwidth != owidth || iheight != oheight ) ) + { + iwidth = iwidth - ( iwidth % 2 ); + owidth = owidth - ( owidth % 2 ); + + output = mlt_pool_alloc( owidth * oheight ); + + // Coordinates (0,0 is middle of output) + int y; + + // Calculate ranges + int out_x_range = owidth / 2; + int out_y_range = oheight / 2; + int in_x_range = iwidth / 2 < out_x_range ? iwidth / 2 : out_x_range; + int in_y_range = iheight / 2 < out_y_range ? iheight / 2 : out_y_range; + + // Output pointers + uint8_t *out_line = output; + uint8_t *out_ptr = out_line; + + // Calculate a middle and possibly invalid pointer in the input + uint8_t *in_middle = input + iwidth * ( iheight / 2 ) + ( iwidth / 2 ); + int in_line = - in_y_range * iwidth - in_x_range; + + int elements; + + // Fill whole section with black + y = out_y_range - ( iheight / 2 ); + int blank_elements = owidth * y; + elements = blank_elements; + while ( elements -- ) + *out_line ++ = 0; + + int active_width = iwidth; + int inactive_width = out_x_range - in_x_range; + uint8_t *p = NULL; + uint8_t *end = NULL; + + // Loop for the entirety of our output height. + while ( iheight -- ) + { + // Start at the beginning of the line + out_ptr = out_line; + + // Fill the outer part with black + elements = inactive_width; + while ( elements -- ) + *out_ptr ++ = 0; + + // We're in the input range for this row. + p = in_middle + in_line; + end = out_ptr + active_width; + while ( out_ptr != end ) + *out_ptr ++ = *p ++; + + // Fill the outer part with black + elements = inactive_width; + while ( elements -- ) + *out_ptr ++ = 0; + + // Move to next input line + in_line += iwidth; + + // Move to next output line + out_line += owidth; + } + + // Fill whole section with black + elements = blank_elements; + while ( elements -- ) + *out_line ++ = 0; + } + + return output; +} + void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input, int iwidth, int iheight ) { // Calculate strides @@ -539,8 +619,8 @@ void mlt_resize_yuv422( uint8_t *output, int owidth, int oheight, uint8_t *input iwidth = iwidth - ( iwidth % 4 ); owidth = owidth - ( owidth % 4 ); - iheight = iheight - ( iheight % 2 ); - oheight = oheight - ( oheight % 2 ); + //iheight = iheight - ( iheight % 2 ); + //oheight = oheight - ( oheight % 2 ); // Optimisation point if ( iwidth == owidth && iheight == oheight ) @@ -638,6 +718,8 @@ uint8_t *mlt_frame_resize_yuv422( mlt_frame this, int owidth, int oheight ) // Get the input image, width and height uint8_t *input = mlt_properties_get_data( properties, "image", NULL ); + uint8_t *alpha = mlt_frame_get_alpha_mask( this ); + int iwidth = mlt_properties_get_int( properties, "width" ); int iheight = mlt_properties_get_int( properties, "height" ); @@ -655,6 +737,14 @@ uint8_t *mlt_frame_resize_yuv422( mlt_frame this, int owidth, int oheight ) mlt_properties_set_int( properties, "width", owidth ); mlt_properties_set_int( properties, "height", oheight ); + // We should resize the alpha too + alpha = mlt_resize_alpha( alpha, owidth, oheight, iwidth, iheight ); + if ( alpha != NULL ) + { + mlt_properties_set_data( properties, "alpha", alpha, owidth * ( oheight + 1 ), ( mlt_destructor )mlt_pool_release, NULL ); + this->get_alpha_mask = NULL; + } + // Return the output return output; } diff --git a/src/framework/mlt_playlist.c b/src/framework/mlt_playlist.c index 0787bfb6..6ebf37af 100644 --- a/src/framework/mlt_playlist.c +++ b/src/framework/mlt_playlist.c @@ -1078,7 +1078,7 @@ static int producer_get_frame( mlt_producer producer, mlt_frame_ptr frame, int i // Set the consumer progressive property if ( progressive ) { - mlt_properties_set_int( properties, "consumer_progressive", progressive ); + mlt_properties_set_int( properties, "consumer_deinterlace", progressive ); mlt_properties_set_int( properties, "test_audio", 1 ); } diff --git a/src/framework/mlt_properties.c b/src/framework/mlt_properties.c index 1d137146..ab2c206f 100644 --- a/src/framework/mlt_properties.c +++ b/src/framework/mlt_properties.c @@ -648,6 +648,8 @@ void mlt_properties_debug( mlt_properties this, char *title, FILE *output ) for ( i = 0; i < list->count; i ++ ) if ( mlt_properties_get( this, list->name[ i ] ) != NULL ) fprintf( output, ", %s=%s", list->name[ i ], mlt_properties_get( this, list->name[ i ] ) ); + else + fprintf( output, ", %s=%p", list->name[ i ], mlt_properties_get_data( this, list->name[ i ], NULL ) ); fprintf( output, " ]" ); } fprintf( stderr, "\n" ); diff --git a/src/framework/mlt_tractor.c b/src/framework/mlt_tractor.c index 92a10dc9..2b7616c4 100644 --- a/src/framework/mlt_tractor.c +++ b/src/framework/mlt_tractor.c @@ -201,11 +201,6 @@ mlt_producer mlt_tractor_get_track( mlt_tractor this, int index ) return mlt_multitrack_track( mlt_tractor_multitrack( this ), index ); } -static uint8_t *mlt_tractor_alpha_mask( mlt_frame frame ) -{ - return mlt_properties_get_data( mlt_frame_properties( frame ), "alpha", NULL ); -} - static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_format *format, int *width, int *height, int writable ) { uint8_t *data = NULL; @@ -215,18 +210,21 @@ static int producer_get_image( mlt_frame this, uint8_t **buffer, mlt_image_forma mlt_properties_set_int( frame_properties, "width", mlt_properties_get_int( properties, "width" ) ); mlt_properties_set_int( frame_properties, "height", mlt_properties_get_int( properties, "height" ) ); mlt_properties_set( frame_properties, "rescale.interp", mlt_properties_get( properties, "rescale.interp" ) ); + if ( mlt_properties_get( properties, "distort" ) ) + mlt_properties_set( frame_properties, "distort", mlt_properties_get( properties, "distort" ) ); mlt_properties_set_double( frame_properties, "aspect_ratio", mlt_properties_get_double( properties, "aspect_ratio" ) ); mlt_properties_set_double( frame_properties, "consumer_aspect_ratio", mlt_properties_get_double( properties, "consumer_aspect_ratio" ) ); - mlt_properties_set_int( frame_properties, "consumer_progressive", mlt_properties_get_double( properties, "consumer_progressive" ) ); mlt_properties_set_int( frame_properties, "consumer_deinterlace", mlt_properties_get_double( properties, "consumer_deinterlace" ) ); mlt_frame_get_image( frame, buffer, format, width, height, writable ); 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_double( properties, "aspect_ratio", mlt_frame_get_aspect_ratio( frame ) ); + mlt_properties_set_int( properties, "progressive", mlt_properties_get_int( frame_properties, "progressive" ) ); + if ( mlt_properties_get( frame_properties, "distort" ) ) + mlt_properties_set( properties, "distort", mlt_properties_get( frame_properties, "distort" ) ); data = mlt_frame_get_alpha_mask( frame ); mlt_properties_set_data( properties, "alpha", data, 0, NULL, NULL ); - this->get_alpha_mask = mlt_tractor_alpha_mask; return 0; } @@ -340,6 +338,9 @@ static int producer_get_frame( mlt_producer parent, mlt_frame_ptr frame, int tra mlt_properties_set_data( frame_properties, "data_queue", data_queue, 0, NULL, NULL ); mlt_properties_set_int( frame_properties, "width", mlt_properties_get_int( video_properties, "width" ) ); mlt_properties_set_int( frame_properties, "height", mlt_properties_get_int( video_properties, "height" ) ); + mlt_properties_set_int( frame_properties, "real_width", mlt_properties_get_int( video_properties, "real_width" ) ); + mlt_properties_set_int( frame_properties, "real_height", mlt_properties_get_int( video_properties, "real_height" ) ); + mlt_properties_set_int( frame_properties, "progressive", mlt_properties_get_int( video_properties, "progressive" ) ); mlt_properties_set_double( frame_properties, "aspect_ratio", mlt_properties_get_double( video_properties, "aspect_ratio" ) ); } diff --git a/src/inigo/inigo.c b/src/inigo/inigo.c index e39b21d4..b5a5f27c 100644 --- a/src/inigo/inigo.c +++ b/src/inigo/inigo.c @@ -128,7 +128,7 @@ static void transport_action( mlt_producer producer, char *value ) static mlt_consumer create_consumer( char *id, mlt_producer producer ) { - char *arg = strchr( id, ':' ); + char *arg = id != NULL ? strchr( id, ':' ) : NULL; if ( arg != NULL ) *arg ++ = '\0'; mlt_consumer consumer = mlt_factory_consumer( id, arg ); @@ -246,7 +246,7 @@ int main( int argc, char **argv ) // If we have no consumer, default to sdl if ( store == NULL && consumer == NULL ) - consumer = create_consumer( "sdl", inigo ); + consumer = create_consumer( NULL, inigo ); if ( consumer != NULL && store == NULL ) { diff --git a/src/miracle/miracle_connection.c b/src/miracle/miracle_connection.c index 6bf496cf..51b1a0bb 100644 --- a/src/miracle/miracle_connection.c +++ b/src/miracle/miracle_connection.c @@ -201,6 +201,7 @@ void *parser_thread( void *arg ) { struct hostent *he; connection_t *connection = arg; + mlt_properties owner = connection->owner; char address[ 512 ]; char command[ 1024 ]; int fd = connection->fd; @@ -223,6 +224,8 @@ void *parser_thread( void *arg ) while( !error && connection_read( fd, command, 1024 ) ) { + response = NULL; + if ( !strncmp( command, "PUSH ", 5 ) ) { char temp[ 20 ]; @@ -245,7 +248,9 @@ void *parser_thread( void *arg ) buffer[ bytes ] = '\0'; if ( bytes > 0 && total == bytes ) service = ( mlt_service )mlt_factory_producer( "westley-xml", buffer ); - response = valerie_parser_push( parser, command, service ); + mlt_events_fire( owner, "push-received", &response, command, service, NULL ); + if ( response == NULL ) + response = valerie_parser_push( parser, command, service ); error = connection_send( fd, response ); valerie_response_close( response ); mlt_service_close( service ); @@ -253,7 +258,9 @@ void *parser_thread( void *arg ) } else if ( strncmp( command, "STATUS", 6 ) ) { - response = valerie_parser_execute( parser, command ); + mlt_events_fire( owner, "command-received", &response, command, NULL ); + if ( response == NULL ) + response = valerie_parser_execute( parser, command ); miracle_log( LOG_INFO, "%s \"%s\" %d", address, command, valerie_response_get_error_code( response ) ); error = connection_send( fd, response ); valerie_response_close( response ); diff --git a/src/miracle/miracle_connection.h b/src/miracle/miracle_connection.h index ce19115f..8734c6ca 100644 --- a/src/miracle/miracle_connection.h +++ b/src/miracle/miracle_connection.h @@ -38,6 +38,7 @@ extern "C" typedef struct { + mlt_properties owner; int fd; struct sockaddr_in sin; valerie_parser parser; diff --git a/src/miracle/miracle_server.c b/src/miracle/miracle_server.c index c5a00eea..6d733ded 100644 --- a/src/miracle/miracle_server.c +++ b/src/miracle/miracle_server.c @@ -46,6 +46,18 @@ #define VERSION "0.0.1" +static void miracle_command_received( mlt_listener listener, mlt_properties owner, miracle_server this, void **args ) +{ + if ( listener != NULL ) + listener( owner, this, ( valerie_response ** )args[ 0 ], ( char * )args[ 1 ] ); +} + +static void miracle_push_received( mlt_listener listener, mlt_properties owner, miracle_server this, void **args ) +{ + if ( listener != NULL ) + listener( owner, this, ( valerie_response ** )args[ 0 ], ( char * )args[ 1 ], ( mlt_service )args[ 2 ] ); +} + /** Initialise a server structure. */ @@ -53,11 +65,15 @@ miracle_server miracle_server_init( char *id ) { miracle_server server = malloc( sizeof( miracle_server_t ) ); if ( server != NULL ) - { memset( server, 0, sizeof( miracle_server_t ) ); + if ( server != NULL && mlt_properties_init( &server->parent, server ) == 0 ) + { server->id = id; server->port = DEFAULT_TCP_PORT; server->socket = -1; + mlt_events_init( &server->parent ); + mlt_events_register( &server->parent, "command-received", ( mlt_transmitter )miracle_command_received ); + mlt_events_register( &server->parent, "push-received", ( mlt_transmitter )miracle_push_received ); } return server; } @@ -141,6 +157,7 @@ static void *miracle_server_run( void *arg ) our server thread. The thread should free this when it terminates. */ tmp = (connection_t*) malloc( sizeof(connection_t) ); + tmp->owner = &server->parent; tmp->parser = server->parser; tmp->fd = accept( server->socket, (struct sockaddr*) &(tmp->sin), &socksize ); @@ -287,8 +304,9 @@ void miracle_server_shutdown( miracle_server server ) void miracle_server_close( miracle_server server ) { - if ( server != NULL ) + if ( server != NULL && mlt_properties_dec_ref( &server->parent ) <= 0 ) { + mlt_properties_close( &server->parent ); miracle_server_shutdown( server ); free( server ); } diff --git a/src/miracle/miracle_server.h b/src/miracle/miracle_server.h index 5ed27986..ce8ef25b 100644 --- a/src/miracle/miracle_server.h +++ b/src/miracle/miracle_server.h @@ -42,6 +42,7 @@ extern "C" typedef struct { + struct mlt_properties_s parent; char *id; int port; int socket; diff --git a/src/modules/core/filter_rescale.c b/src/modules/core/filter_rescale.c index 1c02a4ad..e606a174 100644 --- a/src/modules/core/filter_rescale.c +++ b/src/modules/core/filter_rescale.c @@ -108,6 +108,64 @@ static int filter_scale( mlt_frame this, uint8_t **image, mlt_image_format iform return 0; } +static void scale_alpha( mlt_frame this, int iwidth, int iheight, int owidth, int oheight ) +{ + uint8_t *input = mlt_frame_get_alpha_mask( this ); + + if ( input != NULL ) + { + uint8_t *output = mlt_pool_alloc( owidth * oheight ); + + // Derived coordinates + int dy, dx; + + // Calculate ranges + int out_x_range = owidth / 2; + int out_y_range = oheight / 2; + int in_x_range = iwidth / 2; + int in_y_range = iheight / 2; + + // Output pointers + register uint8_t *out_line = output; + register uint8_t *out_ptr; + + // Calculate a middle pointer + uint8_t *in_middle = input + iwidth * in_y_range + in_x_range; + uint8_t *in_line; + + // Generate the affine transform scaling values + register int scale_width = ( iwidth << 16 ) / owidth; + register int scale_height = ( iheight << 16 ) / oheight; + register int base = 0; + + int outer = out_x_range * scale_width; + int bottom = out_y_range * scale_height; + + // Loop for the entirety of our output height. + for ( dy = - bottom; dy < bottom; dy += scale_height ) + { + // Start at the beginning of the line + out_ptr = out_line; + + // Pointer to the middle of the input line + in_line = in_middle + ( dy >> 16 ) * iwidth; + + // Loop for the entirety of our output row. + for ( dx = - outer; dx < outer; dx += scale_width ) + { + base = dx >> 15; + *out_ptr ++ = *( in_line + base ); + } + + // Move to next output line + out_line += owidth; + } + + this->get_alpha_mask = NULL; + mlt_properties_set_data( mlt_frame_properties( this ), "alpha", output, 0, mlt_pool_release, NULL ); + } +} + /** Do it :-). */ @@ -133,7 +191,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * } // There can be problems with small images - avoid them (by hacking - gah) - if ( *width >= 2 && *height >= 6 ) + if ( *width >= 6 && *height >= 6 ) { int iwidth = *width; int iheight = *height; @@ -171,7 +229,7 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * // Get the image as requested mlt_frame_get_image( this, image, format, &iwidth, &iheight, writable ); - + // Get rescale interpretation again, in case the producer wishes to override scaling interps = mlt_properties_get( properties, "rescale.interp" ); @@ -189,6 +247,9 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * scaler_method( this, image, *format, mlt_image_yuv422, iwidth, iheight, owidth, oheight ); *width = owidth; *height = oheight; + + // Scale the alpha + scale_alpha( this, iwidth, iheight, owidth, oheight ); } else if ( *format == mlt_image_rgb24 && wanted_format == mlt_image_rgb24 ) { @@ -198,6 +259,9 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * // Return the output *width = owidth; *height = oheight; + + // Scale the alpha + scale_alpha( this, iwidth, iheight, owidth, oheight ); } else if ( *format == mlt_image_rgb24 || *format == mlt_image_rgb24a ) { @@ -208,6 +272,9 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * *format = mlt_image_yuv422; *width = owidth; *height = oheight; + + // Scale the alpha + scale_alpha( this, iwidth, iheight, owidth, oheight ); } else { @@ -239,15 +306,6 @@ static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format * return 0; } -static uint8_t *producer_get_alpha_mask( mlt_frame this ) -{ - // Obtain properties of frame - mlt_properties properties = mlt_frame_properties( this ); - - // Return the alpha mask - return mlt_properties_get_data( properties, "alpha", NULL ); -} - /** Filter processing. */ @@ -259,9 +317,6 @@ static mlt_frame filter_process( mlt_filter this, mlt_frame frame ) // Push the get image method mlt_frame_push_service( frame, filter_get_image ); - // Set alpha call back - frame->get_alpha_mask = producer_get_alpha_mask; - return frame; } diff --git a/src/modules/core/filter_watermark.c b/src/modules/core/filter_watermark.c index e91aeadd..9f6b64d3 100644 --- a/src/modules/core/filter_watermark.c +++ b/src/modules/core/filter_watermark.c @@ -142,7 +142,14 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format // Set the b frame to be in the same position and have same consumer requirements mlt_frame_set_position( b_frame, position ); mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); - mlt_properties_set_int( b_props, "consumer_progressive", mlt_properties_get_double( a_props, "consumer_progressive" ) ); + mlt_properties_set_int( b_props, "consumer_deinterlace", mlt_properties_get_double( a_props, "consumer_deinterlace" ) ); + + if ( mlt_properties_get_int( properties, "distort" ) ) + { + mlt_properties_set( mlt_transition_properties( composite ), "distort", "true" ); + mlt_properties_set( a_props, "distort", "true" ); + mlt_properties_set( b_props, "distort", "true" ); + } if ( mlt_properties_get_int( properties, "reverse" ) == 0 ) { @@ -157,15 +164,27 @@ static int filter_get_image( mlt_frame frame, uint8_t **image, mlt_image_format } else { + char temp[ 132 ]; + int count = 0; + uint8_t *alpha = NULL; mlt_transition_process( composite, b_frame, frame ); + mlt_properties_set_int( a_props, "consumer_deinterlace", 1 ); + mlt_properties_set_int( b_props, "consumer_deinterlace", 1 ); mlt_properties_set( a_props, "rescale.interp", "nearest" ); mlt_properties_set( b_props, "rescale.interp", "nearest" ); - mlt_service_apply_filters( mlt_filter_service( this ), frame, 0 ); + mlt_service_apply_filters( mlt_filter_service( this ), b_frame, 0 ); error = mlt_frame_get_image( b_frame, image, format, width, height, 1 ); - mlt_properties_set_data( b_props, "image", *image, 0, NULL, NULL ); - mlt_properties_set_data( a_props, "image", *image, *width * *height * 2, mlt_pool_release, NULL ); + alpha = mlt_frame_get_alpha_mask( b_frame ); + mlt_properties_set_data( a_props, "image", *image, *width * *height * 2, NULL, NULL ); + mlt_properties_set_data( a_props, "alpha", alpha, *width * *height, NULL, NULL ); mlt_properties_set_int( a_props, "width", *width ); mlt_properties_set_int( a_props, "height", *height ); + mlt_properties_set_int( a_props, "progressive", 1 ); + mlt_properties_inc_ref( b_props ); + strcpy( temp, "_b_frame" ); + while( mlt_properties_get_data( a_props, temp, NULL ) != NULL ) + sprintf( temp, "_b_frame%d", count ++ ); + mlt_properties_set_data( a_props, temp, b_frame, 0, ( mlt_destructor )mlt_frame_close, NULL ); } } diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index 57cf67d0..88d6b57c 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -786,7 +786,7 @@ static int get_b_frame_image( mlt_transition this, mlt_frame b_frame, uint8_t ** mlt_properties b_props = mlt_frame_properties( b_frame ); mlt_properties properties = mlt_transition_properties( this ); - if ( mlt_properties_get( properties, "distort" ) == NULL && geometry->distort == 0 ) + if ( mlt_properties_get( properties, "distort" ) == NULL && mlt_properties_get( b_props, "distort" ) == NULL && geometry->distort == 0 ) { // Adjust b_frame pixel aspect int normalised_width = geometry->w; @@ -980,6 +980,7 @@ mlt_frame composite_copy_region( mlt_transition this, mlt_frame a_frame, mlt_pos // Assign this position to the b frame mlt_frame_set_position( b_frame, frame_position ); + mlt_properties_set( b_props, "distort", "true" ); // Return the frame return b_frame; @@ -1048,7 +1049,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // Since we are the consumer of the b_frame, we must pass along these // consumer properties from the a_frame - mlt_properties_set_double( b_props, "consumer_progressive", mlt_properties_get_double( a_props, "consumer_progressive" ) ); + mlt_properties_set_double( b_props, "consumer_deinterlace", mlt_properties_get_double( a_props, "consumer_deinterlace" ) ); mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); // Special case for titling... @@ -1067,7 +1068,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f uint8_t *src = image_b; uint8_t *alpha = mlt_frame_get_alpha_mask( b_frame ); int progressive = - mlt_properties_get_int( a_props, "consumer_progressive" ) || + mlt_properties_get_int( a_props, "consumer_deinterlace" ) || mlt_properties_get_int( properties, "progressive" ); int field; diff --git a/src/modules/core/transition_luma.c b/src/modules/core/transition_luma.c index f5da57eb..c938f0ca 100644 --- a/src/modules/core/transition_luma.c +++ b/src/modules/core/transition_luma.c @@ -75,6 +75,9 @@ static inline int dissolve_yuv( mlt_frame this, mlt_frame that, float weight, in int32_t weigh = weight * ( 1 << 16 ); int32_t weigh_complement = ( 1 - weight ) * ( 1 << 16 ); + if ( mlt_properties_get( &this->parent, "distort" ) ) + mlt_properties_set( &that->parent, "distort", mlt_properties_get( &this->parent, "distort" ) ); + mlt_properties_set_int( &that->parent, "consumer_deinterlace", mlt_properties_get_int( &this->parent, "consumer_deinterlace" ) ); mlt_frame_get_image( this, &p_dest, &format, &width, &height, 1 ); mlt_frame_get_image( that, &p_src, &format, &width_src, &height_src, 0 ); @@ -129,6 +132,9 @@ static void luma_composite( mlt_frame a_frame, mlt_frame b_frame, int luma_width format_src = mlt_image_yuv422; format_dest = mlt_image_yuv422; + if ( mlt_properties_get( &a_frame->parent, "distort" ) ) + mlt_properties_set( &b_frame->parent, "distort", mlt_properties_get( &a_frame->parent, "distort" ) ); + mlt_properties_set_int( &b_frame->parent, "consumer_deinterlace", mlt_properties_get_int( &a_frame->parent, "consumer_deinterlace" ) ); mlt_frame_get_image( a_frame, &p_dest, &format_dest, &width_dest, &height_dest, 1 ); mlt_frame_get_image( b_frame, &p_src, &format_src, &width_src, &height_src, 0 ); @@ -446,7 +452,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f float luma_softness = mlt_properties_get_double( properties, "softness" ); int progressive = - mlt_properties_get_int( a_props, "consumer_progressive" ) || + mlt_properties_get_int( a_props, "consumer_deinterlace" ) || mlt_properties_get_int( properties, "progressive" ) || mlt_properties_get_int( b_props, "luma.progressive" ); int top_field_first = mlt_properties_get_int( b_props, "top_field_first" ); diff --git a/src/modules/plus/transition_affine.c b/src/modules/plus/transition_affine.c index c37d7c2b..a8c92d03 100644 --- a/src/modules/plus/transition_affine.c +++ b/src/modules/plus/transition_affine.c @@ -587,6 +587,8 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f int y_offset = ( int )result.h >> 1; uint8_t *alpha = mlt_frame_get_alpha_mask( b_frame ); + uint8_t *mask = mlt_pool_alloc( b_width * b_height ); + uint8_t *pmask = mask; float mix; affine_t affine; @@ -613,6 +615,9 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f dz = MapZ( affine.matrix, 0, 0 ); + if ( mask != NULL ) + memset( mask, 0, b_width * b_height ); + for ( y = lower_y; y < upper_y; y ++ ) { p = q; @@ -626,12 +631,14 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f { if ( alpha == NULL ) { + *pmask ++ = 255; dx += dx & 1; *p ++ = *( b_image + dy * b_stride + ( dx << 1 ) ); *p ++ = *( b_image + dy * b_stride + ( dx << 1 ) + ( ( x & 1 ) << 1 ) + 1 ); } else { + *pmask ++ = *( alpha + dy * b_width + dx ); mix = ( float )*( alpha + dy * b_width + dx ) / 255.0; dx += dx & 1; *p = *p * ( 1 - mix ) + mix * *( b_image + dy * b_stride + ( dx << 1 ) ); @@ -643,11 +650,15 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f else { p += 2; + pmask ++; } } q += a_stride; } + + b_frame->get_alpha_mask = NULL; + mlt_properties_set_data( b_props, "alpha", mask, 0, mlt_pool_release, NULL ); } return 0;