]> git.sesse.net Git - mlt/blobdiff - src/modules/frei0r/frei0r_helper.c
use sse2 instruction for line compositing
[mlt] / src / modules / frei0r / frei0r_helper.c
index 83ed8fcd0f6f2b12d6e2bafad3577176ca73aecc..4f73c0f2470fdcfcda505f38c0a1f2d5a0d5d26e 100644 (file)
@@ -31,7 +31,21 @@ static void parse_color( int color, f0r_param_color_t *fcolor )
        fcolor->b /= 255;
 }
 
-int process_frei0r_item( mlt_service_type type, double position, mlt_properties prop, mlt_frame this, uint8_t **image, int *width, int *height )
+static void rgba_bgra( uint8_t *src, uint8_t* dst, int width, int height )
+{
+       int n = width * height + 1;
+
+       while ( --n )
+       {
+               *dst++ = src[2];
+               *dst++ = src[1];
+               *dst++ = src[0];
+               *dst++ = src[3];
+               src += 4;
+       }       
+}
+
+int process_frei0r_item( mlt_service service, double position, double time, mlt_properties prop, mlt_frame this, uint8_t **image, int *width, int *height )
 {
        int i=0;
        f0r_instance_t ( *f0r_construct ) ( unsigned int , unsigned int ) =  mlt_properties_get_data(  prop , "f0r_construct" ,NULL);
@@ -43,14 +57,18 @@ int process_frei0r_item( mlt_service_type type, double position, mlt_properties
        void (*f0r_set_param_value)(f0r_instance_t instance, f0r_param_t param, int param_index)=mlt_properties_get_data(  prop , "f0r_set_param_value" ,NULL);
        void (*f0r_update2) (f0r_instance_t instance, double time,
                         const uint32_t* inframe1,const uint32_t* inframe2,const uint32_t* inframe3,
-        uint32_t* outframe)=mlt_properties_get_data(  prop , "f0r_update2" ,NULL);
-
+       uint32_t* outframe)=mlt_properties_get_data(  prop , "f0r_update2" ,NULL);
+       mlt_service_type type = mlt_service_identify( service );
+       int not_thread_safe = mlt_properties_get_int( prop, "_not_thread_safe" );
 
        //use as name the width and height
        f0r_instance_t inst;
+       f0r_plugin_info_t info;
        char ctorname[1024]="";
        sprintf(ctorname,"ctor-%dx%d",*width,*height);
 
+       mlt_service_lock( service );
+
        void* neu=mlt_properties_get_data( prop , ctorname ,NULL );
        if (!f0r_construct){
                //printf("no ctor\n");
@@ -62,8 +80,11 @@ int process_frei0r_item( mlt_service_type type, double position, mlt_properties
        }else{
                inst=mlt_properties_get_data( prop ,  ctorname , NULL );
        }
+
+       if ( !not_thread_safe )
+               mlt_service_unlock( service );
+       
        if (f0r_get_plugin_info){
-               f0r_plugin_info_t info;
                f0r_get_plugin_info(&info);
                for (i=0;i<info.num_params;i++){
                        f0r_param_info_t pinfo;
@@ -103,16 +124,40 @@ int process_frei0r_item( mlt_service_type type, double position, mlt_properties
 
        int video_area = *width * *height;
        uint32_t *result = mlt_pool_alloc( video_area * sizeof(uint32_t) );
+       uint32_t *extra = NULL;
+       uint32_t *source[2] = { (uint32_t*) image[0], (uint32_t*) image[1] };
+       uint32_t *dest = result;
 
+       if (info.color_model == F0R_COLOR_MODEL_BGRA8888) {
+               rgba_bgra(image[0], (uint8_t*) result, *width, *height);
+               source[0] = result;
+               dest = (uint32_t*) image[0];
+               if (type == producer_type) {
+                       extra = mlt_pool_alloc( video_area * sizeof(uint32_t) );
+                       dest = extra;
+               }
+               else if (type == transition_type && f0r_update2) {
+                       extra = mlt_pool_alloc( video_area * sizeof(uint32_t) );
+                       rgba_bgra(image[1], (uint8_t*) extra, *width, *height);
+                       source[1] = extra;
+               }
+       }
        if (type==producer_type) {
-               f0r_update (inst, position, NULL, result );
+               f0r_update (inst, time, NULL, dest );
        } else if (type==filter_type) {
-               f0r_update ( inst, position, (uint32_t *)image[0], result );
+               f0r_update ( inst, time, source[0], dest );
        } else if (type==transition_type && f0r_update2 ){
-               f0r_update2 ( inst, position, (uint32_t *)image[0], (uint32_t *)image[1], NULL, result );
+               f0r_update2 ( inst, time, source[0], source[1], NULL, dest );
+       }
+       if ( not_thread_safe )
+               mlt_service_unlock( service );
+       if (info.color_model == F0R_COLOR_MODEL_BGRA8888) {
+               rgba_bgra((uint8_t*) dest, (uint8_t*) result, *width, *height);
        }
        *image = (uint8_t*) result;
-       mlt_properties_set_data(MLT_FRAME_PROPERTIES(this), "image", result, video_area * sizeof(uint32_t), mlt_pool_release, NULL);
+       mlt_frame_set_image(this, (uint8_t*) result, video_area * sizeof(uint32_t), mlt_pool_release);
+       if (extra)
+               mlt_pool_release(extra);
 
        return 0;
 }