summaryrefslogtreecommitdiff
path: root/libavfilter/vf_lenscorrection.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2014-08-20 14:05:20 +0200
committerMichael Niedermayer <michaelni@gmx.at>2014-08-21 11:42:57 +0200
commit2450ca0f3344acc9c48c5990aee2e617313f030d (patch)
tree035be7d8658dbf63c4e5a9d5242e4ef4bbc2a93d /libavfilter/vf_lenscorrection.c
parentc1b663bc92d3d5d4683b4109e5f6cea075855a7d (diff)
avfilter/vf_lenscorrection: get rid of all floats per frame
there are some still left for 1 time initialization Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter/vf_lenscorrection.c')
-rw-r--r--libavfilter/vf_lenscorrection.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/libavfilter/vf_lenscorrection.c b/libavfilter/vf_lenscorrection.c
index 048820c298..11fa4c80c2 100644
--- a/libavfilter/vf_lenscorrection.c
+++ b/libavfilter/vf_lenscorrection.c
@@ -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));
}