]> git.sesse.net Git - mlt/commitdiff
Make bloxblur faster and simpler.
authorDan Dennedy <dan@dennedy.org>
Fri, 4 Jun 2010 05:58:35 +0000 (22:58 -0700)
committerDan Dennedy <dan@dennedy.org>
Fri, 4 Jun 2010 05:58:35 +0000 (22:58 -0700)
It no longer does YUV-RGB-YUV conversion; just operates in RGB.

src/modules/kdenlive/filter_boxblur.c

index ab318df365ac08a553fdd08513c4730e30385f2b..c48fc3dee99fcbe563ace166a84f92aa16c1690e 100644 (file)
 #include <math.h>
 
 
-static void PreCompute(uint8_t *yuv, int32_t *rgb, int width, int height)
+static void PreCompute(uint8_t *image, int32_t *rgb, int width, int height)
 {
        register int x, y, z;
-       register int uneven = width % 2;
-       int w = (width - uneven ) / 2;
-       int yy, uu, vv;
-       int r, g, b;
        int32_t pts[3];
-       for (y=0; y<height; y++)
+       
+       for (y = 0; y < height; y++)
        {
-               for (x=0; x<w; x++)
+               for (x = 0; x < width; x++)
                {
-                       uu = yuv[1];
-                       vv = yuv[3];
-                       yy = yuv[0];
-                       YUV2RGB(yy, uu, vv, r, g, b);
-                       pts[0] = r;
-                       pts[1] = g;
-                       pts[2] = b;
+                       pts[0] = image[0];
+                       pts[1] = image[1];
+                       pts[2] = image[2];
                        for (z = 0; z < 3; z++) 
                        {
-                               if (x>0) pts[z]+=rgb[-3];
-                               if (y>0) pts[z]+=rgb[-(width*3)];
-                               if (x>0 && y>0) pts[z]-=rgb[-((width+1)*3)];
-                               *rgb++=pts[z];
-                       }
-
-                       yy = yuv[2];
-                       YUV2RGB(yy, uu, vv, r, g, b);
-                       pts[0] = r;
-                       pts[1] = g;
-                       pts[2] = b;
-                       for (z = 0; z < 3; z++)
-                       {
-                               pts[z]+=rgb[-3];
-                               if (y>0)
-                               {
-                                       pts[z]+=rgb[-(width*3)];
-                                       pts[z]-=rgb[-((width+1)*3)];
-                               }
-                               *rgb++=pts[z];
-                       }
-                       yuv += 4;
-               }
-               if (uneven) 
-               {
-                       uu = yuv[1];
-                       vv = yuv[3];
-                       yy = yuv[0];
-                       YUV2RGB(yy, uu, vv, r, g, b);
-                       pts[0] = r;
-                       pts[1] = g;
-                       pts[2] = b;
-                       for (z = 0; z < 3; z++)
-                       {
-                               pts[z]+=rgb[-3];
-                               if (y>0)
-                               {
-                                       pts[z]+=rgb[-(width*3)];
-                                       pts[z]-=rgb[-((width+1)*3)];
-                               }
-                               *rgb++=pts[z];
-                       }
-                       yuv += 2;
+                               if (x > 0) pts[z] += rgb[-3];
+                               if (y > 0) pts[z] += rgb[width * -3];
+                               if (x>0 && y>0) pts[z] -= rgb[(width + 1) * -3];
+                               *rgb++ = pts[z];
+            }
+                       image += 3;
                }
        }
 }
 
 static int32_t GetRGB(int32_t *rgb, unsigned int w, unsigned int h, unsigned int x, int offsetx, unsigned int y, int offsety, unsigned int z)
 {
-       int xtheo = x * 2 + offsetx;
+       int xtheo = x * 1 + offsetx;
        int ytheo = y + offsety;
        if (xtheo < 0) xtheo = 0; else if (xtheo >= w) xtheo = w - 1;
        if (ytheo < 0) ytheo = 0; else if (ytheo >= h) ytheo = h - 1;
        return rgb[3*(xtheo+ytheo*w)+z];
 }
 
-static int32_t GetRGB2(int32_t *rgb, unsigned int w, unsigned int h, unsigned int x, int offsetx, unsigned int y, int offsety, unsigned int z)
-{
-       int xtheo = x * 2 + 1 + offsetx;
-       int ytheo = y + offsety;
-       if (xtheo < 0) xtheo = 0; else if (xtheo >= w) xtheo = w - 1;
-       if (ytheo < 0) ytheo = 0; else if (ytheo >= h) ytheo = h - 1;
-       return rgb[3*(xtheo+ytheo*w)+z];
-}
-
-static void DoBoxBlur(uint8_t *yuv, int32_t *rgb, unsigned int width, unsigned int height, unsigned int boxw, unsigned int boxh)
+static void DoBoxBlur(uint8_t *image, int32_t *rgb, unsigned int width, unsigned int height, unsigned int boxw, unsigned int boxh)
 {
        register int x, y;
-       int32_t r, g, b;
-       register int uneven = width % 2;
-       register int y0, y1, u0, u1, v0, v1;
-       int w = (width - uneven ) / 2;
        float mul = 1.f / ((boxw*2) * (boxh*2));
 
        for (y = 0; y < height; y++)
        {
-               for (x = 0; x < w; x++)
+               for (x = 0; x < width; x++)
                {
-                       r = GetRGB(rgb, width, height, x, +boxw, y, +boxh, 0) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 0) - GetRGB(rgb, width, height, x, -boxw, y, + boxh, 0) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 0);
-                       g = GetRGB(rgb, width, height, x, +boxw, y, +boxh, 1) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 1) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 1) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 1);
-                       b = GetRGB(rgb, width, height, x, +boxw, y, +boxh, 2) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 2) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 2) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 2);
-                       r = (int32_t) (r * mul);
-                       g = (int32_t) (g * mul);
-                       b = (int32_t) (b * mul);
-                       RGB2YUV (r, g, b, y0, u0, v0);
-
-                       r = GetRGB2(rgb, width, height, x, +boxw, y, +boxh, 0) + GetRGB2(rgb, width, height, x, -boxw, y, -boxh, 0) - GetRGB2(rgb, width, height, x, -boxw, y, +boxh, 0) - GetRGB2(rgb, width, height, x, +boxw, y, -boxh, 0);
-                       g = GetRGB2(rgb, width, height, x, +boxw, y, +boxh, 1) + GetRGB2(rgb, width, height, x, -boxw, y, -boxh, 1) - GetRGB2(rgb, width, height, x, -boxw, y, +boxh, 1) - GetRGB2(rgb, width, height, x, +boxw, y, -boxh, 1);
-                       b = GetRGB2(rgb, width, height, x, +boxw, y, +boxh, 2) + GetRGB2(rgb, width, height, x, -boxw, y, -boxh, 2) - GetRGB2(rgb, width, height, x, -boxw, y, +boxh, 2) - GetRGB2(rgb, width, height, x, +boxw, y, -boxh, 2);
-                       r = (int32_t) (r * mul);
-                       g = (int32_t) (g * mul);
-                       b = (int32_t) (b * mul);
-                       RGB2YUV (r, g, b, y1, u1, v1);
-                       *yuv++ = y0;
-                       *yuv++ = (u0+u1) >> 1;
-                       *yuv++ = y1;
-                       *yuv++ = (v0+v1) >> 1;
-               }
-               if (uneven)
-               {
-                       r =  GetRGB(rgb, width, height, x, +boxw, y, +boxh, 0) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 0) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 0) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 0);
-                       g =  GetRGB(rgb, width, height, x, +boxw, y, +boxh, 1) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 1) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 1) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 1);
-                       b =  GetRGB(rgb, width, height, x, +boxw, y, +boxh, 2) + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 2) - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 2) - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 2);
-                       r = (int32_t) (r * mul);
-                       g = (int32_t) (g * mul);
-                       b = (int32_t) (b * mul);
-                       RGB2YUV (r, g, b, y0, u0, v0);
-                       *yuv++ = mul * y0;
-                       *yuv++ = mul * u0;
+                       *image++ = (GetRGB(rgb, width, height, x, +boxw, y, +boxh, 0)
+                                 + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 0)
+                                 - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 0)
+                                 - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 0)) * mul;
+                       *image++ = (GetRGB(rgb, width, height, x, +boxw, y, +boxh, 1)
+                                 + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 1)
+                                 - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 1)
+                                 - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 1)) * mul;
+                       *image++ = (GetRGB(rgb, width, height, x, +boxw, y, +boxh, 2)
+                                 + GetRGB(rgb, width, height, x, -boxw, y, -boxh, 2)
+                                 - GetRGB(rgb, width, height, x, -boxw, y, +boxh, 2)
+                                 - GetRGB(rgb, width, height, x, +boxw, y, -boxh, 2)) * mul;
                }
        }
 }
@@ -163,21 +87,22 @@ static void DoBoxBlur(uint8_t *yuv, int32_t *rgb, unsigned int width, unsigned i
 static int filter_get_image( mlt_frame this, uint8_t **image, mlt_image_format *format, int *width, int *height, int writable )
 {
        // Get the image
-       *format = mlt_image_yuv422;
+       *format = mlt_image_rgb24;
        int error = mlt_frame_get_image( this, image, format, width, height, 1 );
-       short hori = mlt_properties_get_int(MLT_FRAME_PROPERTIES( this ), "hori" );
-       short vert = mlt_properties_get_int(MLT_FRAME_PROPERTIES( this ), "vert" );
+       short hori = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "hori" );
+       short vert = mlt_properties_get_int( MLT_FRAME_PROPERTIES( this ), "vert" );
 
        // Only process if we have no error and a valid colour space
        if ( error == 0 )
        {
                double factor = mlt_properties_get_double( MLT_FRAME_PROPERTIES( this ), "boxblur" );
-               if (factor != 0) {
+               if ( factor != 0)
+               {
                        int h = *height + 1;
-                       int32_t *rgb = mlt_pool_alloc (3 * *width * h * sizeof(int32_t));
-                       PreCompute (*image, rgb, *width, h);
-                       DoBoxBlur (*image, rgb, *width, h, (int) factor*hori, (int) factor*vert);
-                       mlt_pool_release (rgb);
+                       int32_t *rgb = mlt_pool_alloc( 3 * *width * h * sizeof(int32_t) );
+                       PreCompute( *image, rgb, *width, h );
+                       DoBoxBlur( *image, rgb, *width, h, (int) factor * hori, (int) factor * vert );
+                       mlt_pool_release( rgb );
                }
        }
        return error;
@@ -223,7 +148,7 @@ mlt_filter filter_boxblur_init( mlt_profile profile, mlt_service_type type, cons
        if ( this != NULL )
        {
                this->process = filter_process;
-               mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "start", arg == NULL ? "10" : arg);
+               mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "start", arg == NULL ? "2" : arg);
                mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "hori", arg == NULL ? "1" : arg);
                mlt_properties_set( MLT_FILTER_PROPERTIES( this ), "vert", arg == NULL ? "1" : arg);
        }