]> git.sesse.net Git - mlt/blobdiff - src/modules/kdenlive/producer_framebuffer.c
Refactor to use mlt_frame_set_image/_alpha.
[mlt] / src / modules / kdenlive / producer_framebuffer.c
index 43fa9567774f08fc725f8067ad6a68a108810ec7..6ec1740a1bf6d4f661aa67f5fe6502addcf97803 100644 (file)
@@ -41,6 +41,8 @@ static int framebuffer_get_image( mlt_frame this, uint8_t **image, mlt_image_for
        int index = ( int )mlt_frame_pop_service( this );
        mlt_properties properties = MLT_PRODUCER_PROPERTIES( producer );
 
+       mlt_service_lock( MLT_PRODUCER_SERVICE( producer ) );
+
        // Frame properties objects
        mlt_properties frame_properties = MLT_FRAME_PROPERTIES( this );
        mlt_frame first_frame = mlt_properties_get_data( properties, "first_frame", NULL );
@@ -105,24 +107,39 @@ static int framebuffer_get_image( mlt_frame this, uint8_t **image, mlt_image_for
        
 
        // Get output buffer
-       int buffersize;
+       int buffersize = 0;
        uint8_t *output = mlt_properties_get_data( properties, "output_buffer", &buffersize );
-       
-       if (output != NULL && buffersize != size)
+       if( buffersize == 0 || buffersize != size)
        {
-             // buffer size changed
-             output = NULL;
-             mlt_properties_set_data( properties, "output_buffer", NULL, 0, NULL, NULL );
-             
-             // invalidate cached frame
-             first_position = -1;
+               // invalidate cached frame
+               first_position = -1;
        }
 
        if ( need_first != first_position )
        {
+               // invalidate cached frame
+               first_position = -1;
+               
                // Bust the cached frame
-               first_frame = NULL;
                mlt_properties_set_data( properties, "first_frame", NULL, 0, NULL, NULL );
+               first_frame = NULL;
+       }
+
+       if (output != NULL && first_position != -1) {
+               // Using the cached frame
+               uint8_t *image_copy = mlt_pool_alloc( size );
+               memcpy( image_copy, output, size );
+
+               // Set the output image
+               *image = image_copy;
+               mlt_frame_set_image( this, image_copy, size, mlt_pool_release );
+
+               *width = mlt_properties_get_int( properties, "_output_width" );
+               *height = mlt_properties_get_int( properties, "_output_height" );
+               *format = mlt_properties_get_int( properties, "_output_format" );
+
+               mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
+               return 0;
        }
 
        // Get the cached frame
@@ -142,41 +159,39 @@ static int framebuffer_get_image( mlt_frame this, uint8_t **image, mlt_image_for
        }
        mlt_properties first_frame_properties = MLT_FRAME_PROPERTIES( first_frame );
        
-       if( output == NULL )
-       {
-               output = mlt_pool_alloc( size );
-
-               // Let someone else clean up
-               mlt_properties_set_data( properties, "output_buffer", output, size, mlt_pool_release, NULL ); 
-       }
 
        // Which frames are buffered?
        uint8_t *first_image = mlt_properties_get_data( first_frame_properties, "image", NULL );
        if( first_image == NULL )
        {
-               mlt_properties props = MLT_FRAME_PROPERTIES( this );
-               mlt_properties test_properties = MLT_FRAME_PROPERTIES( first_frame );
-               mlt_properties_set_double( test_properties, "consumer_aspect_ratio", mlt_properties_get_double( props, "consumer_aspect_ratio" ) );
-               mlt_properties_set( test_properties, "rescale.interp", mlt_properties_get( props, "rescale.interp" ) );
+               mlt_properties_set_double( first_frame_properties, "consumer_aspect_ratio", mlt_properties_get_double( frame_properties, "consumer_aspect_ratio" ) );
+               mlt_properties_set( first_frame_properties, "rescale.interp", mlt_properties_get( frame_properties, "rescale.interp" ) );
 
                int error = mlt_frame_get_image( first_frame, &first_image, format, width, height, writable );
 
                if ( error != 0 ) {
-                       fprintf(stderr, "first_image == NULL get image died\n");
+                       mlt_log_error( MLT_PRODUCER_SERVICE( producer ), "first_image == NULL get image died\n" );
+                       mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
                        return error;
                }
+               output = mlt_pool_alloc( size );
+               memcpy( output, first_image, size );
+               // Let someone else clean up
+               mlt_properties_set_data( properties, "output_buffer", output, size, mlt_pool_release, NULL ); 
+               mlt_properties_set_int( properties, "_output_width", *width );
+               mlt_properties_set_int( properties, "_output_height", *height );
+               mlt_properties_set_int( properties, "_output_format", *format );
+       
        }
+       mlt_service_unlock( MLT_PRODUCER_SERVICE( producer ) );
 
-       // Start with a base image
-       memcpy( output, first_image, size );
+       // Create a copy
+       uint8_t *image_copy = mlt_pool_alloc( size );
+       memcpy( image_copy, first_image, size );
 
        // Set the output image
-       *image = output;
-       mlt_properties_set_data( frame_properties, "image", output, size, NULL, NULL );
-
-       // Make sure that no further scaling is done
-       mlt_properties_set( frame_properties, "rescale.interps", "none" );
-       mlt_properties_set( frame_properties, "scale", "off" );
+       *image = image_copy;
+       mlt_frame_set_image( this, *image, size, mlt_pool_release );
 
        return 0;
 }
@@ -192,8 +207,19 @@ static int producer_get_frame( mlt_producer this, mlt_frame_ptr frame, int index
                mlt_frame_push_service( *frame, this );
                mlt_frame_push_service( *frame, framebuffer_get_image );
 
+               mlt_properties properties = MLT_PRODUCER_PROPERTIES( this );
+               mlt_properties frame_properties = MLT_FRAME_PROPERTIES(*frame);
+               
+               double force_aspect_ratio = mlt_properties_get_double( properties, "force_aspect_ratio" );
+               if ( force_aspect_ratio <= 0.0 ) force_aspect_ratio = mlt_properties_get_double( properties, "aspect_ratio" );
+               mlt_properties_set_double( frame_properties, "aspect_ratio", force_aspect_ratio );
+                
                // Give the returned frame temporal identity
                mlt_frame_set_position( *frame, mlt_producer_position( this ) );
+
+               mlt_properties_set_int( frame_properties, "real_width", mlt_properties_get_int( properties, "width" ) );
+               mlt_properties_set_int( frame_properties, "real_height", mlt_properties_get_int( properties, "height" ) );
+               mlt_properties_pass_list( frame_properties, properties, "width, height" );
        }
 
        return 0;
@@ -239,7 +265,7 @@ mlt_producer producer_framebuffer_init( mlt_profile profile, mlt_service_type ty
                        *ptr = '\0';
        }
                
-       real_producer = mlt_factory_producer( profile, NULL, props );
+       real_producer = mlt_factory_producer( profile, "abnormal", props );
        free( props );
 
        if (speed == 0.0) speed = 1.0;
@@ -249,15 +275,13 @@ mlt_producer producer_framebuffer_init( mlt_profile profile, mlt_service_type ty
                // Get the properties of this producer
                mlt_properties properties = MLT_PRODUCER_PROPERTIES( this );
 
-               // The loader normalised it for us already
-               mlt_properties_set_int( properties, "loader_normalised", 1);
                mlt_properties_set( properties, "resource", arg);
 
                // Store the producer and fitler
                mlt_properties_set_data( properties, "producer", real_producer, 0, ( mlt_destructor )mlt_producer_close, NULL );
 
                // Grab some stuff from the real_producer
-               mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( real_producer ), "length, width,height" );
+               mlt_properties_pass_list( properties, MLT_PRODUCER_PROPERTIES( real_producer ), "length, width, height, aspect_ratio" );
 
                if ( speed < 0 )
                {