fix broken aspect handling again
[melted] / src / modules / core / transition_luma.c
index ebc8915..9a180d1 100644 (file)
@@ -34,7 +34,7 @@ typedef struct
        struct mlt_transition_s parent;
        char *filename;
        int width;
-       int height;                                                     
+       int height;
        float *bitmap;
 }
 transition_luma;
@@ -59,99 +59,60 @@ static inline float smoothstep( float edge1, float edge2, float a )
        return ( a * a * ( 3 - 2 * a ) );
 }
 
-static int frame_composite_yuv( mlt_frame this, mlt_frame that, int x, int y, float weight, int *width, int *height )
-{
-       int ret = 0;
-       int width_src = *width, height_src = *height;
-       int width_dest = *width, height_dest = *height;
-       mlt_image_format format_src = mlt_image_yuv422, format_dest = mlt_image_yuv422;
-       uint8_t *p_src, *p_dest;
-       int i, j;
-       int stride_src;
-       int stride_dest;
-       int x_src = 0, y_src = 0;
-
-       // optimization point - no work to do
-       if ( ( x < 0 && -x >= width_src ) || ( y < 0 && -y >= height_src ) )
-               return ret;
-
-       format_src = mlt_image_yuv422;
-       format_dest = mlt_image_yuv422;
-
-       mlt_frame_get_image( this, &p_dest, &format_dest, &width_dest, &height_dest, 1 /* writable */ );
-       mlt_frame_get_image( that, &p_src, &format_src, &width_src, &height_src, 0 /* writable */ );
+/** Calculate the position for this frame.
+*/
 
-       stride_src = width_src * 2;
-       stride_dest = width_dest * 2;
-       
-       // crop overlay off the left edge of frame
-       if ( x < 0 )
-       {
-               x_src = -x;
-               width_src -= x_src;
-               x = 0;
-       }
-       
-       // crop overlay beyond right edge of frame
-       else if ( x + width_src > width_dest )
-               width_src = width_dest - x;
+static float position_calculate( mlt_transition this, mlt_frame frame )
+{
+       // Get the in and out position
+       mlt_position in = mlt_transition_get_in( this );
+       mlt_position out = mlt_transition_get_out( this );
 
-       // crop overlay off the top edge of the frame
-       if ( y < 0 )
-       {
-               y_src = -y;
-               height_src -= y_src;
-       }
-       // crop overlay below bottom edge of frame
-       else if ( y + height_src > height_dest )
-               height_src = height_dest - y;
+       // Get the position of the frame
+       mlt_position position = mlt_frame_get_position( frame );
 
-       // offset pointer into overlay buffer based on cropping
-       p_src += x_src * 2 + y_src * stride_src;
+       // Now do the calcs
+       return ( float )( position - in ) / ( float )( out - in + 1 );
+}
 
-       // offset pointer into frame buffer based upon positive, even coordinates only!
-       p_dest += ( x < 0 ? 0 : x ) * 2 + ( y < 0 ? 0 : y ) * stride_dest;
+/** Calculate the field delta for this frame - position between two frames.
+*/
 
-       // Get the alpha channel of the overlay
-       uint8_t *p_alpha = mlt_frame_get_alpha_mask( that );
+static float delta_calculate( mlt_transition this, mlt_frame frame )
+{
+       // Get the in and out position
+       mlt_position in = mlt_transition_get_in( this );
+       mlt_position out = mlt_transition_get_out( this );
 
-       // offset pointer into alpha channel based upon cropping
-       if ( p_alpha )
-               p_alpha += x_src + y_src * stride_src / 2;
+       // Get the position of the frame
+       mlt_position position = mlt_frame_get_position( frame );
 
-       uint8_t *p = p_src;
-       uint8_t *q = p_dest;
-       uint8_t *o = p_dest;
-       uint8_t *z = p_alpha;
+       // Now do the calcs
+       float x = ( float )( position - in ) / ( float )( out - in + 1 );
+       position++;
+       float y = ( float )( position - in ) / ( float )( out - in + 1 );
 
-       uint8_t Y;
-       uint8_t UV;
-       uint8_t a;
-       float value;
+       return ( y - x ) / 2.0;
+}
 
-       // now do the compositing only to cropped extents
-       for ( i = 0; i < height_src; i++ )
-       {
-               p = p_src;
-               q = p_dest;
-               o = p_dest;
-               z = p_alpha;
+static inline int dissolve_yuv( mlt_frame this, mlt_frame that, float weight, int width, int height )
+{
+       int ret = 0;
+       int width_src = width, height_src = height;
+       mlt_image_format format = mlt_image_yuv422;
+       uint8_t *p_src, *p_dest;
+       float weight_complement = 1 - weight;
+       uint8_t *p;
+       uint8_t *limit;
 
-               for ( j = 0; j < width_src; j ++ )
-               {
-                       Y = *p ++;
-                       UV = *p ++;
-                       a = ( z == NULL ) ? 255 : *z ++;
-                       value = ( weight * ( float ) a / 255.0 );
-                       *o ++ = (uint8_t)( Y * value + *q++ * ( 1 - value ) );
-                       *o ++ = (uint8_t)( UV * value + *q++ * ( 1 - value ) );
-               }
+       mlt_frame_get_image( this, &p_dest, &format, &width, &height, 1 /* writable */ );
+       mlt_frame_get_image( that, &p_src, &format, &width_src, &height_src, 0 /* writable */ );
+       
+       p = p_dest;
+       limit = p_dest + height_src * width_src * 2;
 
-               p_src += stride_src;
-               p_dest += stride_dest;
-               if ( p_alpha )
-                       p_alpha += stride_src / 2;
-       }
+       while ( p < limit )
+               *p_dest++ = ( uint8_t )( *p_src++ * weight + *p++ * weight_complement );
 
        return ret;
 }
@@ -199,7 +160,7 @@ static void luma_composite( mlt_frame a_frame, mlt_frame b_frame, int luma_width
 
        uint8_t y;
        uint8_t uv;
-       float value;
+       float value;
 
        float x_diff = ( float )luma_width / ( float )*width;
        float y_diff = ( float )luma_height / ( float )*height;
@@ -243,25 +204,27 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form
        mlt_properties b_props = mlt_frame_properties( b_frame );
 
        // Arbitrary composite defaults
-       float frame_delta = 1 / mlt_properties_get_double( b_props, "fps" );
        float mix = mlt_properties_get_double( b_props, "image.mix" );
+       float frame_delta = mlt_properties_get_double( b_props, "luma.delta" );
        int luma_width = mlt_properties_get_int( b_props, "luma.width" );
        int luma_height = mlt_properties_get_int( b_props, "luma.height" );
        float *luma_bitmap = mlt_properties_get_data( b_props, "luma.bitmap", NULL );
        float luma_softness = mlt_properties_get_double( b_props, "luma.softness" );
-       int progressive = mlt_properties_get_int( b_props, "progressive" );
+       int progressive = mlt_properties_get_int( b_props, "progressive" ) ||
+                       mlt_properties_get_int( a_props, "consumer_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( b_props, "luma.reverse" );
 
        // Since we are the consumer of the b_frame, we must pass along this
        // consumer property from the a_frame
-       mlt_properties_set_double( b_props, "consumer_aspect_ratio",
-               mlt_properties_get_double( mlt_frame_properties( this ), "consumer_aspect_ratio" ) );
-       mlt_properties_set_double( b_props, "consumer_scale",
-               mlt_properties_get_double( mlt_frame_properties( this ), "consumer_scale" ) );
+       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_scale", mlt_properties_get_double( a_props, "consumer_scale" ) );
                
        // Honour the reverse here
        mix = reverse ? 1 - mix : mix;
+       frame_delta *= reverse ? -1.0 : 1.0;
 
        // Ensure we get scaling on the b_frame
        mlt_properties_set( b_props, "rescale.interp", "nearest" );
@@ -269,10 +232,10 @@ static int transition_get_image( mlt_frame this, uint8_t **image, mlt_image_form
        if ( luma_width > 0 && luma_height > 0 && luma_bitmap != NULL )
                // Composite the frames using a luma map
                luma_composite( this, b_frame, luma_width, luma_height, luma_bitmap, mix, frame_delta,
-                       luma_softness, progressive > 0 ? -1 : top_field_first, width, height );
+                       luma_softness, progressive ? -1 : top_field_first, width, height );
        else
                // Dissolve the frames using the time offset for mix value
-               frame_composite_yuv( this, b_frame, 0, 0, mix, width, height );
+               dissolve_yuv( this, b_frame, mix, *width, *height );
 
        // Extract the a_frame image info
        *width = mlt_properties_get_int( a_props, "width" );
@@ -341,8 +304,7 @@ static void luma_read_pgm( FILE *f, float **map, int *width, int *height )
                bpp = maxval > 255 ? 2 : 1;
                
                // allocate temporary storage for the raw data
-               // IRRIGATE ME
-               data = malloc( *width * *height * bpp );
+               data = mlt_pool_alloc( *width * *height * bpp );
                if ( data == NULL )
                        break;
 
@@ -351,8 +313,7 @@ static void luma_read_pgm( FILE *f, float **map, int *width, int *height )
                        break;
                
                // allocate the luma bitmap
-               // IRRIGATE ME
-               *map =  p = (float*) malloc( *width * *height * sizeof( float ) );
+               *map = p = (float*)mlt_pool_alloc( *width * *height * sizeof( float ) );
                if ( *map == NULL )
                        break;
 
@@ -369,7 +330,7 @@ static void luma_read_pgm( FILE *f, float **map, int *width, int *height )
        }
                
        if ( data != NULL )
-               free( data );
+               mlt_pool_release( data );
 }
 
 
@@ -397,20 +358,15 @@ static mlt_frame transition_process( mlt_transition transition, mlt_frame a_fram
                pipe = fopen( luma_file, "r" );
                if ( pipe != NULL )
                {
-                       free( this->bitmap );
+                       mlt_pool_release( this->bitmap );
                        luma_read_pgm( pipe, &this->bitmap, &this->width, &this->height );
                        fclose( pipe );
                }
        }
 
-       // Determine the time position of this frame in the transition duration
-       mlt_position in = mlt_transition_get_in( transition );
-       mlt_position out = mlt_transition_get_out( transition );
-       mlt_position time = mlt_frame_get_position( b_frame );
-       float pos = ( float )( time - in ) / ( float )( out - in + 1 );
-       
        // Set the b frame properties
-       mlt_properties_set_double( b_props, "image.mix", pos );
+       mlt_properties_set_double( b_props, "image.mix", position_calculate( transition, b_frame ) );
+       mlt_properties_set_double( b_props, "luma.delta", delta_calculate( transition, b_frame ) );
        mlt_properties_set_int( b_props, "luma.width", this->width );
        mlt_properties_set_int( b_props, "luma.height", this->height );
        mlt_properties_set_data( b_props, "luma.bitmap", this->bitmap, 0, NULL, NULL );
@@ -447,7 +403,7 @@ mlt_transition transition_luma_init( char *lumafile )
 static void transition_close( mlt_transition parent )
 {
        transition_luma *this = (transition_luma*) parent->child;
-       free( this->bitmap );
+       mlt_pool_release( this->bitmap );
        free( this->filename );
        free( this );
 }