X-Git-Url: http://research.m1stereo.tv/gitweb?a=blobdiff_plain;f=src%2Fmodules%2Fcore%2Ftransition_composite.c;h=04a518f53b569297a019abe0e8b42e71cbdae34d;hb=42eea21bf0c71036397cac39f19d537c9344081c;hp=578131bb020228d791f9838c747f2f15f8c40a36;hpb=9ce4128ce2d56a2e0c5d028d81ec6635813e252a;p=melted diff --git a/src/modules/core/transition_composite.c b/src/modules/core/transition_composite.c index 578131b..04a518f 100644 --- a/src/modules/core/transition_composite.c +++ b/src/modules/core/transition_composite.c @@ -201,7 +201,7 @@ static inline double delta_calculate( mlt_transition this, mlt_frame frame, mlt_ return length * ( y - x ) / 2.0; } -static int get_value( mlt_properties properties, char *preferred, char *fallback ) +static int get_value( mlt_properties properties, const char *preferred, const char *fallback ) { int value = mlt_properties_get_int( properties, preferred ); if ( value == 0 ) @@ -555,13 +555,13 @@ static int composite_yuv( uint8_t *p_dest, int width_dest, int height_dest, uint int alpha_b_stride = stride_src / bpp; int alpha_a_stride = stride_dest / bpp; - // Snap to even columns to prevent "chroma swap" - p_src += uneven_x_src * 2; - width_src -= 2 * uneven_x_src; - alpha_b += uneven_x_src; - p_dest += uneven_x * 2; - width_src -= 2 * uneven_x; - alpha_a += uneven_x; + // Align chroma of source and destination + if ( uneven_x != uneven_x_src ) + { + p_src += 2; + width_src -= 2; + alpha_b += 1; + } // now do the compositing only to cropped extents for ( i = 0; i < height_src; i += step ) @@ -624,7 +624,7 @@ static uint16_t* get_luma( mlt_transition this, mlt_properties properties, int w luma_height = height; } - if ( resource != NULL && strchr( resource, '%' ) ) + if ( resource && resource[0] && strchr( resource, '%' ) ) { // TODO: Clean up quick and dirty compressed/existence check FILE *test; @@ -637,7 +637,28 @@ static uint16_t* get_luma( mlt_transition this, mlt_properties properties, int w resource = temp; } - if ( resource != NULL && ( luma_bitmap == NULL || luma_width != width || luma_height != height ) ) + if ( resource && resource[0] ) + { + char *old_luma = mlt_properties_get( properties, "_luma" ); + int old_invert = mlt_properties_get_int( properties, "_luma_invert" ); + + if ( invert != old_invert || ( old_luma && old_luma[0] && strcmp( resource, old_luma ) ) ) + { + mlt_properties_set_data( properties, "_luma.orig_bitmap", NULL, 0, NULL, NULL ); + luma_bitmap = NULL; + } + } + else { + char *old_luma = mlt_properties_get( properties, "_luma" ); + if ( old_luma && old_luma[0] ) + { + mlt_properties_set_data( properties, "_luma.orig_bitmap", NULL, 0, NULL, NULL ); + luma_bitmap = NULL; + mlt_properties_set( properties, "_luma", NULL); + } + } + + if ( resource && resource[0] && ( luma_bitmap == NULL || luma_width != width || luma_height != height ) ) { uint16_t *orig_bitmap = mlt_properties_get_data( properties, "_luma.orig_bitmap", NULL ); luma_width = mlt_properties_get_int( properties, "_luma.orig_width" ); @@ -725,6 +746,8 @@ static uint16_t* get_luma( mlt_transition this, mlt_properties properties, int w mlt_properties_set_int( properties, "_luma.width", width ); mlt_properties_set_int( properties, "_luma.height", height ); mlt_properties_set_data( properties, "_luma.bitmap", luma_bitmap, width * height * 2, mlt_pool_release, NULL ); + mlt_properties_set( properties, "_luma", resource ); + mlt_properties_set_int( properties, "_luma_invert", invert ); } return luma_bitmap; } @@ -840,6 +863,50 @@ static int get_b_frame_image( mlt_transition this, mlt_frame b_frame, uint8_t ** return ret && image != NULL; } +static void crop_calculate( mlt_transition this, mlt_properties properties, struct geometry_s *result, double position ) +{ + // Initialize panning info + result->x_src = 0; + result->y_src = 0; + if ( mlt_properties_get( properties, "crop" ) ) + { + mlt_geometry crop = mlt_properties_get_data( properties, "crop_geometry", NULL ); + if ( !crop ) + { + crop = mlt_geometry_init(); + mlt_position in = mlt_transition_get_in( this ); + mlt_position out = mlt_transition_get_out( this ); + int length = out - in + 1; + double cycle = mlt_properties_get_double( properties, "cycle" ); + + // Allow a geometry repeat cycle + if ( cycle >= 1 ) + length = cycle; + else if ( cycle > 0 ) + length *= cycle; + mlt_geometry_parse( crop, mlt_properties_get( properties, "crop" ), length, result->sw, result->sh ); + mlt_properties_set_data( properties, "crop_geometry", crop, 0, (mlt_destructor)mlt_geometry_close, NULL ); + } + + // Repeat processing + int length = mlt_geometry_get_length( crop ); + int mirror_off = mlt_properties_get_int( properties, "mirror_off" ); + int repeat_off = mlt_properties_get_int( properties, "repeat_off" ); + if ( !repeat_off && position >= length && length != 0 ) + { + int section = position / length; + position -= section * length; + if ( !mirror_off && section % 2 == 1 ) + position = length - position; + } + + // Compute the pan + struct mlt_geometry_item_s crop_item; + mlt_geometry_fetch( crop, &crop_item, position ); + result->x_src = rint( crop_item.x ); + result->y_src = rint( crop_item.y ); + } +} static mlt_geometry composite_calculate( mlt_transition this, struct geometry_s *result, mlt_frame a_frame, double position ) { @@ -898,25 +965,7 @@ static mlt_geometry composite_calculate( mlt_transition this, struct geometry_s result->halign = alignment_parse( mlt_properties_get( properties, "halign" ) ); result->valign = alignment_parse( mlt_properties_get( properties, "valign" ) ); - result->x_src = 0; - result->y_src = 0; - if ( mlt_properties_get( properties, "crop" ) ) - { - mlt_geometry crop = mlt_properties_get_data( properties, "crop_geometry", NULL ); - if ( !crop ) - { - crop = mlt_geometry_init(); - mlt_position in = mlt_transition_get_in( this ); - mlt_position out = mlt_transition_get_out( this ); - int length = out - in + 1; - mlt_geometry_parse( crop, mlt_properties_get( properties, "crop" ), length, result->sw, result->sh ); - mlt_properties_set_data( properties, "crop_geometry", crop, 0, (mlt_destructor)mlt_geometry_close, NULL ); - } - struct mlt_geometry_item_s crop_item; - mlt_geometry_fetch( crop, &crop_item, position ); - result->x_src = crop_item.x; - result->y_src = crop_item.y; - } + crop_calculate( this, properties, result, position ); return start; } @@ -1089,7 +1138,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f uint8_t *alpha_b = NULL; // Composites always need scaling... defaulting to lowest - char *rescale = mlt_properties_get( a_props, "rescale.interp" ); + const char *rescale = mlt_properties_get( a_props, "rescale.interp" ); if ( rescale == NULL || !strcmp( rescale, "none" ) ) rescale = "nearest"; mlt_properties_set( a_props, "rescale.interp", rescale );