avfilter/vf_lenscorrection: get rid of all floats per frame
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 20 Aug 2014 12:05:20 +0000 (14:05 +0200)
committerMichael Niedermayer <michaelni@gmx.at>
Thu, 21 Aug 2014 09:42:57 +0000 (11:42 +0200)
there are some still left for 1 time initialization

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
libavfilter/vf_lenscorrection.c

index 048820c..11fa4c8 100644 (file)
@@ -41,6 +41,7 @@ typedef struct LenscorrectionCtx {
     int hsub, vsub;
     int nb_planes;
     double cx, cy, k1, k2;
+    int32_t *correction[4];
 } LenscorrectionCtx;
 
 #define FLAGS AV_OPT_FLAG_FILTERING_PARAM|AV_OPT_FLAG_VIDEO_PARAM
@@ -59,7 +60,7 @@ typedef struct ThreadData {
     int w, h;
     int plane;
     int xcenter, ycenter;
-    float k1, k2;
+    int32_t *correction;
 } ThreadData;
 
 static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
@@ -71,9 +72,6 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
     const int w = td->w, h = td->h;
     const int xcenter = td->xcenter;
     const int ycenter = td->ycenter;
-    const float r2inv = 4.0 / (w * w + h * h);
-    const float k1 = td->k1;
-    const float k2 = td->k2;
     const int start = (h *  job   ) / nb_jobs;
     const int end   = (h * (job+1)) / nb_jobs;
     const int plane = td->plane;
@@ -84,15 +82,13 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
     int i;
     for (i = start; i < end; i++, outrow += outlinesize) {
         const int off_y = i - ycenter;
-        const int off_y2 = off_y * off_y;
         uint8_t *out = outrow;
         int j;
         for (j = 0; j < w; j++) {
             const int off_x = j - xcenter;
-            const float r2 = (off_x * off_x + off_y2) * r2inv;
-            const float radius_mult = 1.0f + r2 * k1 + r2 * r2 * k2;
-            const int x = xcenter + radius_mult * off_x + 0.5f;
-            const int y = ycenter + radius_mult * off_y + 0.5f;
+            const int64_t radius_mult = td->correction[j + i*w];
+            const int x = xcenter + ((radius_mult * off_x + (1<<23))>>24);
+            const int y = ycenter + ((radius_mult * off_y + (1<<23))>>24);
             const char isvalid = x > 0 && x < w - 1 && y > 0 && y < h - 1;
             *out++ =  isvalid ? indata[y * inlinesize + x] : 0;
         }
@@ -151,16 +147,39 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in)
         int vdiv = 1 << vsub;
         int w = rect->width / hdiv;
         int h = rect->height / vdiv;
+        int xcenter = rect->cx * w;
+        int ycenter = rect->cy * h;
+        float k1 = rect->k1;
+        float k2 = rect->k2;
         ThreadData td = {
             .in = in,
             .out  = out,
             .w  = w,
             .h  = h,
-            .xcenter = rect->cx * w,
-            .ycenter = rect->cy * h,
-            .k1 = rect->k1,
-            .k2 = rect->k2,
+            .xcenter = xcenter,
+            .ycenter = ycenter,
             .plane = plane};
+
+        if (!rect->correction[plane]) {
+            int i,j;
+            const float r2inv = 4.0 / (w * w + h * h);
+
+            rect->correction[plane] = av_malloc_array(w, h * sizeof(**rect->correction));
+            if (!rect->correction[plane])
+                return AVERROR(ENOMEM);
+            for (j = 0; j < h; j++) {
+                const int off_y = j - ycenter;
+                const int off_y2 = off_y * off_y;
+                for (i = 0; i < w; i++) {
+                    const int off_x = i - xcenter;
+                    const float r2 = (off_x * off_x + off_y2) * r2inv;
+                    const float radius_mult = 1.0f + r2 * k1 + r2 * r2 * k2;
+                    rect->correction[plane][j * w + i] = lrintf(radius_mult * (1<<24));
+                }
+            }
+        }
+
+        td.correction = rect->correction[plane];
         ctx->internal->execute(ctx, filter_slice, &td, NULL, FFMIN(h, ctx->graph->nb_threads));
     }