# HG changeset patch
# User Alexey Osipov <[email protected]>
# 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;