X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Fplus%2Ftransition_affine.c;h=719705618605edc4c6d9c8cc6bb041d00c8e2d57;hb=f4963a6aa07644399b273b5d2b1f9299c9047414;hp=6e10ab437ff954b5760615a6c9d973142af2fa8d;hpb=6ad443b3ffd53b2e8be119df6fb7d3f2da1c4cec;p=melted diff --git a/src/modules/plus/transition_affine.c b/src/modules/plus/transition_affine.c index 6e10ab4..7197056 100644 --- a/src/modules/plus/transition_affine.c +++ b/src/modules/plus/transition_affine.c @@ -3,22 +3,22 @@ * Copyright (C) 2003-2004 Ushodaya Enterprises Limited * Author: Charles Yates * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. * - * This program is distributed in the hope that it will be useful, + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include "transition_affine.h" +#include #include #include @@ -27,262 +27,102 @@ #include #include -/** Geometry struct. -*/ - -struct geometry_s -{ - int frame; - float position; - float mix; - int nw; // normalised width - int nh; // normalised height - int sw; // scaled width, not including consumer scale based upon w/nw - int sh; // scaled height, not including consumer scale based upon h/nh - float x; - float y; - float w; - float h; - struct geometry_s *next; -}; - -/** Parse a value from a geometry string. +/** Calculate real geometry. */ -static float parse_value( char **ptr, int normalisation, char delim, float defaults ) +static void geometry_calculate( mlt_transition this, const char *store, struct mlt_geometry_item_s *output, float position ) { - float value = defaults; + mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); + mlt_geometry geometry = mlt_properties_get_data( properties, store, NULL ); + int mirror_off = mlt_properties_get_int( properties, "mirror_off" ); + int repeat_off = mlt_properties_get_int( properties, "repeat_off" ); + int length = mlt_geometry_get_length( geometry ); - if ( *ptr != NULL && **ptr != '\0' ) + // Allow wrapping + if ( !repeat_off && position >= length && length != 0 ) { - char *end = NULL; - value = strtod( *ptr, &end ); - if ( end != NULL ) - { - if ( *end == '%' ) - value = ( value / 100.0 ) * normalisation; - while ( *end == delim || *end == '%' ) - end ++; - } - *ptr = end; + int section = position / length; + position -= section * length; + if ( !mirror_off && section % 2 == 1 ) + position = length - position; } - return value; + // Fetch the key for the position + mlt_geometry_fetch( geometry, output, position ); } -/** Parse a geometry property string with the syntax X,Y:WxH:MIX. Any value can be - expressed as a percentage by appending a % after the value, otherwise values are - assumed to be relative to the normalised dimensions of the consumer. -*/ -static void geometry_parse( struct geometry_s *geometry, struct geometry_s *defaults, char *property, int nw, int nh ) +static mlt_geometry transition_parse_keys( mlt_transition this, const char *name, const char *store, int normalised_width, int normalised_height ) { - // Assign normalised width and height - geometry->nw = nw; - geometry->nh = nh; - - // Assign from defaults if available - if ( defaults != NULL ) - { - geometry->x = defaults->x; - geometry->y = defaults->y; - geometry->w = geometry->sw = defaults->w; - geometry->h = geometry->sh = defaults->h; - geometry->mix = defaults->mix; - defaults->next = geometry; - } - else - { - geometry->mix = 100; - } + // Get the properties of the transition + mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - // Parse the geomtry string - if ( property != NULL && strcmp( property, "" ) ) - { - char *ptr = property; - geometry->x = parse_value( &ptr, nw, ',', geometry->x ); - geometry->y = parse_value( &ptr, nh, ':', geometry->y ); - geometry->w = geometry->sw = parse_value( &ptr, nw, 'x', geometry->w ); - geometry->h = geometry->sh = parse_value( &ptr, nh, ':', geometry->h ); - geometry->mix = parse_value( &ptr, 100, ' ', geometry->mix ); - } -} + // Try to fetch it first + mlt_geometry geometry = mlt_properties_get_data( properties, store, NULL ); -/** Calculate real geometry. -*/ + // Get the in and out position + mlt_position in = mlt_transition_get_in( this ); + mlt_position out = mlt_transition_get_out( this ); -static void geometry_calculate( struct geometry_s *output, struct geometry_s *in, float position ) -{ - // Search in for position - struct geometry_s *out = in->next; + // Determine length and obtain cycle + int length = out - in + 1; + double cycle = mlt_properties_get_double( properties, "cycle" ); - if ( position >= 1.0 ) - { - int section = floor( position ); - position -= section; - if ( section % 2 == 1 ) - position = 1.0 - position; - } + // Allow a geometry repeat cycle + if ( cycle >= 1 ) + length = cycle; + else if ( cycle > 0 ) + length *= cycle; - while ( out->next != NULL ) + if ( geometry == NULL ) { - if ( position >= in->position && position < out->position ) - break; + // Get the new style geometry string + char *property = mlt_properties_get( properties, name ); - in = out; - out = in->next; - } + // Create an empty geometries object + geometry = mlt_geometry_init( ); - position = ( position - in->position ) / ( out->position - in->position ); + // Parse the geometry if we have one + mlt_geometry_parse( geometry, property, length, normalised_width, normalised_height ); - // Calculate this frames geometry - if ( in->frame != out->frame - 1 ) - { - output->nw = in->nw; - output->nh = in->nh; - output->x = in->x + ( out->x - in->x ) * position; - output->y = in->y + ( out->y - in->y ) * position; - output->w = in->w + ( out->w - in->w ) * position; - output->h = in->h + ( out->h - in->h ) * position; - output->mix = in->mix + ( out->mix - in->mix ) * position; + // Store it + mlt_properties_set_data( properties, store, geometry, 0, ( mlt_destructor )mlt_geometry_close, NULL ); } else { - output->nw = out->nw; - output->nh = out->nh; - output->x = out->x; - output->y = out->y; - output->w = out->w; - output->h = out->h; - output->mix = out->mix; + // Check for updates and refresh if necessary + mlt_geometry_refresh( geometry, mlt_properties_get( properties, name ), length, normalised_width, normalised_height ); } -} -void transition_destroy_keys( void *arg ) -{ - struct geometry_s *ptr = arg; - struct geometry_s *next = NULL; - - while ( ptr != NULL ) - { - next = ptr->next; - free( ptr ); - ptr = next; - } + return geometry; } -static struct geometry_s *transition_parse_keys( mlt_transition this, int normalised_width, int normalised_height ) +static mlt_geometry composite_calculate( mlt_transition this, struct mlt_geometry_item_s *result, int nw, int nh, float position ) { - // Loop variable for property interrogation - int i = 0; - - // Get the properties of the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); - - // Get the in and out position - mlt_position in = mlt_transition_get_in( this ); - mlt_position out = mlt_transition_get_out( this ); - - // Create the start - struct geometry_s *start = calloc( 1, sizeof( struct geometry_s ) ); - - // Create the end (we always need two entries) - struct geometry_s *end = calloc( 1, sizeof( struct geometry_s ) ); - - // Pointer - struct geometry_s *ptr = start; - - // Parse the start property - geometry_parse( start, NULL, mlt_properties_get( properties, "start" ), normalised_width, normalised_height ); - - // Parse the keys in between - for ( i = 0; i < mlt_properties_count( properties ); i ++ ) - { - // Get the name of the property - char *name = mlt_properties_get_name( properties, i ); - - // Check that it's valid - if ( !strncmp( name, "key[", 4 ) ) - { - // Get the value of the property - char *value = mlt_properties_get_value( properties, i ); - - // Determine the frame number - int frame = atoi( name + 4 ); - - // Determine the position - float position = 0; - - if ( frame >= 0 && frame < ( out - in ) ) - position = ( float )frame / ( float )( out - in + 1 ); - else if ( frame < 0 && - frame < ( out - in ) ) - position = ( float )( out - in + frame ) / ( float )( out - in + 1 ); - - // For now, we'll exclude all keys received out of order - if ( position > ptr->position ) - { - // Create a new geometry - struct geometry_s *temp = calloc( 1, sizeof( struct geometry_s ) ); - - // Parse and add to the list - geometry_parse( temp, ptr, value, normalised_width, normalised_height ); - - // Assign the position and frame - temp->frame = frame; - temp->position = position; - - // Allow the next to be appended after this one - ptr = temp; - } - else - { - fprintf( stderr, "Key out of order - skipping %s\n", name ); - } - } - } - - // Parse the end - geometry_parse( end, ptr, mlt_properties_get( properties, "end" ), normalised_width, normalised_height ); - if ( out > 0 ) - end->position = ( float )( out - in ) / ( float )( out - in + 1 ); - else - end->position = 1; + // Structures for geometry + mlt_geometry start = transition_parse_keys( this, "geometry", "geometries", nw, nh ); - // Assign to properties to ensure we get destroyed - mlt_properties_set_data( properties, "geometries", start, 0, transition_destroy_keys, NULL ); + // Do the calculation + geometry_calculate( this, "geometries", result, position ); return start; } -struct geometry_s *composite_calculate( struct geometry_s *result, mlt_transition this, mlt_frame a_frame, float position ) +static inline float composite_calculate_key( mlt_transition this, const char *name, const char *store, int norm, float position ) { - // Get the properties from the transition - mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); + // Struct for the result + struct mlt_geometry_item_s result; - // Get the properties from the frame - mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); - // Structures for geometry - struct geometry_s *start = mlt_properties_get_data( properties, "geometries", NULL ); - - // Now parse the geometries - if ( start == NULL ) - { - // Obtain the normalised width and height from the a_frame - int normalised_width = mlt_properties_get_int( a_props, "normalised_width" ); - int normalised_height = mlt_properties_get_int( a_props, "normalised_height" ); - - // Parse the transitions properties - start = transition_parse_keys( this, normalised_width, normalised_height ); - } + transition_parse_keys( this, name, store, norm, 0 ); // Do the calculation - geometry_calculate( result, start, position ); + geometry_calculate( this, store, &result, position ); - return start; + return result.x; } -typedef struct +typedef struct { float matrix[3][3]; } @@ -324,7 +164,7 @@ static void affine_multiply( float this[3][3], float that[3][3] ) } // Rotate by a given angle -static void affine_rotate( float this[3][3], float angle ) +static void affine_rotate_x( float this[3][3], float angle ) { float affine[3][3]; affine[0][0] = cos( angle * M_PI / 180 ); @@ -426,16 +266,16 @@ static inline double MapZ( float this[3][3], int x, int y ) #define MAX( x, y ) x > y ? x : y #define MIN( x, y ) x < y ? x : y -static void affine_max_output( float this[3][3], float *w, float *h ) +static void affine_max_output( float this[3][3], float *w, float *h, float dz ) { - int tlx = MapX( this, -720, 576 ); - int tly = MapY( this, -720, 576 ); - int trx = MapX( this, 720, 576 ); - int try = MapY( this, 720, 576 ); - int blx = MapX( this, -720, -576 ); - int bly = MapY( this, -720, -576 ); - int brx = MapX( this, 720, -576 ); - int bry = MapY( this, 720, -576 ); + int tlx = MapX( this, -720, 576 ) / dz; + int tly = MapY( this, -720, 576 ) / dz; + int trx = MapX( this, 720, 576 ) / dz; + int try = MapY( this, 720, 576 ) / dz; + int blx = MapX( this, -720, -576 ) / dz; + int bly = MapY( this, -720, -576 ) / dz; + int brx = MapX( this, 720, -576 ) / dz; + int bry = MapY( this, 720, -576 ) / dz; int max_x; int max_y; @@ -464,6 +304,54 @@ static void affine_max_output( float this[3][3], float *w, float *h ) #define IN_RANGE( v, r ) ( v >= - r / 2 && v < r / 2 ) +static inline void get_affine( affine_t *affine, mlt_transition this, float position ) +{ + mlt_properties properties = MLT_TRANSITION_PROPERTIES( this ); + int keyed = mlt_properties_get_int( properties, "keyed" ); + affine_init( affine->matrix ); + + if ( keyed == 0 ) + { + float fix_rotate_x = mlt_properties_get_double( properties, "fix_rotate_x" ); + float fix_rotate_y = mlt_properties_get_double( properties, "fix_rotate_y" ); + float fix_rotate_z = mlt_properties_get_double( properties, "fix_rotate_z" ); + float rotate_x = mlt_properties_get_double( properties, "rotate_x" ); + float rotate_y = mlt_properties_get_double( properties, "rotate_y" ); + float rotate_z = mlt_properties_get_double( properties, "rotate_z" ); + float fix_shear_x = mlt_properties_get_double( properties, "fix_shear_x" ); + float fix_shear_y = mlt_properties_get_double( properties, "fix_shear_y" ); + float fix_shear_z = mlt_properties_get_double( properties, "fix_shear_z" ); + float shear_x = mlt_properties_get_double( properties, "shear_x" ); + float shear_y = mlt_properties_get_double( properties, "shear_y" ); + float shear_z = mlt_properties_get_double( properties, "shear_z" ); + float ox = mlt_properties_get_double( properties, "ox" ); + float oy = mlt_properties_get_double( properties, "oy" ); + + affine_rotate_x( affine->matrix, fix_rotate_x + rotate_x * position ); + affine_rotate_y( affine->matrix, fix_rotate_y + rotate_y * position ); + affine_rotate_z( affine->matrix, fix_rotate_z + rotate_z * position ); + affine_shear( affine->matrix, + fix_shear_x + shear_x * position, + fix_shear_y + shear_y * position, + fix_shear_z + shear_z * position ); + affine_offset( affine->matrix, ox, oy ); + } + else + { + float rotate_x = composite_calculate_key( this, "rotate_x", "rotate_x_info", 360, position ); + float rotate_y = composite_calculate_key( this, "rotate_y", "rotate_y_info", 360, position ); + float rotate_z = composite_calculate_key( this, "rotate_z", "rotate_z_info", 360, position ); + float shear_x = composite_calculate_key( this, "shear_x", "shear_x_info", 360, position ); + float shear_y = composite_calculate_key( this, "shear_y", "shear_y_info", 360, position ); + float shear_z = composite_calculate_key( this, "shear_z", "shear_z_info", 360, position ); + + affine_rotate_x( affine->matrix, rotate_x ); + affine_rotate_y( affine->matrix, rotate_y ); + affine_rotate_z( affine->matrix, rotate_z ); + affine_shear( affine->matrix, shear_x, shear_y, shear_z ); + } +} + /** Get the image. */ @@ -497,47 +385,49 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f mlt_position position = mlt_properties_get_position( a_props, name ); mlt_position in = mlt_properties_get_position( properties, "in" ); mlt_position out = mlt_properties_get_position( properties, "out" ); + int mirror = mlt_properties_get_position( properties, "mirror" ); + int length = out - in + 1; - // Structures for geometry - struct geometry_s *start = mlt_properties_get_data( properties, "geometries", NULL ); - struct geometry_s result; + // Obtain the normalised width and height from the a_frame + int normalised_width = mlt_properties_get_int( a_props, "normalised_width" ); + int normalised_height = mlt_properties_get_int( a_props, "normalised_height" ); - // Now parse the geometries - if ( start == NULL ) - { - // Obtain the normalised width and height from the a_frame - int normalised_width = mlt_properties_get_int( a_props, "normalised_width" ); - int normalised_height = mlt_properties_get_int( a_props, "normalised_height" ); + double consumer_ar = mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ; - // Parse the transitions properties - start = transition_parse_keys( this, normalised_width, normalised_height ); - } + // Structures for geometry + struct mlt_geometry_item_s result; + + if ( mirror && position > length / 2 ) + position = abs( position - length ); // Fetch the a frame image mlt_frame_get_image( a_frame, image, format, width, height, 1 ); // Calculate the region now - composite_calculate( &result, this, a_frame, ( float )( position ) / ( out - in + 1 ) ); + composite_calculate( this, &result, normalised_width, normalised_height, ( float )position ); // Fetch the b frame image - result.w = ( int )( result.w * *width / result.nw ); - result.h = ( int )( result.h * *height / result.nh ); - result.x = ( int )( result.x * *width / result.nw ); - result.y = ( int )( result.y * *height / result.nh ); - result.w -= ( int )abs( result.w ) % 2; - result.x -= ( int )abs( result.x ) % 2; + result.w = ( int )( result.w * *width / normalised_width ); + result.h = ( int )( result.h * *height / normalised_height ); + result.x = ( int )( result.x * *width / normalised_width ); + result.y = ( int )( result.y * *height / normalised_height ); + //result.w -= ( int )abs( result.w ) % 2; + //result.x -= ( int )abs( result.x ) % 2; b_width = result.w; b_height = result.h; + if ( mlt_properties_get_double( b_props, "aspect_ratio" ) == 0.0 ) + mlt_properties_set_double( b_props, "aspect_ratio", consumer_ar ); + if ( !strcmp( mlt_properties_get( a_props, "rescale.interp" ), "none" ) ) { mlt_properties_set( b_props, "rescale.interp", "nearest" ); - mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "aspect_ratio" ) ); + mlt_properties_set_double( b_props, "consumer_aspect_ratio", consumer_ar ); } else { mlt_properties_set( b_props, "rescale.interp", mlt_properties_get( a_props, "rescale.interp" ) ); - mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); + mlt_properties_set_double( b_props, "consumer_aspect_ratio", consumer_ar ); } mlt_properties_set_int( b_props, "distort", mlt_properties_get_int( properties, "distort" ) ); @@ -554,20 +444,8 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f float sw, sh; // Get values from the transition - float fix_rotate_x = mlt_properties_get_double( properties, "fix_rotate_x" ); - float fix_rotate_y = mlt_properties_get_double( properties, "fix_rotate_y" ); - float fix_rotate_z = mlt_properties_get_double( properties, "fix_rotate_z" ); - float rotate_x = mlt_properties_get_double( properties, "rotate_x" ); - float rotate_y = mlt_properties_get_double( properties, "rotate_y" ); - float rotate_z = mlt_properties_get_double( properties, "rotate_z" ); - float fix_shear_x = mlt_properties_get_double( properties, "fix_shear_x" ); - float fix_shear_y = mlt_properties_get_double( properties, "fix_shear_y" ); - float fix_shear_z = mlt_properties_get_double( properties, "fix_shear_z" ); - float shear_x = mlt_properties_get_double( properties, "shear_x" ); - float shear_y = mlt_properties_get_double( properties, "shear_y" ); - float shear_z = mlt_properties_get_double( properties, "shear_z" ); - float ox = mlt_properties_get_double( properties, "ox" ); - float oy = mlt_properties_get_double( properties, "oy" ); + float scale_x = mlt_properties_get_double( properties, "scale_x" ); + float scale_y = mlt_properties_get_double( properties, "scale_y" ); int scale = mlt_properties_get_int( properties, "scale" ); uint8_t *p = *image; @@ -575,7 +453,8 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f int cx = result.x + ( b_width >> 1 ); int cy = result.y + ( b_height >> 1 ); - + cx -= cx % 2; + int lower_x = 0 - cx; int upper_x = *width - cx; int lower_y = 0 - cy; @@ -587,78 +466,101 @@ 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 *mask = mlt_frame_get_alpha_mask( a_frame ); uint8_t *pmask = mask; float mix; affine_t affine; - affine_init( affine.matrix ); - affine_rotate( affine.matrix, fix_rotate_x + rotate_x * ( position - in ) ); - affine_rotate_y( affine.matrix, fix_rotate_y + rotate_y * ( position - in ) ); - affine_rotate_z( affine.matrix, fix_rotate_z + rotate_z * ( position - in ) ); - affine_shear( affine.matrix, - fix_shear_x + shear_x * ( position - in ), - fix_shear_y + shear_y * ( position - in ), - fix_shear_z + shear_z * ( position - in ) ); - affine_offset( affine.matrix, ox, oy ); - if ( scale ) - { - affine_max_output( affine.matrix, &sw, &sh ); - affine_scale( affine.matrix, sw, sh ); - } - - lower_x -= ( lower_x & 1 ); - upper_x -= ( upper_x & 1 ); + get_affine( &affine, this, ( float )position ); q = *image; dz = MapZ( affine.matrix, 0, 0 ); - if ( mask != NULL ) - memset( mask, 0, b_width * b_height ); + if ( mask == NULL ) + { + mask = mlt_pool_alloc( *width * *height ); + pmask = mask; + memset( mask, 255, *width * *height ); + } + + if ( ( int )abs( dz * 1000 ) < 25 ) + goto getout; - for ( y = lower_y; y < upper_y; y ++ ) + if ( scale ) { - p = q; + affine_max_output( affine.matrix, &sw, &sh, dz ); + affine_scale( affine.matrix, sw, sh ); + } + else if ( scale_x != 0 && scale_y != 0 ) + { + affine_scale( affine.matrix, scale_x, scale_y ); + } - for ( x = lower_x; x < upper_x; x ++ ) + if ( alpha == NULL ) + { + for ( y = lower_y; y < upper_y; y ++ ) { - dx = MapX( affine.matrix, x, y ) / dz + x_offset; - dy = MapY( affine.matrix, x, y ) / dz + y_offset; + p = q; - if ( dx >= 0 && dx < b_width && dy >=0 && dy < b_height ) + for ( x = lower_x; x < upper_x; x ++ ) { - if ( alpha == NULL ) + dx = MapX( affine.matrix, x, y ) / dz + x_offset; + dy = MapY( affine.matrix, x, y ) / dz + y_offset; + + if ( dx >= 0 && dx < b_width && dy >=0 && dy < b_height ) { - *pmask ++ = 255; - dx += dx & 1; + pmask ++; + dx -= dx & 1; *p ++ = *( b_image + dy * b_stride + ( dx << 1 ) ); *p ++ = *( b_image + dy * b_stride + ( dx << 1 ) + ( ( x & 1 ) << 1 ) + 1 ); } else { + p += 2; + pmask ++; + } + } + + q += a_stride; + } + } + else + { + for ( y = lower_y; y < upper_y; y ++ ) + { + p = q; + + for ( x = lower_x; x < upper_x; x ++ ) + { + dx = MapX( affine.matrix, x, y ) / dz + x_offset; + dy = MapY( affine.matrix, x, y ) / dz + y_offset; + + if ( dx >= 0 && dx < b_width && dy >=0 && dy < b_height ) + { *pmask ++ = *( alpha + dy * b_width + dx ); mix = ( float )*( alpha + dy * b_width + dx ) / 255.0; - dx += dx & 1; + dx -= dx & 1; *p = *p * ( 1 - mix ) + mix * *( b_image + dy * b_stride + ( dx << 1 ) ); p ++; *p = *p * ( 1 - mix ) + mix * *( b_image + dy * b_stride + ( dx << 1 ) + ( ( x & 1 ) << 1 ) + 1 ); p ++; } + else + { + p += 2; + pmask ++; + } } - else - { - p += 2; - pmask ++; - } - } - q += a_stride; + q += a_stride; + } } - b_frame->get_alpha_mask = NULL; - mlt_properties_set_data( b_props, "alpha", mask, 0, mlt_pool_release, NULL ); +getout: + a_frame->get_alpha_mask = NULL; + mlt_properties_set_data( a_props, "alpha", mask, 0, mlt_pool_release, NULL ); } return 0; @@ -691,7 +593,7 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram /** Constructor for the filter. */ -mlt_transition transition_affine_init( char *arg ) +mlt_transition transition_affine_init( mlt_profile profile, mlt_service_type type, const char *id, char *arg ) { mlt_transition transition = mlt_transition_new( ); if ( transition != NULL ) @@ -699,7 +601,7 @@ mlt_transition transition_affine_init( char *arg ) mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "sx", 1 ); mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "sy", 1 ); mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "distort", 0 ); - mlt_properties_set( MLT_TRANSITION_PROPERTIES( transition ), "start", "0,0:100%x100%" ); + mlt_properties_set( MLT_TRANSITION_PROPERTIES( transition ), "geometry", "0,0:100%x100%" ); // Inform apps and framework that this is a video only transition mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "_transition_type", 1 ); transition->process = transition_process;