# HG changeset patch # User Alexey Osipov <si...@lerlan.ru> # Date 1310724640 -25200 # Branch stabilize_optimize # Node ID ca546347d93b572f79923401fad4b90a5334b53c # Parent a988634e1d2b94aab2babbeb8df8ce0a2b77e311 Simple optimization (early cut obviously false search paths), giving approx three times speed-up.
diff -r a988634e1d2b -r ca546347d93b filter/stabilize/filter_stabilize.c --- a/filter/stabilize/filter_stabilize.c Fri Jul 15 17:01:54 2011 +0700 +++ b/filter/stabilize/filter_stabilize.c Fri Jul 15 17:10:40 2011 +0700 @@ -3,6 +3,11 @@ * * Copyright (C) Georg Martius - June 2007 * georg dot martius at web dot de + * initial author + * + * Copyright (C) Alexey Osipov - Jule 2011 + * simba at lerlan dot ru + * speed optimizations * * This file is part of transcode, a video stream processing tool * @@ -63,6 +68,8 @@ * this is really just for debugging and development */ // #define STABVERBOSE +#define MAXLONG ((unsigned long int)(-1)) + typedef struct _field { int x; // middle position x int y; // middle position y @@ -149,11 +156,11 @@ " 'help' print this help message\n"; int initFields(StabData* sd); -double compareImg(unsigned char* I1, unsigned char* I2, - int width, int height, int bytesPerPixel, int d_x, int d_y); -double compareSubImg(unsigned char* const I1, unsigned char* const I2, +unsigned long int compareImg(unsigned char* I1, unsigned char* I2, + int width, int height, int bytesPerPixel, int d_x, int d_y, unsigned long int treshold); +unsigned long int compareSubImg(unsigned char* const I1, unsigned char* const I2, const Field* field, - int width, int height, int bytesPerPixel,int d_x,int d_y); + int width, int height, int bytesPerPixel,int d_x,int d_y, unsigned long int treshold); double contrastSubImgYUV(StabData* sd, const Field* field); double contrastSubImgRGB(StabData* sd, const Field* field); double contrastSubImg(unsigned char* const I, const Field* field, @@ -234,13 +241,13 @@ \param d_x shift in x direction \param d_y shift in y direction */ -double compareImg(unsigned char* I1, unsigned char* I2, - int width, int height, int bytesPerPixel, int d_x, int d_y) +unsigned long int compareImg(unsigned char* I1, unsigned char* I2, + int width, int height, int bytesPerPixel, int d_x, int d_y, unsigned long int treshold) { int i, j; unsigned char* p1 = NULL; unsigned char* p2 = NULL; - long int sum = 0; + unsigned long int sum = 0; int effectWidth = width - abs(d_x); int effectHeight = height - abs(d_y); @@ -278,11 +285,13 @@ p1++; p2++; } + if (sum > treshold) + break; } /* fclose(pic1); fclose(pic2); */ - return sum/((double) effectWidth * effectHeight * bytesPerPixel); + return sum; } /** @@ -295,15 +304,15 @@ \param d_x shift in x direction \param d_y shift in y direction */ -double compareSubImg(unsigned char* const I1, unsigned char* const I2, +unsigned long int compareSubImg(unsigned char* const I1, unsigned char* const I2, const Field* field, - int width, int height, int bytesPerPixel, int d_x, int d_y) + int width, int height, int bytesPerPixel, int d_x, int d_y, unsigned long int treshold) { int k, j; unsigned char* p1 = NULL; unsigned char* p2 = NULL; int s2 = field->size / 2; - double sum = 0; + unsigned long int sum = 0; p1=I1 + ((field->x - s2) + (field->y - s2)*width)*bytesPerPixel; p2=I2 + ((field->x - s2 + d_x) + (field->y - s2 + d_y)*width)*bytesPerPixel; @@ -314,10 +323,12 @@ p1++; p2++; } + if (sum > treshold) + break; p1 += (width - field->size) * bytesPerPixel; p2 += (width - field->size) * bytesPerPixel; } - return sum/((double) field->size *field->size* bytesPerPixel); + return sum; } /** \see contrastSubImg called with bytesPerPixel=1*/ @@ -376,11 +387,11 @@ { int x = 0, y = 0; int i, j; - double minerror = 1e20; + unsigned long int minerror = MAXLONG; for (i = -sd->maxshift; i <= sd->maxshift; i++) { for (j = -sd->maxshift; j <= sd->maxshift; j++) { - double error = compareImg(sd->curr, sd->prev, - sd->width, sd->height, 3, i, j); + unsigned long int error = compareImg(sd->curr, sd->prev, + sd->width, sd->height, 3, i, j, minerror); if (error < minerror) { minerror = error; x = i; @@ -419,11 +430,11 @@ //Cb_p = sd->prev + sd->width*sd->height; //Cr_p = sd->prev + 5*sd->width*sd->height/4; - double minerror = 1e20; + unsigned long int minerror = MAXLONG; for (i = -sd->maxshift; i <= sd->maxshift; i++) { for (j = -sd->maxshift; j <= sd->maxshift; j++) { - double error = compareImg(Y_c, Y_p, - sd->width, sd->height, 1, i, j); + unsigned long int error = compareImg(Y_c, Y_p, + sd->width, sd->height, 1, i, j, minerror); #ifdef STABVERBOSE fprintf(f, "%i %i %f\n", i, j, error); #endif @@ -490,12 +501,12 @@ fprintf(f, "# splot \"%s\"\n", buffer); #endif - double minerror = 1e10; - double error = 1e10; + unsigned long int minerror = MAXLONG; + unsigned long int error = MAXLONG; for (i = -sd->maxshift; i <= sd->maxshift; i += sd->stepsize) { for (j = -sd->maxshift; j <= sd->maxshift; j += sd->stepsize) { error = compareSubImg(Y_c, Y_p, field, - sd->width, sd->height, 1, i, j); + sd->width, sd->height, 1, i, j, minerror); #ifdef STABVERBOSE fprintf(f, "%i %i %f\n", i, j, error); #endif @@ -516,7 +527,7 @@ if (i == txc && j == tyc) continue; //no need to check this since already done error = compareSubImg(Y_c, Y_p, field, - sd->width, sd->height, 1, i, j); + sd->width, sd->height, 1, i, j, minerror); #ifdef STABVERBOSE fprintf(f, "%i %i %f\n", i, j, error); #endif @@ -560,11 +571,11 @@ uint8_t *I_c = sd->curr, *I_p = sd->prev; int i, j; - double minerror = 1e20; + unsigned long int minerror = MAXLONG; for (i = -sd->maxshift; i <= sd->maxshift; i += 2) { for (j=-sd->maxshift; j <= sd->maxshift; j += 2) { - double error = compareSubImg(I_c, I_p, field, - sd->width, sd->height, 3, i, j); + unsigned long int error = compareSubImg(I_c, I_p, field, + sd->width, sd->height, 3, i, j, minerror); if (error < minerror) { minerror = error; t.x = i; @@ -574,8 +585,8 @@ } for (i = t.x - 1; i <= t.x + 1; i += 2) { for (j = -t.y - 1; j <= t.y + 1; j += 2) { - double error = compareSubImg(I_c, I_p, field, - sd->width, sd->height, 3, i, j); + unsigned long int error = compareSubImg(I_c, I_p, field, + sd->width, sd->height, 3, i, j, minerror); if (error < minerror) { minerror = error; t.x = i;