X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fmodules%2Fcore%2Ftransition_luma.c;h=29eb09582d1de3192150c692a12ca170c7089662;hb=1f6faabf5ef11e6321d186772d88fb6958cdd057;hp=6c7b6e828a9b561da4062b86be314a48aff3f936;hpb=52b7a4fb7a6e8745ac40153cd18c1fb5555a82f2;p=mlt diff --git a/src/modules/core/transition_luma.c b/src/modules/core/transition_luma.c index 6c7b6e82..29eb0958 100644 --- a/src/modules/core/transition_luma.c +++ b/src/modules/core/transition_luma.c @@ -37,8 +37,8 @@ static float position_calculate( mlt_transition this, mlt_frame frame ) mlt_position out = mlt_transition_get_out( this ); // Get the position of the frame - char *name = mlt_properties_get( mlt_transition_properties( this ), "_unique_id" ); - mlt_position position = mlt_properties_get_position( mlt_frame_properties( frame ), name ); + char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( this ), "_unique_id" ); + mlt_position position = mlt_properties_get_position( MLT_FRAME_PROPERTIES( frame ), name ); // Now do the calcs return ( float )( position - in ) / ( float )( out - in + 1 ); @@ -75,9 +75,16 @@ 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 ); + // Pick the lesser of two evils ;-) + width_src = width_src > width ? width : width_src; + height_src = height_src > height ? height : height_src; + p = p_dest; limit = p_dest + height_src * width_src * 2; @@ -92,7 +99,7 @@ static inline int dissolve_yuv( mlt_frame this, mlt_frame that, float weight, in // image processing functions -static inline uint32_t smoothstep( int32_t edge1, int32_t edge2, uint32_t a ) +static inline int32_t smoothstep( int32_t edge1, int32_t edge2, uint32_t a ) { if ( a < edge1 ) return 0; @@ -125,9 +132,16 @@ 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 ); + // Pick the lesser of two evils ;-) + width_src = width_src > width_dest ? width_dest : width_src; + height_src = height_src > height_dest ? height_dest : height_src; + stride_src = width_src * 2; stride_dest = width_dest * 2; @@ -152,10 +166,9 @@ static void luma_composite( mlt_frame a_frame, mlt_frame b_frame, int luma_width int32_t i_softness = softness * ( 1 << 16 ); - int field_count = field_order <= 0 ? 1 : 2; + int field_count = field_order < 0 ? 1 : 2; int field_stride_src = field_count * stride_src; int field_stride_dest = field_count * stride_dest; - int field = 0; // composite using luma map @@ -163,7 +176,7 @@ static void luma_composite( mlt_frame a_frame, mlt_frame b_frame, int luma_width { p_row = p_src + field * stride_src; q_row = p_dest + field * stride_dest; - y_offset = ( field * luma_width ) << 16; + y_offset = field << 16; i = field; while ( i < height_src ) @@ -312,6 +325,7 @@ static void luma_read_pgm( FILE *f, uint16_t **map, int *width, int *height ) static void luma_read_yuv422( uint8_t *image, uint16_t **map, int width, int height ) { int i; + int size = width * height * 2; // allocate the luma bitmap uint16_t *p = *map = ( uint16_t* )mlt_pool_alloc( width * height * sizeof( uint16_t ) ); @@ -319,7 +333,7 @@ static void luma_read_yuv422( uint8_t *image, uint16_t **map, int width, int hei return; // proces the image data into the luma bitmap - for ( i = 0; i < width * height * 2; i += 2 ) + for ( i = 0; i < size; i += 2 ) *p++ = ( image[ i ] - 16 ) * 299; // 299 = 65535 / 219 } @@ -341,13 +355,13 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f mlt_transition transition = mlt_frame_pop_service( a_frame ); // Get the properties of the transition - mlt_properties properties = mlt_transition_properties( transition ); + mlt_properties properties = MLT_TRANSITION_PROPERTIES( transition ); // Get the properties of the a frame - mlt_properties a_props = mlt_frame_properties( a_frame ); + mlt_properties a_props = MLT_FRAME_PROPERTIES( a_frame ); // Get the properties of the b frame - mlt_properties b_props = mlt_frame_properties( b_frame ); + mlt_properties b_props = MLT_FRAME_PROPERTIES( b_frame ); // The cached luma map information int luma_width = mlt_properties_get_int( properties, "width" ); @@ -357,9 +371,30 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f // If the filename property changed, reload the map char *resource = mlt_properties_get( properties, "resource" ); + // Correct width/height if not specified + if ( luma_width == 0 || luma_height == 0 ) + { + luma_width = mlt_properties_get_int( a_props, "width" ); + luma_height = mlt_properties_get_int( a_props, "height" ); + } + if ( luma_bitmap == NULL && resource != NULL ) { - char *extension = extension = strrchr( resource, '.' ); + char temp[ 512 ]; + char *extension = strrchr( resource, '.' ); + + if ( strchr( resource, '%' ) ) + { + FILE *test; + sprintf( temp, "%s/lumas/%s/%s", mlt_factory_prefix( ), mlt_environment( "MLT_NORMALISATION" ), strchr( resource, '%' ) + 1 ); + test = fopen( temp, "r" ); + if ( test == NULL ) + strcat( temp, ".png" ); + else + fclose( test ); + resource = temp; + extension = strrchr( resource, '.' ); + } // See if it is a PGM if ( extension != NULL && strcmp( extension, ".pgm" ) == 0 ) @@ -390,7 +425,7 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f if ( producer != NULL ) { // Get the producer properties - mlt_properties producer_properties = mlt_producer_properties( producer ); + mlt_properties producer_properties = MLT_PRODUCER_PROPERTIES( producer ); // Ensure that we loop mlt_properties_set( producer_properties, "eof", "loop" ); @@ -402,13 +437,13 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f mlt_frame luma_frame = NULL; // Get the luma frame - if ( mlt_service_get_frame( mlt_producer_service( producer ), &luma_frame, 0 ) == 0 ) + if ( mlt_service_get_frame( MLT_PRODUCER_SERVICE( producer ), &luma_frame, 0 ) == 0 ) { - uint8_t *luma_image; + uint8_t *luma_image = NULL; mlt_image_format luma_format = mlt_image_yuv422; // Get image from the luma producer - mlt_properties_set( mlt_frame_properties( luma_frame ), "rescale.interp", "none" ); + mlt_properties_set( MLT_FRAME_PROPERTIES( luma_frame ), "rescale.interp", "nearest" ); mlt_frame_get_image( luma_frame, &luma_image, &luma_format, &luma_width, &luma_height, 0 ); // Generate the luma map @@ -438,38 +473,51 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f float frame_delta = delta_calculate( transition, a_frame ); float luma_softness = mlt_properties_get_double( properties, "softness" ); - int progressive = mlt_properties_get_int( b_props, "progressive" ) || - mlt_properties_get_int( a_props, "consumer_progressive" ) || + int 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" ); int reverse = mlt_properties_get_int( properties, "reverse" ); + int invert = mlt_properties_get_int( properties, "invert" ); + + if ( mlt_properties_get( a_props, "rescale.interp" ) == NULL || !strcmp( mlt_properties_get( a_props, "rescale.interp" ), "none" ) ) + mlt_properties_set( a_props, "rescale.interp", "nearest" ); // Since we are the consumer of the b_frame, we must pass along this // consumer property from the a_frame + if ( mlt_properties_get_double( a_props, "aspect_ratio" ) == 0.0 ) + mlt_properties_set_double( a_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); + if ( mlt_properties_get_double( b_props, "aspect_ratio" ) == 0.0 ) + mlt_properties_set_double( b_props, "aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); mlt_properties_set_double( b_props, "consumer_aspect_ratio", mlt_properties_get_double( a_props, "consumer_aspect_ratio" ) ); // Honour the reverse here if ( mix >= 1.0 ) mix -= floor( mix ); - mix = reverse ? 1 - mix : mix; - frame_delta *= reverse ? -1.0 : 1.0; + mix = reverse || invert ? 1 - mix : mix; + frame_delta *= reverse || invert ? -1.0 : 1.0; // Ensure we get scaling on the b_frame - mlt_properties_set( b_props, "rescale.interp", "nearest" ); + if ( mlt_properties_get( b_props, "rescale.interp" ) == NULL || !strcmp( mlt_properties_get( b_props, "rescale.interp" ), "none" ) ) + mlt_properties_set( b_props, "rescale.interp", "nearest" ); + + if ( mlt_properties_get( properties, "fixed" ) ) + mix = mlt_properties_get_double( properties, "fixed" ); if ( luma_width > 0 && luma_height > 0 && luma_bitmap != NULL ) // Composite the frames using a luma map - luma_composite( a_frame, b_frame, luma_width, luma_height, luma_bitmap, mix, frame_delta, + luma_composite( !invert ? a_frame : b_frame, !invert ? b_frame : a_frame, luma_width, luma_height, luma_bitmap, mix, frame_delta, luma_softness, progressive ? -1 : top_field_first, width, height ); else // Dissolve the frames using the time offset for mix value dissolve_yuv( a_frame, b_frame, mix, *width, *height ); // Extract the a_frame image info - *width = mlt_properties_get_int( a_props, "width" ); - *height = mlt_properties_get_int( a_props, "height" ); - *image = mlt_properties_get_data( a_props, "image", NULL ); + *width = mlt_properties_get_int( !invert ? a_props : b_props, "width" ); + *height = mlt_properties_get_int( !invert ? a_props : b_props, "height" ); + *image = mlt_properties_get_data( !invert ? a_props : b_props, "image", NULL ); return 0; } @@ -481,10 +529,10 @@ static int transition_get_image( mlt_frame a_frame, uint8_t **image, mlt_image_f static mlt_frame transition_process( mlt_transition transition, mlt_frame a_frame, mlt_frame b_frame ) { // Get a unique name to store the frame position - char *name = mlt_properties_get( mlt_transition_properties( transition ), "_unique_id" ); + char *name = mlt_properties_get( MLT_TRANSITION_PROPERTIES( transition ), "_unique_id" ); // Assign the current position to the name - mlt_properties_set_position( mlt_frame_properties( a_frame ), name, mlt_frame_get_position( a_frame ) ); + mlt_properties_set_position( MLT_FRAME_PROPERTIES( a_frame ), name, mlt_frame_get_position( a_frame ) ); // Push the transition on to the frame mlt_frame_push_service( a_frame, transition ); @@ -510,11 +558,14 @@ mlt_transition transition_luma_init( char *lumafile ) transition->process = transition_process; // Default factory - mlt_properties_set( mlt_transition_properties( transition ), "factory", "fezzik" ); + mlt_properties_set( MLT_TRANSITION_PROPERTIES( transition ), "factory", "fezzik" ); // Set the main property - mlt_properties_set( mlt_transition_properties( transition ), "resource", lumafile ); + mlt_properties_set( MLT_TRANSITION_PROPERTIES( transition ), "resource", lumafile ); + // Inform apps and framework that this is a video only transition + mlt_properties_set_int( MLT_TRANSITION_PROPERTIES( transition ), "_transition_type", 1 ); + return transition; } return NULL;